├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── .travis ├── before-cache.sh ├── before-ci.sh ├── before-install.sh ├── ci.sh └── install.sh ├── LICENSE ├── README.md ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── gettipsi │ └── boilerplate │ ├── RNBoilerplateModule.java │ └── RNBoilerplateReactPackage.java ├── example ├── .appiumhelperrc ├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── __tests__ │ ├── 01_test_simple_view.js │ └── setup │ │ └── elements.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── index.android.js ├── index.ios.js ├── ios │ ├── Podfile │ ├── example-tvOS │ │ └── Info.plist │ ├── example-tvOSTests │ │ └── Info.plist │ ├── example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── example-tvOS.xcscheme │ │ │ └── example.xcscheme │ ├── example.xcworkspace │ │ └── contents.xcworkspacedata │ ├── example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ └── exampleTests │ │ ├── Info.plist │ │ └── exampleTests.m ├── package-lock.json ├── package.json └── three.js ├── ios ├── RNWebGLARKit.xcodeproj │ └── project.pbxproj └── RNWebGLARKit │ ├── RNWebGLARKit.h │ ├── RNWebGLARKit.m │ ├── RNWebGLARKitManager.h │ └── RNWebGLARKitManager.m ├── package.json ├── scripts ├── copy-from-node-modules.sh ├── local-ci.sh ├── post-link-android.sh ├── post-link-ios.sh ├── post-link.sh └── pre-link.sh ├── src ├── Camera.js ├── RNWebGLARKitView.js ├── index.js └── kelvin2rgb.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "parser": "babel-eslint", 4 | "rules": { 5 | "react/prefer-stateless-function": 0, 6 | "react/jsx-filename-extension": 0, 7 | "jsx-a11y/href-no-hash": 0, 8 | "padded-blocks": 0, 9 | "new-cap": 0, 10 | "no-underscore-dangle": 0, 11 | "class-methods-use-this": 0, 12 | "no-return-assign": 0, 13 | "no-use-before-define": 0, 14 | "import/no-unresolved": 0, 15 | "import/extensions": 0 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | Podfile.lock 25 | Pods/ 26 | 27 | # Built application files 28 | # 29 | *.apk 30 | *.ap_ 31 | 32 | # Files for the ART/Dalvik VM 33 | # 34 | *.dex 35 | 36 | # Java class files 37 | # 38 | *.class 39 | 40 | # Generated files 41 | # 42 | bin/ 43 | gen/ 44 | out/ 45 | 46 | # Gradle files 47 | # 48 | build/ 49 | *.iml 50 | .idea 51 | .gradle 52 | local.properties 53 | *.hprof 54 | 55 | # Proguard folder generated by Eclipse 56 | # 57 | proguard/ 58 | .navigation/ 59 | 60 | # Android Studio captures folder 61 | captures/ 62 | 63 | # Keystore files 64 | # 65 | *.jks 66 | android/gradlew 67 | android/gradlew.bat 68 | android/gradle/wrapper/gradle-wrapper.jar 69 | android/gradle/wrapper/gradle-wrapper.properties 70 | 71 | # node.js 72 | # 73 | node_modules/ 74 | npm-debug.log 75 | 76 | tmp 77 | example_tmp 78 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | .eslintrc 3 | .travis 4 | .travis.yml 5 | example 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: osx 4 | language: objective-c 5 | osx_image: xcode8 6 | - os: linux 7 | language: android 8 | jdk: oraclejdk8 9 | sudo: required 10 | android: 11 | components: 12 | - platform-tools 13 | - tools 14 | - build-tools-25.0.1 15 | - android-25 16 | - sys-img-armeabi-v7a-android-23 17 | - extra-android-m2repository 18 | - extra-google-m2repository 19 | - extra-google-google_play_services 20 | 21 | cache: 22 | directories: 23 | - $HOME/.nvm 24 | - $HOME/.npm 25 | - $HOME/.cocoapods 26 | - $HOME/.gradle/caches/ 27 | - $HOME/.gradle/wrapper/ 28 | - example/node_modules 29 | 30 | before_cache: .travis/before-cache.sh 31 | before_install: . .travis/before-install.sh 32 | install: .travis/install.sh 33 | before_script: .travis/before-ci.sh 34 | script: .travis/ci.sh 35 | -------------------------------------------------------------------------------- /.travis/before-cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${TRAVIS_OS_NAME}" in 4 | osx) 5 | rm -rf example_tmp/node_modules/react-native-webgl-arkit 6 | ;; 7 | linux) 8 | rm -rf example_tmp/node_modules/react-native-webgl-arkit 9 | rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 10 | ;; 11 | esac 12 | -------------------------------------------------------------------------------- /.travis/before-ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${TRAVIS_OS_NAME}" in 4 | osx) 5 | example_tmp/node_modules/.bin/appium --session-override > appium.out & 6 | ;; 7 | linux) 8 | echo no | android create avd --force -n test -t android-21 --abi armeabi-v7a --skin WVGA800 9 | emulator -avd test -scale 96dpi -dpi-device 160 -no-audio -no-window & 10 | android-wait-for-emulator 11 | sleep 60 12 | adb shell input keyevent 82 & 13 | example_tmp/node_modules/.bin/appium --session-override > appium.out & 14 | ;; 15 | esac 16 | -------------------------------------------------------------------------------- /.travis/before-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | init_new_example_project() { 4 | proj_dir_old=example 5 | proj_dir_new=example_tmp 6 | 7 | react_native_version=$(cat $proj_dir_old/package.json | sed -n 's/"react-native": "\(\^|~\)*\(.*\)",*/\2/p') 8 | 9 | files_to_copy=( 10 | .appiumhelperrc 11 | .babelrc 12 | package.json 13 | index.{ios,android}.js 14 | android/app/build.gradle 15 | src 16 | scripts 17 | __tests__ 18 | ) 19 | 20 | mkdir tmp 21 | cd tmp 22 | react-native init $proj_dir_old --version $react_native_version 23 | cd .. 24 | mv tmp/$proj_dir_old $proj_dir_new 25 | rm -rf $proj_dir_new/__tests__ 26 | 27 | for i in ${files_to_copy[@]}; do 28 | if [ -e $proj_dir_old/$i ]; then 29 | cp -Rp $proj_dir_old/$i $proj_dir_new/$i 30 | fi 31 | done 32 | } 33 | 34 | case "${TRAVIS_OS_NAME}" in 35 | osx) 36 | $HOME/.nvm/nvm.sh 37 | nvm install 7.2.0 38 | gem install cocoapods -v 1.1.1 39 | travis_wait pod repo update --silent 40 | npm install -g react-native-cli 41 | init_new_example_project 42 | ;; 43 | linux) 44 | $HOME/.nvm/nvm.sh 45 | nvm install 7.2.0 46 | npm install -g react-native-cli 47 | init_new_example_project 48 | ;; 49 | esac 50 | -------------------------------------------------------------------------------- /.travis/ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${TRAVIS_OS_NAME}" in 4 | osx) 5 | cd example_tmp 6 | set -o pipefail && npm run build:ios | xcpretty -c -f `xcpretty-travis-formatter` 7 | npm run test:ios 8 | ;; 9 | linux) 10 | cd example_tmp 11 | npm run build:android 12 | npm run test:android 13 | ;; 14 | esac 15 | -------------------------------------------------------------------------------- /.travis/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | library_name=$(node -p "require('./package.json').name") 4 | 5 | case "${TRAVIS_OS_NAME}" in 6 | osx) 7 | cd example_tmp 8 | npm install 9 | react-native unlink $library_name 10 | react-native link 11 | ;; 12 | linux) 13 | cd example_tmp 14 | npm install 15 | react-native unlink $library_name 16 | react-native link 17 | ;; 18 | esac 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Anton Kuznetsov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-webgl-arkit 2 | 3 | ARKit camera layer that is interactable with THREE.js WebGL layer on top. 4 | 5 | Example of use 6 | 7 | ```js 8 | class App extends Component { 9 | 10 | // Perspective Camera 11 | camera = new THREE.PerspectiveCamera(); 12 | 13 | // Ambient Light 14 | light = new THREE.AmbientLight(0xFFFFFF); 15 | 16 | onContextCreate = (gl) => { 17 | const rngl = gl.getExtension('RN'); 18 | const { drawingBufferWidth: width, drawingBufferHeight: height } = gl; 19 | 20 | const renderer = new THREE.WebGLRenderer({ ... }); // See react-native-webgl 21 | renderer.setClearColor(0x000000, 0); // Make the renderer transparent 22 | 23 | this.camera.width = width; // Set width and height of camera 24 | this.camera.height = height; 25 | 26 | const animate = () => { 27 | // Update camera position 28 | this.camera.position.setFromMatrixPosition(this.camera.matrixWorld); 29 | 30 | renderer.render(this.scene, this.camera); 31 | requestAnimationFrame(animate); 32 | 33 | gl.flush(); 34 | rngl.endFrame(); 35 | }; 36 | animate(); 37 | } 38 | 39 | render() { 40 | return ( 41 | 42 | 47 | 51 | 52 | ); 53 | } 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.1" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | compile 'com.facebook.react:react-native:+' 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/src/main/java/com/gettipsi/boilerplate/RNBoilerplateModule.java: -------------------------------------------------------------------------------- 1 | package com.gettipsi.boilerplate; 2 | 3 | import com.facebook.react.bridge.NativeModule; 4 | import com.facebook.react.bridge.ReactApplicationContext; 5 | import com.facebook.react.bridge.ReactContext; 6 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 7 | import com.facebook.react.bridge.ReactMethod; 8 | import com.facebook.react.bridge.Promise; 9 | import com.facebook.react.bridge.WritableNativeArray; 10 | 11 | import java.util.Map; 12 | 13 | public class RNBoilerplateModule extends ReactContextBaseJavaModule { 14 | 15 | private static final String MODULE_NAME = "RNBoilerplateModule"; 16 | 17 | public RNBoilerplateModule(ReactApplicationContext reactContext) { 18 | super(reactContext); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return MODULE_NAME; 24 | } 25 | 26 | @ReactMethod 27 | public void findCars(Promise promise) { 28 | WritableNativeArray cars = new WritableNativeArray(); 29 | cars.pushString("Mercedes-Benz"); 30 | cars.pushString("BMW"); 31 | cars.pushString("Porsche"); 32 | cars.pushString("Opel"); 33 | cars.pushString("Volkswagen"); 34 | cars.pushString("Audi"); 35 | 36 | if (promise != null) { 37 | promise.resolve(cars); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /android/src/main/java/com/gettipsi/boilerplate/RNBoilerplateReactPackage.java: -------------------------------------------------------------------------------- 1 | package com.gettipsi.boilerplate; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class RNBoilerplateReactPackage implements ReactPackage { 15 | 16 | @Override 17 | public List> createJSModules() { 18 | return Collections.emptyList(); 19 | } 20 | 21 | @Override 22 | public List createViewManagers(ReactApplicationContext reactContext) { 23 | return Collections.emptyList(); 24 | } 25 | 26 | @Override 27 | public List createNativeModules(ReactApplicationContext reactContext) { 28 | List modules = new ArrayList<>(); 29 | modules.add(new RNBoilerplateModule(reactContext)); 30 | return modules; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/.appiumhelperrc: -------------------------------------------------------------------------------- 1 | { 2 | "register": "./__tests__/setup/elements", 3 | "ios": { 4 | "appPath": "./ios/build/Build/Products/Release-iphonesimulator/example.app", 5 | "noReset": true 6 | }, 7 | "android": { 8 | "appPath": "./android/app/build/outputs/apk/app-release.apk" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } -------------------------------------------------------------------------------- /example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | module.system=haste 26 | 27 | experimental.strict_type_args=true 28 | 29 | munge_underscores=true 30 | 31 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 32 | 33 | suppress_type=$FlowIssue 34 | suppress_type=$FlowFixMe 35 | suppress_type=$FixMe 36 | 37 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-7]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 38 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-7]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 40 | 41 | unsafe.enable_getters_and_setters=true 42 | 43 | [version] 44 | ^0.37.0 45 | -------------------------------------------------------------------------------- /example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | android/app/libs 43 | *.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/Preview.html 54 | fastlane/screenshots 55 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/__tests__/01_test_simple_view.js: -------------------------------------------------------------------------------- 1 | import test from 'tape-async' 2 | import helper from 'tipsi-appium-helper' 3 | 4 | const { driver, elements } = helper 5 | 6 | test('Test if user can see view', async (t) => { 7 | const screen = elements() 8 | 9 | try { 10 | await driver.waitForVisible(screen.title, 60000) 11 | const title = await driver.getText(screen.title) 12 | t.equal(title, 'Welcome to React Native!', 'Title is correct') 13 | } catch (error) { 14 | await helper.screenshot() 15 | await helper.source() 16 | 17 | throw error 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /example/__tests__/setup/elements.js: -------------------------------------------------------------------------------- 1 | import helper from 'tipsi-appium-helper' 2 | 3 | helper.extend('elements', function () { 4 | const { idFromXPath, idFromAccessId } = this 5 | 6 | const selectors = { 7 | title: { 8 | ios: idFromXPath(` 9 | /XCUIElementTypeApplication/XCUIElementTypeWindow/XCUIElementTypeOther/ 10 | XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/ 11 | XCUIElementTypeOther/XCUIElementTypeStaticText[1] 12 | `), 13 | android: idFromAccessId('title'), 14 | }, 15 | } 16 | 17 | return Object.keys(selectors).reduce((memo, item) => { 18 | const currentImplementation = selectors[item][this.config.platformName] 19 | if (currentImplementation) { 20 | /* eslint no-param-reassign: 0 */ 21 | memo[item] = currentImplementation 22 | } 23 | 24 | return memo 25 | }, {}) 26 | }) 27 | -------------------------------------------------------------------------------- /example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.example', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.example', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"] 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.example" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile project(':react-native-webgl') 130 | compile fileTree(dir: "libs", include: ["*.jar"]) 131 | compile "com.android.support:appcompat-v7:23.0.1" 132 | compile "com.facebook.react:react-native:+" // From node_modules 133 | } 134 | 135 | // Run this once to be able to run the application with BUCK 136 | // puts all compile dependencies into folder libs for BUCK to use 137 | task copyDownloadableDepsToLibs(type: Copy) { 138 | from configurations.compile 139 | into 'libs' 140 | } 141 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # okhttp 54 | 55 | -keepattributes Signature 56 | -keepattributes *Annotation* 57 | -keep class okhttp3.** { *; } 58 | -keep interface okhttp3.** { *; } 59 | -dontwarn okhttp3.** 60 | 61 | # okio 62 | 63 | -keep class sun.misc.Unsafe { *; } 64 | -dontwarn java.nio.file.* 65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 66 | -dontwarn okio.** 67 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "example"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.ReactApplication; 7 | import fr.greweb.rnwebgl.RNWebGLPackage; 8 | import com.facebook.react.ReactInstanceManager; 9 | import com.facebook.react.ReactNativeHost; 10 | import com.facebook.react.ReactPackage; 11 | import com.facebook.react.shell.MainReactPackage; 12 | import com.facebook.soloader.SoLoader; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 20 | @Override 21 | public boolean getUseDeveloperSupport() { 22 | return BuildConfig.DEBUG; 23 | } 24 | 25 | @Override 26 | protected List getPackages() { 27 | return Arrays.asList( 28 | new MainReactPackage(), 29 | new RNWebGLPackage() 30 | ); 31 | } 32 | }; 33 | 34 | @Override 35 | public ReactNativeHost getReactNativeHost() { 36 | return mReactNativeHost; 37 | } 38 | 39 | @Override 40 | public void onCreate() { 41 | super.onCreate(); 42 | SoLoader.init(this, /* native exopackage */ false); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/birkir/react-native-webgl-arkit/73599c5612671e3c94ab3077af3f4df1baf1e9a4/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/birkir/react-native-webgl-arkit/73599c5612671e3c94ab3077af3f4df1baf1e9a4/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/birkir/react-native-webgl-arkit/73599c5612671e3c94ab3077af3f4df1baf1e9a4/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/birkir/react-native-webgl-arkit/73599c5612671e3c94ab3077af3f4df1baf1e9a4/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.3.1' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/birkir/react-native-webgl-arkit/73599c5612671e3c94ab3077af3f4df1baf1e9a4/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /example/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /example/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | include ':react-native-webgl' 3 | project(':react-native-webgl').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webgl/android') 4 | 5 | include ':app' 6 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } -------------------------------------------------------------------------------- /example/index.android.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | AppRegistry, 4 | StyleSheet, 5 | Text, 6 | View, 7 | } from 'react-native'; 8 | import { Camera } from 'react-native-webgl-arkit'; 9 | 10 | export default class example extends Component { 11 | render() { 12 | return ( 13 | 14 | 15 | Welcome to React Native! 16 | 17 | 18 | 19 | Double tap R on your keyboard to reload,{'\n'} 20 | Shake or press menu button for dev menu 21 | 22 | 23 | ) 24 | } 25 | } 26 | 27 | const styles = StyleSheet.create({ 28 | container: { 29 | flex: 1, 30 | justifyContent: 'center', 31 | alignItems: 'center', 32 | backgroundColor: '#F5FCFF', 33 | }, 34 | welcome: { 35 | fontSize: 20, 36 | textAlign: 'center', 37 | margin: 10, 38 | }, 39 | instructions: { 40 | textAlign: 'center', 41 | color: '#333333', 42 | marginBottom: 5, 43 | }, 44 | }); 45 | 46 | AppRegistry.registerComponent('example', () => example); 47 | -------------------------------------------------------------------------------- /example/index.ios.js: -------------------------------------------------------------------------------- 1 | /* global requestAnimationFrame cancelAnimationFrame */ 2 | import React from 'react'; 3 | import { AppRegistry, StyleSheet, View } from 'react-native'; 4 | import { WebGLView } from 'react-native-webgl'; 5 | import { Camera } from 'react-native-webgl-arkit'; 6 | import THREE from './three'; 7 | 8 | export default class example extends React.Component { 9 | 10 | componentWillUnmount() { 11 | cancelAnimationFrame(this.requestId); 12 | } 13 | 14 | onContextCreate = (gl) => { 15 | const rngl = gl.getExtension('RN'); 16 | 17 | const { drawingBufferWidth: width, drawingBufferHeight: height } = gl; 18 | const renderer = new THREE.WebGLRenderer({ 19 | canvas: { 20 | width, 21 | height, 22 | style: {}, 23 | addEventListener: () => {}, 24 | removeEventListener: () => {}, 25 | clientHeight: height, 26 | }, 27 | context: gl, 28 | }); 29 | renderer.setSize(width, height); 30 | renderer.setClearColor(0x000000, 0); // Make the renderer transparent 31 | 32 | // Set camera size 33 | this.camera.width = width; 34 | this.camera.height = height; 35 | 36 | let cube; 37 | 38 | const init = () => { 39 | const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1); 40 | for (let i = 0; i < geometry.faces.length; i += 2) { 41 | const hex = Math.random() * 0xffffff; 42 | geometry.faces[i].color.setHex(hex); 43 | geometry.faces[i + 1].color.setHex(hex); 44 | } 45 | 46 | const material = new THREE.MeshBasicMaterial({ 47 | vertexColors: THREE.FaceColors, 48 | overdraw: 0.5, 49 | }); 50 | 51 | cube = new THREE.Mesh(geometry, material); 52 | cube.position.z = -0.05; 53 | this.scene.add(cube); 54 | }; 55 | 56 | const animate = () => { 57 | this.requestId = requestAnimationFrame(animate); 58 | 59 | // Update camera position 60 | this.camera.position.setFromMatrixPosition(this.camera.matrixWorld); 61 | renderer.render(this.scene, this.camera); 62 | 63 | cube.rotation.y += 0.05; 64 | 65 | gl.flush(); 66 | rngl.endFrame(); 67 | }; 68 | 69 | init(); 70 | animate(); 71 | }; 72 | 73 | onPlaneDetected = (e) => { 74 | const { center, extent } = e.nativeEvent; 75 | const geometry = new THREE.PlaneGeometry(extent.x, extent.z, 16); 76 | const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, wireframe: true }); 77 | const plane = new THREE.Mesh(geometry, material); 78 | plane.rotation.x = Math.PI / 2; 79 | plane.position.x = center.x; 80 | plane.position.y = center.y; 81 | plane.position.z = center.z; 82 | this.scene.add(plane); 83 | } 84 | 85 | requestId; 86 | ambientLight = new THREE.AmbientLight(); 87 | camera = new THREE.PerspectiveCamera(); 88 | scene = new THREE.Scene(); 89 | 90 | render() { 91 | return ( 92 | 93 | 100 | 104 | 105 | ); 106 | } 107 | } 108 | 109 | const styles = StyleSheet.create({ 110 | container: { 111 | flex: 1, 112 | }, 113 | }); 114 | 115 | AppRegistry.registerComponent('example', () => example); 116 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'example' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | 8 | # Pods for example 9 | 10 | target 'exampleTests' do 11 | inherit! :search_paths 12 | # Pods for testing 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /example/ios/example-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /example/ios/example-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"example" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /example/ios/example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | NSLocationWhenInUseUsageDescription 42 | 43 | NSCameraUsageDescription 44 | ARKit 45 | NSAppTransportSecurity 46 | 47 | NSExceptionDomains 48 | 49 | localhost 50 | 51 | NSExceptionAllowsInsecureHTTPLoads 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/ios/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/exampleTests/exampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface exampleTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation exampleTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "description": "react-native-webgl-arkit example", 4 | "version": "0.1.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "node node_modules/react-native/local-cli/cli.js start", 8 | "clean": "rm -rf android/app/release.keystore", 9 | "appium": "appium", 10 | "build:android:key": "keytool -genkey -v -keystore android/app/release.keystore -storepass android -alias androidreleasekey -keypass android -dname 'CN=Android Debug,O=Android,C=US'", 11 | "build:android:release": "cd android && ./gradlew assembleRelease --console=plain -S", 12 | "build:android": "npm-run-all clean build:android:*", 13 | "build:ios": "cd ios && xcodebuild build -project example.xcodeproj -scheme example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO OTHER_LDFLAGS='$(inherited) -ObjC -lc++' -destination 'platform=iOS Simulator,name=iPhone 6' -configuration Release -derivedDataPath build", 14 | "test:android": "appium-helper --platform android", 15 | "test:ios": "appium-helper --platform ios", 16 | "test": "npm-run-all test:*" 17 | }, 18 | "dependencies": { 19 | "prop-types": "15.6.1", 20 | "react": "16.3.2", 21 | "react-native": "0.55.4", 22 | "react-native-webgl": "0.8.0", 23 | "three": "0.92.0" 24 | }, 25 | "devDependencies": { 26 | "appium": "1.6.3", 27 | "npm-run-all": "^3.1.1", 28 | "tape-async": "^2.1.1", 29 | "tipsi-appium-helper": "1.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/three.js: -------------------------------------------------------------------------------- 1 | /* global window */ 2 | window.addEventListener = () => {}; 3 | 4 | console.ignoredYellowBox = ['THREE.WebGL']; 5 | 6 | const THREE = require('three'); 7 | 8 | global.THREE = THREE; 9 | 10 | export default THREE; 11 | -------------------------------------------------------------------------------- /ios/RNWebGLARKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 66399AC21DF0490400D167A8 /* RNWebGLARKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 66399AC11DF0490400D167A8 /* RNWebGLARKit.m */; }; 11 | 66399AC71DF049AE00D167A8 /* RNWebGLARKitManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66399AC61DF049AE00D167A8 /* RNWebGLARKitManager.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXContainerItemProxy section */ 15 | 66ABD5021DEDAAD100F706C0 /* PBXContainerItemProxy */ = { 16 | isa = PBXContainerItemProxy; 17 | containerPortal = 66ABD4FD1DEDAAD100F706C0 /* React.xcodeproj */; 18 | proxyType = 2; 19 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 20 | remoteInfo = React; 21 | }; 22 | 66ABD5041DEDAAD100F706C0 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 66ABD4FD1DEDAAD100F706C0 /* React.xcodeproj */; 25 | proxyType = 2; 26 | remoteGlobalIDString = 2D2A28131D9B038B00D4039D; 27 | remoteInfo = "React-tvOS"; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 665E380C1DEDA42C007CA9FA /* CopyFiles */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = "include/$(PRODUCT_NAME)"; 36 | dstSubfolderSpec = 16; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXCopyFilesBuildPhase section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 66399AC01DF0490400D167A8 /* RNWebGLARKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWebGLARKit.h; sourceTree = ""; }; 45 | 66399AC11DF0490400D167A8 /* RNWebGLARKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWebGLARKit.m; sourceTree = ""; }; 46 | 66399AC51DF049AE00D167A8 /* RNWebGLARKitManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWebGLARKitManager.h; sourceTree = ""; }; 47 | 66399AC61DF049AE00D167A8 /* RNWebGLARKitManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWebGLARKitManager.m; sourceTree = ""; }; 48 | 665E380E1DEDA42C007CA9FA /* libRNWebGLARKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNWebGLARKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 66ABD4FD1DEDAAD100F706C0 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../../react-native/React/React.xcodeproj"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 665E380B1DEDA42C007CA9FA /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 665E38051DEDA42C007CA9FA = { 64 | isa = PBXGroup; 65 | children = ( 66 | 665E38101DEDA42C007CA9FA /* RNWebGLARKit */, 67 | 665E380F1DEDA42C007CA9FA /* Products */, 68 | 66ABD4FC1DEDAAD100F706C0 /* Frameworks */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | 665E380F1DEDA42C007CA9FA /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 665E380E1DEDA42C007CA9FA /* libRNWebGLARKit.a */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | 665E38101DEDA42C007CA9FA /* RNWebGLARKit */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 66399AC01DF0490400D167A8 /* RNWebGLARKit.h */, 84 | 66399AC11DF0490400D167A8 /* RNWebGLARKit.m */, 85 | 66399AC51DF049AE00D167A8 /* RNWebGLARKitManager.h */, 86 | 66399AC61DF049AE00D167A8 /* RNWebGLARKitManager.m */, 87 | ); 88 | path = RNWebGLARKit; 89 | sourceTree = ""; 90 | }; 91 | 66ABD4FC1DEDAAD100F706C0 /* Frameworks */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 66ABD4FD1DEDAAD100F706C0 /* React.xcodeproj */, 95 | ); 96 | name = Frameworks; 97 | sourceTree = ""; 98 | }; 99 | 66ABD4FE1DEDAAD100F706C0 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 66ABD5031DEDAAD100F706C0 /* libReact.a */, 103 | 66ABD5051DEDAAD100F706C0 /* libReact-tvOS.a */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | /* End PBXGroup section */ 109 | 110 | /* Begin PBXNativeTarget section */ 111 | 665E380D1DEDA42C007CA9FA /* RNWebGLARKit */ = { 112 | isa = PBXNativeTarget; 113 | buildConfigurationList = 665E38171DEDA42C007CA9FA /* Build configuration list for PBXNativeTarget "RNWebGLARKit" */; 114 | buildPhases = ( 115 | 665E380A1DEDA42C007CA9FA /* Sources */, 116 | 665E380B1DEDA42C007CA9FA /* Frameworks */, 117 | 665E380C1DEDA42C007CA9FA /* CopyFiles */, 118 | ); 119 | buildRules = ( 120 | ); 121 | dependencies = ( 122 | ); 123 | name = RNWebGLARKit; 124 | productName = RNModule; 125 | productReference = 665E380E1DEDA42C007CA9FA /* libRNWebGLARKit.a */; 126 | productType = "com.apple.product-type.library.static"; 127 | }; 128 | /* End PBXNativeTarget section */ 129 | 130 | /* Begin PBXProject section */ 131 | 665E38061DEDA42C007CA9FA /* Project object */ = { 132 | isa = PBXProject; 133 | attributes = { 134 | LastUpgradeCheck = 0810; 135 | TargetAttributes = { 136 | 665E380D1DEDA42C007CA9FA = { 137 | CreatedOnToolsVersion = 8.1; 138 | ProvisioningStyle = Automatic; 139 | }; 140 | }; 141 | }; 142 | buildConfigurationList = 665E38091DEDA42C007CA9FA /* Build configuration list for PBXProject "RNWebGLARKit" */; 143 | compatibilityVersion = "Xcode 3.2"; 144 | developmentRegion = English; 145 | hasScannedForEncodings = 0; 146 | knownRegions = ( 147 | en, 148 | ); 149 | mainGroup = 665E38051DEDA42C007CA9FA; 150 | productRefGroup = 665E380F1DEDA42C007CA9FA /* Products */; 151 | projectDirPath = ""; 152 | projectReferences = ( 153 | { 154 | ProductGroup = 66ABD4FE1DEDAAD100F706C0 /* Products */; 155 | ProjectRef = 66ABD4FD1DEDAAD100F706C0 /* React.xcodeproj */; 156 | }, 157 | ); 158 | projectRoot = ""; 159 | targets = ( 160 | 665E380D1DEDA42C007CA9FA /* RNWebGLARKit */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXReferenceProxy section */ 166 | 66ABD5031DEDAAD100F706C0 /* libReact.a */ = { 167 | isa = PBXReferenceProxy; 168 | fileType = archive.ar; 169 | path = libReact.a; 170 | remoteRef = 66ABD5021DEDAAD100F706C0 /* PBXContainerItemProxy */; 171 | sourceTree = BUILT_PRODUCTS_DIR; 172 | }; 173 | 66ABD5051DEDAAD100F706C0 /* libReact-tvOS.a */ = { 174 | isa = PBXReferenceProxy; 175 | fileType = archive.ar; 176 | path = "libReact-tvOS.a"; 177 | remoteRef = 66ABD5041DEDAAD100F706C0 /* PBXContainerItemProxy */; 178 | sourceTree = BUILT_PRODUCTS_DIR; 179 | }; 180 | /* End PBXReferenceProxy section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | 665E380A1DEDA42C007CA9FA /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | 66399AC21DF0490400D167A8 /* RNWebGLARKit.m in Sources */, 188 | 66399AC71DF049AE00D167A8 /* RNWebGLARKitManager.m in Sources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXSourcesBuildPhase section */ 193 | 194 | /* Begin XCBuildConfiguration section */ 195 | 665E38151DEDA42C007CA9FA /* Debug */ = { 196 | isa = XCBuildConfiguration; 197 | buildSettings = { 198 | ALWAYS_SEARCH_USER_PATHS = NO; 199 | CLANG_ANALYZER_NONNULL = YES; 200 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 201 | CLANG_CXX_LIBRARY = "libc++"; 202 | CLANG_ENABLE_MODULES = YES; 203 | CLANG_ENABLE_OBJC_ARC = YES; 204 | CLANG_WARN_BOOL_CONVERSION = YES; 205 | CLANG_WARN_CONSTANT_CONVERSION = YES; 206 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 207 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 208 | CLANG_WARN_EMPTY_BODY = YES; 209 | CLANG_WARN_ENUM_CONVERSION = YES; 210 | CLANG_WARN_INFINITE_RECURSION = YES; 211 | CLANG_WARN_INT_CONVERSION = YES; 212 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 213 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 214 | CLANG_WARN_UNREACHABLE_CODE = YES; 215 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 216 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 217 | COPY_PHASE_STRIP = NO; 218 | DEBUG_INFORMATION_FORMAT = dwarf; 219 | ENABLE_STRICT_OBJC_MSGSEND = YES; 220 | ENABLE_TESTABILITY = YES; 221 | GCC_C_LANGUAGE_STANDARD = gnu99; 222 | GCC_DYNAMIC_NO_PIC = NO; 223 | GCC_NO_COMMON_BLOCKS = YES; 224 | GCC_OPTIMIZATION_LEVEL = 0; 225 | GCC_PREPROCESSOR_DEFINITIONS = ( 226 | "DEBUG=1", 227 | "$(inherited)", 228 | ); 229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 231 | GCC_WARN_UNDECLARED_SELECTOR = YES; 232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 233 | GCC_WARN_UNUSED_FUNCTION = YES; 234 | GCC_WARN_UNUSED_VARIABLE = YES; 235 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 236 | MTL_ENABLE_DEBUG_INFO = YES; 237 | ONLY_ACTIVE_ARCH = YES; 238 | SDKROOT = iphoneos; 239 | }; 240 | name = Debug; 241 | }; 242 | 665E38161DEDA42C007CA9FA /* Release */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | ALWAYS_SEARCH_USER_PATHS = NO; 246 | CLANG_ANALYZER_NONNULL = YES; 247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 248 | CLANG_CXX_LIBRARY = "libc++"; 249 | CLANG_ENABLE_MODULES = YES; 250 | CLANG_ENABLE_OBJC_ARC = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_CONSTANT_CONVERSION = YES; 253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 254 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 255 | CLANG_WARN_EMPTY_BODY = YES; 256 | CLANG_WARN_ENUM_CONVERSION = YES; 257 | CLANG_WARN_INFINITE_RECURSION = YES; 258 | CLANG_WARN_INT_CONVERSION = YES; 259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 260 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 261 | CLANG_WARN_UNREACHABLE_CODE = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 264 | COPY_PHASE_STRIP = NO; 265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 266 | ENABLE_NS_ASSERTIONS = NO; 267 | ENABLE_STRICT_OBJC_MSGSEND = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu99; 269 | GCC_NO_COMMON_BLOCKS = YES; 270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 272 | GCC_WARN_UNDECLARED_SELECTOR = YES; 273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 274 | GCC_WARN_UNUSED_FUNCTION = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 277 | MTL_ENABLE_DEBUG_INFO = NO; 278 | SDKROOT = iphoneos; 279 | VALIDATE_PRODUCT = YES; 280 | }; 281 | name = Release; 282 | }; 283 | 665E38181DEDA42C007CA9FA /* Debug */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | HEADER_SEARCH_PATHS = ( 287 | "$(SRCROOT)/../../react-native/React/**", 288 | "${SRCROOT}/../../../ios/Pods/Headers/Public/**", 289 | ); 290 | OTHER_LDFLAGS = "-ObjC"; 291 | PRODUCT_NAME = "$(TARGET_NAME)"; 292 | SKIP_INSTALL = YES; 293 | }; 294 | name = Debug; 295 | }; 296 | 665E38191DEDA42C007CA9FA /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | HEADER_SEARCH_PATHS = ( 300 | "$(SRCROOT)/../../react-native/React/**", 301 | "${SRCROOT}/../../../ios/Pods/Headers/Public/**", 302 | ); 303 | OTHER_LDFLAGS = "-ObjC"; 304 | PRODUCT_NAME = "$(TARGET_NAME)"; 305 | SKIP_INSTALL = YES; 306 | }; 307 | name = Release; 308 | }; 309 | /* End XCBuildConfiguration section */ 310 | 311 | /* Begin XCConfigurationList section */ 312 | 665E38091DEDA42C007CA9FA /* Build configuration list for PBXProject "RNWebGLARKit" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | 665E38151DEDA42C007CA9FA /* Debug */, 316 | 665E38161DEDA42C007CA9FA /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | 665E38171DEDA42C007CA9FA /* Build configuration list for PBXNativeTarget "RNWebGLARKit" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 665E38181DEDA42C007CA9FA /* Debug */, 325 | 665E38191DEDA42C007CA9FA /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | /* End XCConfigurationList section */ 331 | }; 332 | rootObject = 665E38061DEDA42C007CA9FA /* Project object */; 333 | } 334 | -------------------------------------------------------------------------------- /ios/RNWebGLARKit/RNWebGLARKit.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | typedef void (^RCTBubblingEventBlock)(NSDictionary *body); 6 | 7 | @interface RNWebGLARKit : UIView 8 | 9 | + (instancetype)sharedInstance; 10 | - (instancetype)initWithARView:(ARSCNView *)arView; 11 | 12 | #pragma mark - Properties 13 | @property (nonatomic, strong) ARSCNView *arView; 14 | @property (nonatomic, assign) BOOL debug; 15 | @property (nonatomic, assign) BOOL planeDetection; 16 | @property (nonatomic, assign) BOOL lightEstimation; 17 | @property (nonatomic, assign) ARWorldAlignment worldAlignment; 18 | @property (nonatomic, copy) RCTBubblingEventBlock onPlaneDetected; 19 | @property (nonatomic, copy) RCTBubblingEventBlock onPlaneUpdated; 20 | @property (nonatomic, copy) RCTBubblingEventBlock onPlaneRemoved; 21 | @property (nonatomic, copy) RCTBubblingEventBlock onFrameUpdate; 22 | 23 | #pragma mark - Public Method 24 | - (void)pause; 25 | - (void)resume; 26 | - (void)reset; 27 | 28 | #pragma mark - Delegates 29 | - (void)renderer:(id )renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor; 30 | - (void)renderer:(id )renderer willUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor; 31 | - (void)renderer:(id )renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor; 32 | - (void)renderer:(id )renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor; 33 | - (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame; 34 | - (void)session:(ARSession *)session cameraDidChangeTrackingState:(ARCamera *)camera; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /ios/RNWebGLARKit/RNWebGLARKit.m: -------------------------------------------------------------------------------- 1 | #import "RNWebGLARKit.h" 2 | 3 | @import CoreLocation; 4 | 5 | @interface RNWebGLARKit () 6 | 7 | @property (nonatomic, strong) ARSession* session; 8 | @property (nonatomic, strong) ARWorldTrackingConfiguration *configuration; 9 | 10 | @end 11 | 12 | void dispatch_once_on_main_thread(dispatch_once_t *predicate, 13 | dispatch_block_t block) { 14 | if ([NSThread isMainThread]) { 15 | dispatch_once(predicate, block); 16 | } else { 17 | if (DISPATCH_EXPECT(*predicate == 0L, NO)) { 18 | dispatch_sync(dispatch_get_main_queue(), ^{ 19 | dispatch_once(predicate, block); 20 | }); 21 | } 22 | } 23 | } 24 | 25 | @implementation RNWebGLARKit 26 | 27 | + (instancetype)sharedInstance { 28 | static RNWebGLARKit *instance = nil; 29 | static dispatch_once_t onceToken; 30 | 31 | dispatch_once_on_main_thread(&onceToken, ^{ 32 | if (instance == nil) { 33 | ARSCNView *arView = [[ARSCNView alloc] init]; 34 | instance = [[self alloc] initWithARView:arView]; 35 | } 36 | }); 37 | return instance; 38 | } 39 | 40 | 41 | - (instancetype)initWithARView:(ARSCNView *)arView { 42 | if ((self = [super init])) { 43 | self.arView = arView; 44 | 45 | // delegates 46 | arView.delegate = self; 47 | arView.session.delegate = self; 48 | 49 | // configuration(s) 50 | arView.autoenablesDefaultLighting = YES; 51 | arView.scene.rootNode.name = @"root"; 52 | 53 | // start ARKit 54 | [self addSubview:arView]; 55 | [self resume]; 56 | } 57 | return self; 58 | } 59 | 60 | 61 | - (void)layoutSubviews { 62 | [super layoutSubviews]; 63 | self.arView.frame = self.bounds; 64 | } 65 | 66 | - (void)pause { 67 | [self.session pause]; 68 | } 69 | 70 | - (void)resume { 71 | [self.session runWithConfiguration:self.configuration]; 72 | } 73 | 74 | - (void)reset { 75 | if (ARWorldTrackingConfiguration.isSupported) { 76 | [self.session runWithConfiguration:self.configuration options:ARSessionRunOptionRemoveExistingAnchors | ARSessionRunOptionResetTracking]; 77 | } 78 | } 79 | 80 | #pragma mark - setter-getter 81 | 82 | - (ARSession*)session { 83 | return self.arView.session; 84 | } 85 | 86 | - (BOOL)debug { 87 | return self.arView.showsStatistics; 88 | } 89 | 90 | - (void)setDebug:(BOOL)debug { 91 | if (debug) { 92 | self.arView.showsStatistics = YES; 93 | self.arView.debugOptions = ARSCNDebugOptionShowWorldOrigin | ARSCNDebugOptionShowFeaturePoints; 94 | } else { 95 | self.arView.showsStatistics = NO; 96 | self.arView.debugOptions = SCNDebugOptionNone; 97 | } 98 | } 99 | 100 | - (BOOL)planeDetection { 101 | ARWorldTrackingConfiguration *configuration = (ARWorldTrackingConfiguration *) self.session.configuration; 102 | return configuration.planeDetection == ARPlaneDetectionHorizontal; 103 | } 104 | 105 | - (void)setPlaneDetection:(BOOL)planeDetection { 106 | ARWorldTrackingConfiguration *configuration = (ARWorldTrackingConfiguration *) self.session.configuration; 107 | if (planeDetection) { 108 | configuration.planeDetection = ARPlaneDetectionHorizontal; 109 | } else { 110 | configuration.planeDetection = ARPlaneDetectionNone; 111 | } 112 | [self resume]; 113 | } 114 | 115 | - (BOOL)lightEstimation { 116 | ARConfiguration *configuration = self.session.configuration; 117 | return configuration.lightEstimationEnabled; 118 | } 119 | 120 | - (void)setLightEstimation:(BOOL)lightEstimation { 121 | ARConfiguration *configuration = self.session.configuration; 122 | configuration.lightEstimationEnabled = lightEstimation; 123 | [self resume]; 124 | } 125 | 126 | - (ARWorldAlignment)worldAlignment { 127 | ARConfiguration *configuration = self.session.configuration; 128 | return configuration.worldAlignment; 129 | } 130 | 131 | - (void)setWorldAlignment:(ARWorldAlignment)worldAlignment { 132 | ARConfiguration *configuration = self.configuration; 133 | if (worldAlignment == ARWorldAlignmentGravityAndHeading) { 134 | configuration.worldAlignment = ARWorldAlignmentGravityAndHeading; 135 | } else if (worldAlignment == ARWorldAlignmentCamera) { 136 | configuration.worldAlignment = ARWorldAlignmentCamera; 137 | } else { 138 | configuration.worldAlignment = ARWorldAlignmentGravity; 139 | } 140 | [self resume]; 141 | } 142 | 143 | #pragma mark - Lazy loads 144 | 145 | -(ARWorldTrackingConfiguration *)configuration { 146 | if (_configuration) { 147 | return _configuration; 148 | } 149 | 150 | if (!ARWorldTrackingConfiguration.isSupported) {} 151 | 152 | _configuration = [ARWorldTrackingConfiguration new]; 153 | _configuration.planeDetection = ARPlaneDetectionHorizontal; 154 | 155 | return _configuration; 156 | } 157 | 158 | 159 | #pragma mark - ARSCNViewDelegate 160 | 161 | - (void)renderer:(id )renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor { 162 | if (![anchor isKindOfClass:[ARPlaneAnchor class]]) { 163 | return; 164 | } 165 | ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor; 166 | NSLog(@"Did plane detect"); 167 | if (self.onPlaneDetected) { 168 | self.onPlaneDetected(@{ 169 | @"id": planeAnchor.identifier.UUIDString, 170 | @"alignment": @(planeAnchor.alignment), 171 | @"node": @{ @"x": @(node.position.x), @"y": @(node.position.y), @"z": @(node.position.z) }, 172 | @"center": @{ @"x": @(planeAnchor.center.x), @"y": @(planeAnchor.center.y), @"z": @(planeAnchor.center.z) }, 173 | @"extent": @{ @"x": @(planeAnchor.extent.x), @"y": @(planeAnchor.extent.y), @"z": @(planeAnchor.extent.z) }, 174 | }); 175 | } 176 | } 177 | 178 | - (void)renderer:(id )renderer willUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor { 179 | } 180 | 181 | - (void)renderer:(id )renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor { 182 | ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor; 183 | NSLog(@"Did plane update"); 184 | if (self.onPlaneUpdated) { 185 | self.onPlaneUpdated(@{ 186 | @"id": planeAnchor.identifier.UUIDString, 187 | @"alignment": @(planeAnchor.alignment), 188 | @"node": @{ @"x": @(node.position.x), @"y": @(node.position.y), @"z": @(node.position.z) }, 189 | @"center": @{ @"x": @(planeAnchor.center.x), @"y": @(planeAnchor.center.y), @"z": @(planeAnchor.center.z) }, 190 | @"extent": @{ @"x": @(planeAnchor.extent.x), @"y": @(planeAnchor.extent.y), @"z": @(planeAnchor.extent.z) }, 191 | }); 192 | } 193 | } 194 | 195 | - (void)renderer:(id )renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor { 196 | ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor; 197 | if (self.onPlaneRemoved) { 198 | self.onPlaneRemoved(@{ 199 | @"id": planeAnchor.identifier.UUIDString, 200 | }); 201 | } 202 | } 203 | 204 | 205 | static NSArray * nsArrayForMatrix(matrix_float4x4 mat) { 206 | const float *v = (const float *)&mat; 207 | return @[ 208 | @(v[0]), @(v[1]), @(v[2]), @(v[3]), 209 | @(v[4]), @(v[5]), @(v[6]), @(v[7]), 210 | @(v[8]), @(v[9]), @(v[10]), @(v[11]), 211 | @(v[12]), @(v[13]), @(v[14]), @(v[15]) 212 | ]; 213 | } 214 | 215 | #pragma mark - ARSessionDelegate 216 | 217 | - (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame { 218 | NSLog(@"Did didUpdateFrame"); 219 | if (self.onFrameUpdate) { 220 | matrix_float4x4 viewMat = [frame.camera viewMatrixForOrientation:UIInterfaceOrientationPortrait]; 221 | matrix_float4x4 projMat = [frame.camera projectionMatrixForOrientation:UIInterfaceOrientationPortrait viewportSize:self.arView.frame.size zNear:0.1 zFar:1000]; 222 | matrix_float4x4 transform = [frame.camera transform]; 223 | self.onFrameUpdate(@{ 224 | @"camera": @{ 225 | @"transform": nsArrayForMatrix(transform), 226 | @"viewMatrix": nsArrayForMatrix(viewMat), 227 | @"projectionMatrix": nsArrayForMatrix(projMat) 228 | }, 229 | @"lightEstimate": @{ 230 | @"ambientIntensity": @(frame.lightEstimate.ambientIntensity), 231 | @"ambientColorTemperature": @(frame.lightEstimate.ambientColorTemperature), 232 | } 233 | }); 234 | } 235 | } 236 | 237 | @end 238 | 239 | -------------------------------------------------------------------------------- /ios/RNWebGLARKit/RNWebGLARKitManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RNWebGLARKitManager : RCTViewManager 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /ios/RNWebGLARKit/RNWebGLARKitManager.m: -------------------------------------------------------------------------------- 1 | #import "RNWebGLARKitManager.h" 2 | #import "RNWebGLARKit.h" 3 | #import "UIKit/UIKit.h" 4 | 5 | @implementation RNWebGLARKitManager 6 | 7 | RCT_EXPORT_MODULE() 8 | 9 | - (UIView *)view { 10 | return [RNWebGLARKit sharedInstance]; 11 | } 12 | 13 | RCT_EXPORT_VIEW_PROPERTY(debug, BOOL) 14 | RCT_EXPORT_VIEW_PROPERTY(planeDetection, BOOL) 15 | RCT_EXPORT_VIEW_PROPERTY(lightEstimation, BOOL) 16 | RCT_EXPORT_VIEW_PROPERTY(worldAlignment, NSInteger) 17 | RCT_EXPORT_VIEW_PROPERTY(onPlaneDetected, RCTBubblingEventBlock) 18 | RCT_EXPORT_VIEW_PROPERTY(onPlaneUpdated, RCTBubblingEventBlock) 19 | RCT_EXPORT_VIEW_PROPERTY(onPlaneRemoved, RCTBubblingEventBlock) 20 | RCT_EXPORT_VIEW_PROPERTY(onFrameUpdate, RCTBubblingEventBlock) 21 | 22 | RCT_EXPORT_METHOD(pause:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { 23 | [[RNWebGLARKit sharedInstance] pause]; 24 | resolve(@{}); 25 | } 26 | 27 | RCT_EXPORT_METHOD(resume:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { 28 | [[RNWebGLARKit sharedInstance] resume]; 29 | resolve(@{}); 30 | } 31 | 32 | RCT_EXPORT_METHOD(reset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { 33 | [[RNWebGLARKit sharedInstance] reset]; 34 | resolve(@{}); 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-webgl-arkit", 3 | "version": "0.1.1", 4 | "description": "React Native WebGL ARKit", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "ci": "scripts/local-ci.sh" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+ssh://git@github.com/birkir/react-native-webgl-arkit.git" 12 | }, 13 | "keywords": [ 14 | "react", 15 | "react-native", 16 | "ios", 17 | "webgl", 18 | "arkit" 19 | ], 20 | "author": "Birkir Gudjonsson ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/birkir/react-native-webgl-arkit/issues" 24 | }, 25 | "homepage": "https://github.com/birkir/react-native-webgl-arkit#readme", 26 | "rnpm": { 27 | "commands": { 28 | "prelink": "node_modules/react-native-webgl-arkit/scripts/pre-link.sh", 29 | "postlink": "node_modules/react-native-webgl-arkit/scripts/post-link.sh" 30 | } 31 | }, 32 | "peerDependencies": { 33 | "react": "*", 34 | "react-native": "*", 35 | "prop-types": "*" 36 | }, 37 | "devDependencies": { 38 | "babel-eslint": "8.0.1", 39 | "eslint": "4.10.0", 40 | "eslint-config-airbnb": "16.1.0", 41 | "eslint-plugin-import": "2.8.0", 42 | "eslint-plugin-jsx-a11y": "6.0.2", 43 | "eslint-plugin-react": "7.4.0" 44 | }, 45 | "dependencies": { 46 | "prop-types": "15.6.1", 47 | "react": "16.3.2", 48 | "react-native": "0.55.4" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /scripts/copy-from-node-modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MODULE_NAME="react-native-webgl-arkit" 3 | 4 | cp -rf example/node_modules/$MODULE_NAME/{ios,src} ./ 5 | cp -rf example/node_modules/$MODULE_NAME/android/{src,build.gradle} ./android 6 | -------------------------------------------------------------------------------- /scripts/local-ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ $@ == *"--skip-new"* ]]; then 6 | skip_new=true 7 | else 8 | skip_new=false 9 | fi 10 | 11 | if [[ $@ == *"--use-old"* ]]; then 12 | use_old=true 13 | else 14 | use_old=false 15 | fi 16 | 17 | proj_dir_old=example 18 | proj_dir_new=example_tmp 19 | 20 | react_native_version=$(cat $proj_dir_old/package.json | sed -n 's/"react-native": "\(\^|~\)*\(.*\)",*/\2/p') 21 | library_name=$(node -p "require('./package.json').name") 22 | 23 | files_to_copy=( 24 | .appiumhelperrc 25 | .babelrc 26 | package.json 27 | index.{ios,android}.js 28 | android/app/build.gradle 29 | src 30 | scripts 31 | __tests__ 32 | ) 33 | 34 | isMacOS() { 35 | [ "$(uname)" == "Darwin" ] 36 | } 37 | 38 | ################### 39 | # BEFORE INSTALL # 40 | ################### 41 | 42 | # Check is macOS 43 | ! isMacOS && echo "Current os is not macOS, setup for iOS will be skipped" 44 | # Install react-native-cli if not exist 45 | if ! type react-native > /dev/null; then 46 | yarn install -g react-native-cli 47 | fi 48 | 49 | if ($skip_new && ! $use_old); then 50 | echo "Creating new example project skipped" 51 | # Go to new test project 52 | cd $proj_dir_new 53 | elif (! $skip_new && ! $use_old); then 54 | # Remove react-native to avoid affecting react-native init 55 | rm -rf node_modules/react-native 56 | echo "Creating new example project" 57 | # Remove old test project and tmp dir if exist 58 | rm -rf $proj_dir_new tmp 59 | # Init new test project in tmp directory 60 | mkdir tmp 61 | cd tmp 62 | react-native init $proj_dir_old --version $react_native_version 63 | # Move new project from tmp dir and remove tmp dir 64 | cd .. 65 | mv tmp/$proj_dir_old $proj_dir_new 66 | rm -rf tmp 67 | # Remove default __tests__ folder from new project directory 68 | rm -rf $proj_dir_new/__tests__ 69 | # Copy necessary files from example project 70 | for i in ${files_to_copy[@]}; do 71 | if [ -e $proj_dir_old/$i ]; then 72 | cp -Rp $proj_dir_old/$i $proj_dir_new/$i 73 | fi 74 | done 75 | # Go to new test project 76 | cd $proj_dir_new 77 | else 78 | echo "Using example folder for tests" 79 | # Go to old test project 80 | cd $proj_dir_old 81 | fi 82 | 83 | ################### 84 | # INSTALL # 85 | ################### 86 | 87 | # Install dependencies 88 | npm install 89 | # Link project 90 | react-native unlink $library_name 91 | react-native link 92 | 93 | ################### 94 | # BEFORE BUILD # 95 | ################### 96 | 97 | # Run appium 98 | (pkill -9 -f appium || true) 99 | yarn run appium > /dev/null 2>&1 & 100 | 101 | ################### 102 | # BUILD # 103 | ################### 104 | 105 | # Build Android app 106 | yarn run build:android 107 | # Build iOS app 108 | isMacOS && yarn run build:ios 109 | 110 | ################### 111 | # TESTS # 112 | ################### 113 | 114 | # Run Android e2e tests 115 | yarn run test:android 116 | # Run iOS e2e tests 117 | if isMacOS; then 118 | yarn run test:ios 119 | fi 120 | -------------------------------------------------------------------------------- /scripts/post-link-android.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // This code is taken from 4 | // https://github.com/maxs15/react-native-spinkit 5 | 6 | var fs = require('fs'); 7 | var path = require('path'); 8 | var GRADLE_SCRIPT_PATH = path.join(process.cwd(), 'android', 'build.gradle'); 9 | 10 | // load build.gradle content 11 | try { 12 | var cfg = fs.readFileSync(GRADLE_SCRIPT_PATH); 13 | } catch(err) { 14 | console.log(err.stack); 15 | console.log('Failed to load `android/build.gradle` when linking react-native-webgl-arkit'); 16 | } 17 | 18 | var depStr = String(cfg).match(/allprojects(.|[\r\n])+/); 19 | 20 | if(depStr === null) { 21 | console.log('Could not find `allprojects { }` block in build.gradle'); 22 | } 23 | 24 | // search fro allprojects {...} block 25 | var bracketCount = 0; 26 | var str = depStr[0]; 27 | var replacePos = 0; 28 | for(var i in str) { 29 | if(str[i] === '{') 30 | bracketCount ++; 31 | else if(str[i] === '}'){ 32 | bracketCount --; 33 | // block found 34 | if(bracketCount === 0) { 35 | replacePos = i; 36 | break; 37 | } 38 | } 39 | } 40 | 41 | // add jitpack repo to `repositories` block 42 | var dep = str.substr(0, replacePos); 43 | 44 | // Chech if the repository already exists 45 | if (String(dep).match(/url[^h]*https\:\/\/jitpack\.io/) === null) { 46 | 47 | dep = String(dep).replace(/repositories[^\{]*\{/, 'repositories {\r\n // Add jitpack repository (added by react-native-webl-arkit)\r\n maven { url "https://jitpack.io" }'); 48 | str = dep + str.substr(replacePos, str.length - replacePos); 49 | 50 | // replace original build script 51 | depStr = String(cfg).replace(/allprojects(.|[\r\n])+/, str); 52 | fs.writeFileSync(GRADLE_SCRIPT_PATH, depStr); 53 | } 54 | -------------------------------------------------------------------------------- /scripts/post-link-ios.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$(uname)" != "Darwin" ]; then 4 | echo "Current OS is not macOS, skip iOS linking" 5 | exit 0 6 | fi 7 | 8 | ios_dir=`pwd`/ios 9 | if [ -d ios_dir ]; then 10 | exit 0 11 | fi 12 | 13 | podfile="$ios_dir/Podfile" 14 | 15 | # Type your pods here. 16 | # Example: pod_dep="pod 'Stripe'" 17 | pod_dep="" 18 | 19 | echo "Checking Podfile in iOS project ($podfile)" 20 | 21 | if [ ! -f $podfile ]; then 22 | echo "Adding Podfile to iOS project" 23 | 24 | cd ios 25 | pod init >/dev/null 2>&1 26 | cd .. 27 | else 28 | echo "Found an existing Podfile" 29 | fi 30 | 31 | if ! grep -q "$pod_dep" "$podfile"; then 32 | echo "Adding the following pod to Podfile": 33 | echo "" 34 | echo $pod_dep 35 | echo "" 36 | 37 | echo $pod_dep >> $podfile 38 | fi 39 | 40 | echo "Installing Pods" 41 | 42 | pod install --project-directory=ios 43 | -------------------------------------------------------------------------------- /scripts/post-link.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | $(dirname "$0")/post-link-ios.sh 4 | $(dirname "$0")/post-link-android.sh 5 | -------------------------------------------------------------------------------- /scripts/pre-link.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Preparing to link react-native-webgl-arkit for iOS" 4 | 5 | echo "Checking CocoaPods..." 6 | has_cocoapods=`which pod >/dev/null 2>&1` 7 | if [ -z "$has_cocoapods" ] 8 | then 9 | echo "CocoaPods already installed" 10 | else 11 | echo "Installing CocoaPods..." 12 | gem install cocoapods 13 | fi 14 | -------------------------------------------------------------------------------- /src/Camera.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import RNWebGLARKitView from './RNWebGLARKitView'; 4 | import kelvin2rgb from './kelvin2rgb'; 5 | 6 | export default class Camera extends Component { 7 | 8 | static propTypes = { 9 | camera: PropTypes.any, // eslint-disable-line 10 | ambientLight: PropTypes.any, // eslint-disable-line 11 | onFrameUpdate: PropTypes.func, 12 | }; 13 | 14 | static defaultProps = { 15 | camera: undefined, 16 | ambientLight: undefined, 17 | onFrameUpdate: undefined, 18 | } 19 | 20 | constructor(props) { 21 | super(props); 22 | if (this.props.camera) { 23 | // Set camera to class scope 24 | this.camera = this.props.camera; 25 | 26 | // Set dimensions 27 | this.aspect = this.camera.width / this.camera.height; 28 | this.camera.near = 0.01; // Fixed for now 29 | this.camera.far = 1000; // Fixed for now 30 | 31 | // Update perspective 32 | this.camera.updateMatrixWorld = () => { 33 | if (this.frame && this.frame.camera) { 34 | const { viewMatrix, projectionMatrix } = this.frame.camera || {}; 35 | this.camera.matrixWorldInverse.fromArray(viewMatrix); 36 | this.camera.matrixWorld.getInverse(this.camera.matrixWorldInverse); 37 | this.camera.projectionMatrix.fromArray(projectionMatrix); 38 | } 39 | }; 40 | 41 | // Update projection matrix 42 | this.camera.updateProjectionMatrix = () => this.camera.updateMatrixWorld(); 43 | } 44 | } 45 | 46 | onFrameUpdate = (e) => { 47 | this.frame = e.nativeEvent; 48 | 49 | if (this.props.ambientLight) { 50 | const { ambientColorTemperature, ambientIntensity } = this.frame.lightEstimate; 51 | this.props.ambientLight.color.setRGB(...kelvin2rgb(ambientColorTemperature)); 52 | this.props.ambientLight.intensity = ambientIntensity / 1000.0; 53 | } 54 | 55 | if (this.props.onFrameUpdate) { 56 | this.props.onFrameUpdate(e); 57 | } 58 | } 59 | 60 | render() { 61 | return ( 62 | 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/RNWebGLARKitView.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View, NativeModules, requireNativeComponent } from 'react-native'; 3 | import PropTypes from 'prop-types'; 4 | 5 | const { RNWebGLARKitManager } = NativeModules; 6 | 7 | class RNWebGLARKit extends Component { 8 | 9 | static propTypes = { 10 | ...View.propTypes, 11 | debug: PropTypes.bool, 12 | planeDetection: PropTypes.bool, 13 | lightEstimation: PropTypes.bool, 14 | worldAlignment: PropTypes.number, 15 | onPlaneDetected: PropTypes.func, 16 | onPlaneUpdated: PropTypes.func, 17 | onPlaneRemoved: PropTypes.func, 18 | onFrameUpdate: PropTypes.func, 19 | } 20 | 21 | static defaultProps = { 22 | debug: false, 23 | planeDetection: true, 24 | lightEstimation: true, 25 | worldAlignment: undefined, 26 | onPlaneDetected: undefined, 27 | onPlaneUpdated: undefined, 28 | onPlaneRemoved: undefined, 29 | onFrameUpdate: undefined, 30 | } 31 | 32 | constructor(props) { 33 | super(props); 34 | RNWebGLARKitManager.reset(); 35 | } 36 | 37 | componentDidMount() { 38 | RNWebGLARKitManager.resume(); 39 | } 40 | 41 | componentWillUnmount() { 42 | RNWebGLARKitManager.pause(); 43 | } 44 | 45 | render() { 46 | return ( 47 | 50 | ); 51 | } 52 | } 53 | 54 | const RNWebGLARKitView = requireNativeComponent('RNWebGLARKit', RNWebGLARKit); 55 | 56 | export default RNWebGLARKitView; 57 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Camera from './Camera'; 2 | 3 | module.exports = { 4 | Camera, 5 | }; 6 | -------------------------------------------------------------------------------- /src/kelvin2rgb.js: -------------------------------------------------------------------------------- 1 | /* eslint no-mixed-operators: 0 no-restricted-properties: 0 */ 2 | export default (kelvin) => { 3 | const t = kelvin / 100; 4 | const rgb = { r: 0, g: 0, b: 0 }; 5 | 6 | if (t <= 66) { 7 | rgb.r = 255; 8 | } else { 9 | rgb.r = t - 60; 10 | rgb.r = 329.698727466 * Math.pow(rgb.r, -0.1332047592); 11 | } 12 | 13 | if (t <= 66) { 14 | rgb.g = t; 15 | rgb.g = 99.4708025861 * Math.log(rgb.g) - 161.1195681661; 16 | } else { 17 | rgb.g = t - 60; 18 | rgb.g = 288.1221695283 * Math.pow(rgb.g, -0.0755148492); 19 | } 20 | 21 | if (t >= 66) { 22 | rgb.b = 255; 23 | } else if (t <= 19) { 24 | rgb.b = 0; 25 | } else { 26 | rgb.b = t - 10; 27 | rgb.b = 138.5177312231 * Math.log(rgb.b) - 305.0447927307; 28 | } 29 | 30 | return Object.values(rgb) 31 | .map(value => Math.max(0, Math.min(1, value / 255))); 32 | }; 33 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | acorn-jsx@^3.0.0: 6 | version "3.0.1" 7 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" 8 | dependencies: 9 | acorn "^3.0.4" 10 | 11 | acorn@^3.0.4: 12 | version "3.3.0" 13 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" 14 | 15 | acorn@^5.1.1: 16 | version "5.2.1" 17 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" 18 | 19 | ajv-keywords@^2.1.0: 20 | version "2.1.1" 21 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" 22 | 23 | ajv@^5.2.0, ajv@^5.2.3: 24 | version "5.3.0" 25 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" 26 | dependencies: 27 | co "^4.6.0" 28 | fast-deep-equal "^1.0.0" 29 | fast-json-stable-stringify "^2.0.0" 30 | json-schema-traverse "^0.3.0" 31 | 32 | ansi-escapes@^3.0.0: 33 | version "3.0.0" 34 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" 35 | 36 | ansi-regex@^2.0.0: 37 | version "2.1.1" 38 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 39 | 40 | ansi-regex@^3.0.0: 41 | version "3.0.0" 42 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 43 | 44 | ansi-styles@^2.2.1: 45 | version "2.2.1" 46 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 47 | 48 | ansi-styles@^3.1.0: 49 | version "3.2.0" 50 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" 51 | dependencies: 52 | color-convert "^1.9.0" 53 | 54 | argparse@^1.0.7: 55 | version "1.0.9" 56 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 57 | dependencies: 58 | sprintf-js "~1.0.2" 59 | 60 | aria-query@^0.7.0: 61 | version "0.7.0" 62 | resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.7.0.tgz#4af10a1e61573ddea0cf3b99b51c52c05b424d24" 63 | dependencies: 64 | ast-types-flow "0.0.7" 65 | 66 | array-includes@^3.0.3: 67 | version "3.0.3" 68 | resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" 69 | dependencies: 70 | define-properties "^1.1.2" 71 | es-abstract "^1.7.0" 72 | 73 | array-union@^1.0.1: 74 | version "1.0.2" 75 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 76 | dependencies: 77 | array-uniq "^1.0.1" 78 | 79 | array-uniq@^1.0.1: 80 | version "1.0.3" 81 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 82 | 83 | arrify@^1.0.0: 84 | version "1.0.1" 85 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 86 | 87 | asap@~2.0.3: 88 | version "2.0.6" 89 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" 90 | 91 | ast-types-flow@0.0.7: 92 | version "0.0.7" 93 | resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" 94 | 95 | axobject-query@^0.1.0: 96 | version "0.1.0" 97 | resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0" 98 | dependencies: 99 | ast-types-flow "0.0.7" 100 | 101 | babel-code-frame@7.0.0-beta.0: 102 | version "7.0.0-beta.0" 103 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz#418a7b5f3f7dc9a4670e61b1158b4c5661bec98d" 104 | dependencies: 105 | chalk "^2.0.0" 106 | esutils "^2.0.2" 107 | js-tokens "^3.0.0" 108 | 109 | babel-code-frame@^6.22.0: 110 | version "6.26.0" 111 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 112 | dependencies: 113 | chalk "^1.1.3" 114 | esutils "^2.0.2" 115 | js-tokens "^3.0.2" 116 | 117 | babel-eslint@8.0.1: 118 | version "8.0.1" 119 | resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.1.tgz#5d718be7a328625d006022eb293ed3008cbd6346" 120 | dependencies: 121 | babel-code-frame "7.0.0-beta.0" 122 | babel-traverse "7.0.0-beta.0" 123 | babel-types "7.0.0-beta.0" 124 | babylon "7.0.0-beta.22" 125 | 126 | babel-helper-function-name@7.0.0-beta.0: 127 | version "7.0.0-beta.0" 128 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz#d1b6779b647e5c5c31ebeb05e13b998e4d352d56" 129 | dependencies: 130 | babel-helper-get-function-arity "7.0.0-beta.0" 131 | babel-template "7.0.0-beta.0" 132 | babel-traverse "7.0.0-beta.0" 133 | babel-types "7.0.0-beta.0" 134 | 135 | babel-helper-get-function-arity@7.0.0-beta.0: 136 | version "7.0.0-beta.0" 137 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz#9d1ab7213bb5efe1ef1638a8ea1489969b5a8b6e" 138 | dependencies: 139 | babel-types "7.0.0-beta.0" 140 | 141 | babel-messages@7.0.0-beta.0: 142 | version "7.0.0-beta.0" 143 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-beta.0.tgz#6df01296e49fc8fbd0637394326a167f36da817b" 144 | 145 | babel-template@7.0.0-beta.0: 146 | version "7.0.0-beta.0" 147 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.0.tgz#85083cf9e4395d5e48bf5154d7a8d6991cafecfb" 148 | dependencies: 149 | babel-traverse "7.0.0-beta.0" 150 | babel-types "7.0.0-beta.0" 151 | babylon "7.0.0-beta.22" 152 | lodash "^4.2.0" 153 | 154 | babel-traverse@7.0.0-beta.0: 155 | version "7.0.0-beta.0" 156 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz#da14be9b762f62a2f060db464eaafdd8cd072a41" 157 | dependencies: 158 | babel-code-frame "7.0.0-beta.0" 159 | babel-helper-function-name "7.0.0-beta.0" 160 | babel-messages "7.0.0-beta.0" 161 | babel-types "7.0.0-beta.0" 162 | babylon "7.0.0-beta.22" 163 | debug "^3.0.1" 164 | globals "^10.0.0" 165 | invariant "^2.2.0" 166 | lodash "^4.2.0" 167 | 168 | babel-types@7.0.0-beta.0: 169 | version "7.0.0-beta.0" 170 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.0.tgz#eb8b6e556470e6dcc4aef982d79ad229469b5169" 171 | dependencies: 172 | esutils "^2.0.2" 173 | lodash "^4.2.0" 174 | to-fast-properties "^2.0.0" 175 | 176 | babylon@7.0.0-beta.22: 177 | version "7.0.0-beta.22" 178 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.22.tgz#74f0ad82ed7c7c3cfeab74cf684f815104161b65" 179 | 180 | balanced-match@^1.0.0: 181 | version "1.0.0" 182 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 183 | 184 | brace-expansion@^1.1.7: 185 | version "1.1.8" 186 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 187 | dependencies: 188 | balanced-match "^1.0.0" 189 | concat-map "0.0.1" 190 | 191 | builtin-modules@^1.0.0, builtin-modules@^1.1.1: 192 | version "1.1.1" 193 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 194 | 195 | caller-path@^0.1.0: 196 | version "0.1.0" 197 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" 198 | dependencies: 199 | callsites "^0.2.0" 200 | 201 | callsites@^0.2.0: 202 | version "0.2.0" 203 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" 204 | 205 | chalk@^1.1.3: 206 | version "1.1.3" 207 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 208 | dependencies: 209 | ansi-styles "^2.2.1" 210 | escape-string-regexp "^1.0.2" 211 | has-ansi "^2.0.0" 212 | strip-ansi "^3.0.0" 213 | supports-color "^2.0.0" 214 | 215 | chalk@^2.0.0, chalk@^2.1.0: 216 | version "2.3.0" 217 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" 218 | dependencies: 219 | ansi-styles "^3.1.0" 220 | escape-string-regexp "^1.0.5" 221 | supports-color "^4.0.0" 222 | 223 | circular-json@^0.3.1: 224 | version "0.3.3" 225 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" 226 | 227 | cli-cursor@^2.1.0: 228 | version "2.1.0" 229 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 230 | dependencies: 231 | restore-cursor "^2.0.0" 232 | 233 | cli-width@^2.0.0: 234 | version "2.2.0" 235 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" 236 | 237 | co@^4.6.0: 238 | version "4.6.0" 239 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 240 | 241 | color-convert@^1.9.0: 242 | version "1.9.0" 243 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" 244 | dependencies: 245 | color-name "^1.1.1" 246 | 247 | color-name@^1.1.1: 248 | version "1.1.3" 249 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 250 | 251 | concat-map@0.0.1: 252 | version "0.0.1" 253 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 254 | 255 | concat-stream@^1.6.0: 256 | version "1.6.0" 257 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" 258 | dependencies: 259 | inherits "^2.0.3" 260 | readable-stream "^2.2.2" 261 | typedarray "^0.0.6" 262 | 263 | contains-path@^0.1.0: 264 | version "0.1.0" 265 | resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" 266 | 267 | core-js@^1.0.0: 268 | version "1.2.7" 269 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" 270 | 271 | core-util-is@~1.0.0: 272 | version "1.0.2" 273 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 274 | 275 | cross-spawn@^5.1.0: 276 | version "5.1.0" 277 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 278 | dependencies: 279 | lru-cache "^4.0.1" 280 | shebang-command "^1.2.0" 281 | which "^1.2.9" 282 | 283 | damerau-levenshtein@^1.0.0: 284 | version "1.0.4" 285 | resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" 286 | 287 | debug@^2.6.8: 288 | version "2.6.9" 289 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 290 | dependencies: 291 | ms "2.0.0" 292 | 293 | debug@^3.0.1: 294 | version "3.1.0" 295 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 296 | dependencies: 297 | ms "2.0.0" 298 | 299 | deep-is@~0.1.3: 300 | version "0.1.3" 301 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 302 | 303 | define-properties@^1.1.2: 304 | version "1.1.2" 305 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" 306 | dependencies: 307 | foreach "^2.0.5" 308 | object-keys "^1.0.8" 309 | 310 | del@^2.0.2: 311 | version "2.2.2" 312 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" 313 | dependencies: 314 | globby "^5.0.0" 315 | is-path-cwd "^1.0.0" 316 | is-path-in-cwd "^1.0.0" 317 | object-assign "^4.0.1" 318 | pify "^2.0.0" 319 | pinkie-promise "^2.0.0" 320 | rimraf "^2.2.8" 321 | 322 | doctrine@1.5.0: 323 | version "1.5.0" 324 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" 325 | dependencies: 326 | esutils "^2.0.2" 327 | isarray "^1.0.0" 328 | 329 | doctrine@^2.0.0: 330 | version "2.0.0" 331 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" 332 | dependencies: 333 | esutils "^2.0.2" 334 | isarray "^1.0.0" 335 | 336 | emoji-regex@^6.1.0: 337 | version "6.5.1" 338 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" 339 | 340 | encoding@^0.1.11: 341 | version "0.1.12" 342 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" 343 | dependencies: 344 | iconv-lite "~0.4.13" 345 | 346 | error-ex@^1.2.0: 347 | version "1.3.1" 348 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" 349 | dependencies: 350 | is-arrayish "^0.2.1" 351 | 352 | es-abstract@^1.7.0: 353 | version "1.9.0" 354 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" 355 | dependencies: 356 | es-to-primitive "^1.1.1" 357 | function-bind "^1.1.1" 358 | has "^1.0.1" 359 | is-callable "^1.1.3" 360 | is-regex "^1.0.4" 361 | 362 | es-to-primitive@^1.1.1: 363 | version "1.1.1" 364 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" 365 | dependencies: 366 | is-callable "^1.1.1" 367 | is-date-object "^1.0.1" 368 | is-symbol "^1.0.1" 369 | 370 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 371 | version "1.0.5" 372 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 373 | 374 | eslint-config-airbnb-base@^12.1.0: 375 | version "12.1.0" 376 | resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" 377 | dependencies: 378 | eslint-restricted-globals "^0.1.1" 379 | 380 | eslint-config-airbnb@16.1.0: 381 | version "16.1.0" 382 | resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz#2546bfb02cc9fe92284bf1723ccf2e87bc45ca46" 383 | dependencies: 384 | eslint-config-airbnb-base "^12.1.0" 385 | 386 | eslint-import-resolver-node@^0.3.1: 387 | version "0.3.1" 388 | resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" 389 | dependencies: 390 | debug "^2.6.8" 391 | resolve "^1.2.0" 392 | 393 | eslint-module-utils@^2.1.1: 394 | version "2.1.1" 395 | resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" 396 | dependencies: 397 | debug "^2.6.8" 398 | pkg-dir "^1.0.0" 399 | 400 | eslint-plugin-import@2.8.0: 401 | version "2.8.0" 402 | resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894" 403 | dependencies: 404 | builtin-modules "^1.1.1" 405 | contains-path "^0.1.0" 406 | debug "^2.6.8" 407 | doctrine "1.5.0" 408 | eslint-import-resolver-node "^0.3.1" 409 | eslint-module-utils "^2.1.1" 410 | has "^1.0.1" 411 | lodash.cond "^4.3.0" 412 | minimatch "^3.0.3" 413 | read-pkg-up "^2.0.0" 414 | 415 | eslint-plugin-jsx-a11y@6.0.2: 416 | version "6.0.2" 417 | resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.2.tgz#659277a758b036c305a7e4a13057c301cd3be73f" 418 | dependencies: 419 | aria-query "^0.7.0" 420 | array-includes "^3.0.3" 421 | ast-types-flow "0.0.7" 422 | axobject-query "^0.1.0" 423 | damerau-levenshtein "^1.0.0" 424 | emoji-regex "^6.1.0" 425 | jsx-ast-utils "^1.4.0" 426 | 427 | eslint-plugin-react@7.4.0: 428 | version "7.4.0" 429 | resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz#300a95861b9729c087d362dd64abcc351a74364a" 430 | dependencies: 431 | doctrine "^2.0.0" 432 | has "^1.0.1" 433 | jsx-ast-utils "^2.0.0" 434 | prop-types "^15.5.10" 435 | 436 | eslint-restricted-globals@^0.1.1: 437 | version "0.1.1" 438 | resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" 439 | 440 | eslint-scope@^3.7.1: 441 | version "3.7.1" 442 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" 443 | dependencies: 444 | esrecurse "^4.1.0" 445 | estraverse "^4.1.1" 446 | 447 | eslint@4.10.0: 448 | version "4.10.0" 449 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.10.0.tgz#f25d0d7955c81968c2309aa5c9a229e045176bb7" 450 | dependencies: 451 | ajv "^5.2.0" 452 | babel-code-frame "^6.22.0" 453 | chalk "^2.1.0" 454 | concat-stream "^1.6.0" 455 | cross-spawn "^5.1.0" 456 | debug "^3.0.1" 457 | doctrine "^2.0.0" 458 | eslint-scope "^3.7.1" 459 | espree "^3.5.1" 460 | esquery "^1.0.0" 461 | estraverse "^4.2.0" 462 | esutils "^2.0.2" 463 | file-entry-cache "^2.0.0" 464 | functional-red-black-tree "^1.0.1" 465 | glob "^7.1.2" 466 | globals "^9.17.0" 467 | ignore "^3.3.3" 468 | imurmurhash "^0.1.4" 469 | inquirer "^3.0.6" 470 | is-resolvable "^1.0.0" 471 | js-yaml "^3.9.1" 472 | json-stable-stringify "^1.0.1" 473 | levn "^0.3.0" 474 | lodash "^4.17.4" 475 | minimatch "^3.0.2" 476 | mkdirp "^0.5.1" 477 | natural-compare "^1.4.0" 478 | optionator "^0.8.2" 479 | path-is-inside "^1.0.2" 480 | pluralize "^7.0.0" 481 | progress "^2.0.0" 482 | require-uncached "^1.0.3" 483 | semver "^5.3.0" 484 | strip-ansi "^4.0.0" 485 | strip-json-comments "~2.0.1" 486 | table "^4.0.1" 487 | text-table "~0.2.0" 488 | 489 | espree@^3.5.1: 490 | version "3.5.1" 491 | resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.1.tgz#0c988b8ab46db53100a1954ae4ba995ddd27d87e" 492 | dependencies: 493 | acorn "^5.1.1" 494 | acorn-jsx "^3.0.0" 495 | 496 | esprima@^4.0.0: 497 | version "4.0.0" 498 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" 499 | 500 | esquery@^1.0.0: 501 | version "1.0.0" 502 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" 503 | dependencies: 504 | estraverse "^4.0.0" 505 | 506 | esrecurse@^4.1.0: 507 | version "4.2.0" 508 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" 509 | dependencies: 510 | estraverse "^4.1.0" 511 | object-assign "^4.0.1" 512 | 513 | estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: 514 | version "4.2.0" 515 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" 516 | 517 | esutils@^2.0.2: 518 | version "2.0.2" 519 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 520 | 521 | external-editor@^2.0.4: 522 | version "2.0.5" 523 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.5.tgz#52c249a3981b9ba187c7cacf5beb50bf1d91a6bc" 524 | dependencies: 525 | iconv-lite "^0.4.17" 526 | jschardet "^1.4.2" 527 | tmp "^0.0.33" 528 | 529 | fast-deep-equal@^1.0.0: 530 | version "1.0.0" 531 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" 532 | 533 | fast-json-stable-stringify@^2.0.0: 534 | version "2.0.0" 535 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" 536 | 537 | fast-levenshtein@~2.0.4: 538 | version "2.0.6" 539 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 540 | 541 | fbjs@^0.8.16: 542 | version "0.8.16" 543 | resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" 544 | dependencies: 545 | core-js "^1.0.0" 546 | isomorphic-fetch "^2.1.1" 547 | loose-envify "^1.0.0" 548 | object-assign "^4.1.0" 549 | promise "^7.1.1" 550 | setimmediate "^1.0.5" 551 | ua-parser-js "^0.7.9" 552 | 553 | figures@^2.0.0: 554 | version "2.0.0" 555 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" 556 | dependencies: 557 | escape-string-regexp "^1.0.5" 558 | 559 | file-entry-cache@^2.0.0: 560 | version "2.0.0" 561 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" 562 | dependencies: 563 | flat-cache "^1.2.1" 564 | object-assign "^4.0.1" 565 | 566 | find-up@^1.0.0: 567 | version "1.1.2" 568 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 569 | dependencies: 570 | path-exists "^2.0.0" 571 | pinkie-promise "^2.0.0" 572 | 573 | find-up@^2.0.0: 574 | version "2.1.0" 575 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" 576 | dependencies: 577 | locate-path "^2.0.0" 578 | 579 | flat-cache@^1.2.1: 580 | version "1.3.0" 581 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" 582 | dependencies: 583 | circular-json "^0.3.1" 584 | del "^2.0.2" 585 | graceful-fs "^4.1.2" 586 | write "^0.2.1" 587 | 588 | foreach@^2.0.5: 589 | version "2.0.5" 590 | resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" 591 | 592 | fs.realpath@^1.0.0: 593 | version "1.0.0" 594 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 595 | 596 | function-bind@^1.0.2, function-bind@^1.1.1: 597 | version "1.1.1" 598 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 599 | 600 | functional-red-black-tree@^1.0.1: 601 | version "1.0.1" 602 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 603 | 604 | glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: 605 | version "7.1.2" 606 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 607 | dependencies: 608 | fs.realpath "^1.0.0" 609 | inflight "^1.0.4" 610 | inherits "2" 611 | minimatch "^3.0.4" 612 | once "^1.3.0" 613 | path-is-absolute "^1.0.0" 614 | 615 | globals@^10.0.0: 616 | version "10.3.0" 617 | resolved "https://registry.yarnpkg.com/globals/-/globals-10.3.0.tgz#716aba93657b56630b5a0e77de5ea8ac6215afaa" 618 | 619 | globals@^9.17.0: 620 | version "9.18.0" 621 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 622 | 623 | globby@^5.0.0: 624 | version "5.0.0" 625 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" 626 | dependencies: 627 | array-union "^1.0.1" 628 | arrify "^1.0.0" 629 | glob "^7.0.3" 630 | object-assign "^4.0.1" 631 | pify "^2.0.0" 632 | pinkie-promise "^2.0.0" 633 | 634 | graceful-fs@^4.1.2: 635 | version "4.1.11" 636 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 637 | 638 | has-ansi@^2.0.0: 639 | version "2.0.0" 640 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 641 | dependencies: 642 | ansi-regex "^2.0.0" 643 | 644 | has-flag@^2.0.0: 645 | version "2.0.0" 646 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 647 | 648 | has@^1.0.1: 649 | version "1.0.1" 650 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" 651 | dependencies: 652 | function-bind "^1.0.2" 653 | 654 | hosted-git-info@^2.1.4: 655 | version "2.5.0" 656 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" 657 | 658 | iconv-lite@^0.4.17, iconv-lite@~0.4.13: 659 | version "0.4.19" 660 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" 661 | 662 | ignore@^3.3.3: 663 | version "3.3.7" 664 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" 665 | 666 | imurmurhash@^0.1.4: 667 | version "0.1.4" 668 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 669 | 670 | inflight@^1.0.4: 671 | version "1.0.6" 672 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 673 | dependencies: 674 | once "^1.3.0" 675 | wrappy "1" 676 | 677 | inherits@2, inherits@^2.0.3, inherits@~2.0.3: 678 | version "2.0.3" 679 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 680 | 681 | inquirer@^3.0.6: 682 | version "3.3.0" 683 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" 684 | dependencies: 685 | ansi-escapes "^3.0.0" 686 | chalk "^2.0.0" 687 | cli-cursor "^2.1.0" 688 | cli-width "^2.0.0" 689 | external-editor "^2.0.4" 690 | figures "^2.0.0" 691 | lodash "^4.3.0" 692 | mute-stream "0.0.7" 693 | run-async "^2.2.0" 694 | rx-lite "^4.0.8" 695 | rx-lite-aggregates "^4.0.8" 696 | string-width "^2.1.0" 697 | strip-ansi "^4.0.0" 698 | through "^2.3.6" 699 | 700 | invariant@^2.2.0: 701 | version "2.2.2" 702 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" 703 | dependencies: 704 | loose-envify "^1.0.0" 705 | 706 | is-arrayish@^0.2.1: 707 | version "0.2.1" 708 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 709 | 710 | is-builtin-module@^1.0.0: 711 | version "1.0.0" 712 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 713 | dependencies: 714 | builtin-modules "^1.0.0" 715 | 716 | is-callable@^1.1.1, is-callable@^1.1.3: 717 | version "1.1.3" 718 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" 719 | 720 | is-date-object@^1.0.1: 721 | version "1.0.1" 722 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 723 | 724 | is-fullwidth-code-point@^2.0.0: 725 | version "2.0.0" 726 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 727 | 728 | is-path-cwd@^1.0.0: 729 | version "1.0.0" 730 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" 731 | 732 | is-path-in-cwd@^1.0.0: 733 | version "1.0.0" 734 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" 735 | dependencies: 736 | is-path-inside "^1.0.0" 737 | 738 | is-path-inside@^1.0.0: 739 | version "1.0.0" 740 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" 741 | dependencies: 742 | path-is-inside "^1.0.1" 743 | 744 | is-promise@^2.1.0: 745 | version "2.1.0" 746 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" 747 | 748 | is-regex@^1.0.4: 749 | version "1.0.4" 750 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 751 | dependencies: 752 | has "^1.0.1" 753 | 754 | is-resolvable@^1.0.0: 755 | version "1.0.0" 756 | resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" 757 | dependencies: 758 | tryit "^1.0.1" 759 | 760 | is-stream@^1.0.1: 761 | version "1.1.0" 762 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 763 | 764 | is-symbol@^1.0.1: 765 | version "1.0.1" 766 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" 767 | 768 | isarray@^1.0.0, isarray@~1.0.0: 769 | version "1.0.0" 770 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 771 | 772 | isexe@^2.0.0: 773 | version "2.0.0" 774 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 775 | 776 | isomorphic-fetch@^2.1.1: 777 | version "2.2.1" 778 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" 779 | dependencies: 780 | node-fetch "^1.0.1" 781 | whatwg-fetch ">=0.10.0" 782 | 783 | js-tokens@^3.0.0, js-tokens@^3.0.2: 784 | version "3.0.2" 785 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 786 | 787 | js-yaml@^3.9.1: 788 | version "3.10.0" 789 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" 790 | dependencies: 791 | argparse "^1.0.7" 792 | esprima "^4.0.0" 793 | 794 | jschardet@^1.4.2: 795 | version "1.6.0" 796 | resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" 797 | 798 | json-schema-traverse@^0.3.0: 799 | version "0.3.1" 800 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" 801 | 802 | json-stable-stringify@^1.0.1: 803 | version "1.0.1" 804 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" 805 | dependencies: 806 | jsonify "~0.0.0" 807 | 808 | jsonify@~0.0.0: 809 | version "0.0.0" 810 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 811 | 812 | jsx-ast-utils@^1.4.0: 813 | version "1.4.1" 814 | resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" 815 | 816 | jsx-ast-utils@^2.0.0: 817 | version "2.0.1" 818 | resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" 819 | dependencies: 820 | array-includes "^3.0.3" 821 | 822 | levn@^0.3.0, levn@~0.3.0: 823 | version "0.3.0" 824 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 825 | dependencies: 826 | prelude-ls "~1.1.2" 827 | type-check "~0.3.2" 828 | 829 | load-json-file@^2.0.0: 830 | version "2.0.0" 831 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" 832 | dependencies: 833 | graceful-fs "^4.1.2" 834 | parse-json "^2.2.0" 835 | pify "^2.0.0" 836 | strip-bom "^3.0.0" 837 | 838 | locate-path@^2.0.0: 839 | version "2.0.0" 840 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" 841 | dependencies: 842 | p-locate "^2.0.0" 843 | path-exists "^3.0.0" 844 | 845 | lodash.cond@^4.3.0: 846 | version "4.5.2" 847 | resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" 848 | 849 | lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: 850 | version "4.17.4" 851 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 852 | 853 | loose-envify@^1.0.0, loose-envify@^1.3.1: 854 | version "1.3.1" 855 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 856 | dependencies: 857 | js-tokens "^3.0.0" 858 | 859 | lru-cache@^4.0.1: 860 | version "4.1.1" 861 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" 862 | dependencies: 863 | pseudomap "^1.0.2" 864 | yallist "^2.1.2" 865 | 866 | mimic-fn@^1.0.0: 867 | version "1.1.0" 868 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" 869 | 870 | minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: 871 | version "3.0.4" 872 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 873 | dependencies: 874 | brace-expansion "^1.1.7" 875 | 876 | minimist@0.0.8: 877 | version "0.0.8" 878 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 879 | 880 | mkdirp@^0.5.1: 881 | version "0.5.1" 882 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 883 | dependencies: 884 | minimist "0.0.8" 885 | 886 | ms@2.0.0: 887 | version "2.0.0" 888 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 889 | 890 | mute-stream@0.0.7: 891 | version "0.0.7" 892 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" 893 | 894 | natural-compare@^1.4.0: 895 | version "1.4.0" 896 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 897 | 898 | node-fetch@^1.0.1: 899 | version "1.7.3" 900 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" 901 | dependencies: 902 | encoding "^0.1.11" 903 | is-stream "^1.0.1" 904 | 905 | normalize-package-data@^2.3.2: 906 | version "2.4.0" 907 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 908 | dependencies: 909 | hosted-git-info "^2.1.4" 910 | is-builtin-module "^1.0.0" 911 | semver "2 || 3 || 4 || 5" 912 | validate-npm-package-license "^3.0.1" 913 | 914 | object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: 915 | version "4.1.1" 916 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 917 | 918 | object-keys@^1.0.8: 919 | version "1.0.11" 920 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" 921 | 922 | once@^1.3.0: 923 | version "1.4.0" 924 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 925 | dependencies: 926 | wrappy "1" 927 | 928 | onetime@^2.0.0: 929 | version "2.0.1" 930 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" 931 | dependencies: 932 | mimic-fn "^1.0.0" 933 | 934 | optionator@^0.8.2: 935 | version "0.8.2" 936 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" 937 | dependencies: 938 | deep-is "~0.1.3" 939 | fast-levenshtein "~2.0.4" 940 | levn "~0.3.0" 941 | prelude-ls "~1.1.2" 942 | type-check "~0.3.2" 943 | wordwrap "~1.0.0" 944 | 945 | os-tmpdir@~1.0.2: 946 | version "1.0.2" 947 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 948 | 949 | p-limit@^1.1.0: 950 | version "1.1.0" 951 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" 952 | 953 | p-locate@^2.0.0: 954 | version "2.0.0" 955 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" 956 | dependencies: 957 | p-limit "^1.1.0" 958 | 959 | parse-json@^2.2.0: 960 | version "2.2.0" 961 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 962 | dependencies: 963 | error-ex "^1.2.0" 964 | 965 | path-exists@^2.0.0: 966 | version "2.1.0" 967 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 968 | dependencies: 969 | pinkie-promise "^2.0.0" 970 | 971 | path-exists@^3.0.0: 972 | version "3.0.0" 973 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 974 | 975 | path-is-absolute@^1.0.0: 976 | version "1.0.1" 977 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 978 | 979 | path-is-inside@^1.0.1, path-is-inside@^1.0.2: 980 | version "1.0.2" 981 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 982 | 983 | path-parse@^1.0.5: 984 | version "1.0.5" 985 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 986 | 987 | path-type@^2.0.0: 988 | version "2.0.0" 989 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" 990 | dependencies: 991 | pify "^2.0.0" 992 | 993 | pify@^2.0.0: 994 | version "2.3.0" 995 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 996 | 997 | pinkie-promise@^2.0.0: 998 | version "2.0.1" 999 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 1000 | dependencies: 1001 | pinkie "^2.0.0" 1002 | 1003 | pinkie@^2.0.0: 1004 | version "2.0.4" 1005 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 1006 | 1007 | pkg-dir@^1.0.0: 1008 | version "1.0.0" 1009 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" 1010 | dependencies: 1011 | find-up "^1.0.0" 1012 | 1013 | pluralize@^7.0.0: 1014 | version "7.0.0" 1015 | resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" 1016 | 1017 | prelude-ls@~1.1.2: 1018 | version "1.1.2" 1019 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 1020 | 1021 | process-nextick-args@~1.0.6: 1022 | version "1.0.7" 1023 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 1024 | 1025 | progress@^2.0.0: 1026 | version "2.0.0" 1027 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" 1028 | 1029 | promise@^7.1.1: 1030 | version "7.3.1" 1031 | resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" 1032 | dependencies: 1033 | asap "~2.0.3" 1034 | 1035 | prop-types@^15.5.10: 1036 | version "15.6.0" 1037 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" 1038 | dependencies: 1039 | fbjs "^0.8.16" 1040 | loose-envify "^1.3.1" 1041 | object-assign "^4.1.1" 1042 | 1043 | pseudomap@^1.0.2: 1044 | version "1.0.2" 1045 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 1046 | 1047 | read-pkg-up@^2.0.0: 1048 | version "2.0.0" 1049 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" 1050 | dependencies: 1051 | find-up "^2.0.0" 1052 | read-pkg "^2.0.0" 1053 | 1054 | read-pkg@^2.0.0: 1055 | version "2.0.0" 1056 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" 1057 | dependencies: 1058 | load-json-file "^2.0.0" 1059 | normalize-package-data "^2.3.2" 1060 | path-type "^2.0.0" 1061 | 1062 | readable-stream@^2.2.2: 1063 | version "2.3.3" 1064 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" 1065 | dependencies: 1066 | core-util-is "~1.0.0" 1067 | inherits "~2.0.3" 1068 | isarray "~1.0.0" 1069 | process-nextick-args "~1.0.6" 1070 | safe-buffer "~5.1.1" 1071 | string_decoder "~1.0.3" 1072 | util-deprecate "~1.0.1" 1073 | 1074 | require-uncached@^1.0.3: 1075 | version "1.0.3" 1076 | resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" 1077 | dependencies: 1078 | caller-path "^0.1.0" 1079 | resolve-from "^1.0.0" 1080 | 1081 | resolve-from@^1.0.0: 1082 | version "1.0.1" 1083 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" 1084 | 1085 | resolve@^1.2.0: 1086 | version "1.5.0" 1087 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" 1088 | dependencies: 1089 | path-parse "^1.0.5" 1090 | 1091 | restore-cursor@^2.0.0: 1092 | version "2.0.0" 1093 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" 1094 | dependencies: 1095 | onetime "^2.0.0" 1096 | signal-exit "^3.0.2" 1097 | 1098 | rimraf@^2.2.8: 1099 | version "2.6.2" 1100 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 1101 | dependencies: 1102 | glob "^7.0.5" 1103 | 1104 | run-async@^2.2.0: 1105 | version "2.3.0" 1106 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" 1107 | dependencies: 1108 | is-promise "^2.1.0" 1109 | 1110 | rx-lite-aggregates@^4.0.8: 1111 | version "4.0.8" 1112 | resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" 1113 | dependencies: 1114 | rx-lite "*" 1115 | 1116 | rx-lite@*, rx-lite@^4.0.8: 1117 | version "4.0.8" 1118 | resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" 1119 | 1120 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1121 | version "5.1.1" 1122 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 1123 | 1124 | "semver@2 || 3 || 4 || 5", semver@^5.3.0: 1125 | version "5.4.1" 1126 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" 1127 | 1128 | setimmediate@^1.0.5: 1129 | version "1.0.5" 1130 | resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" 1131 | 1132 | shebang-command@^1.2.0: 1133 | version "1.2.0" 1134 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 1135 | dependencies: 1136 | shebang-regex "^1.0.0" 1137 | 1138 | shebang-regex@^1.0.0: 1139 | version "1.0.0" 1140 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 1141 | 1142 | signal-exit@^3.0.2: 1143 | version "3.0.2" 1144 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 1145 | 1146 | slice-ansi@1.0.0: 1147 | version "1.0.0" 1148 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" 1149 | dependencies: 1150 | is-fullwidth-code-point "^2.0.0" 1151 | 1152 | spdx-correct@~1.0.0: 1153 | version "1.0.2" 1154 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" 1155 | dependencies: 1156 | spdx-license-ids "^1.0.2" 1157 | 1158 | spdx-expression-parse@~1.0.0: 1159 | version "1.0.4" 1160 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" 1161 | 1162 | spdx-license-ids@^1.0.2: 1163 | version "1.2.2" 1164 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" 1165 | 1166 | sprintf-js@~1.0.2: 1167 | version "1.0.3" 1168 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1169 | 1170 | string-width@^2.1.0, string-width@^2.1.1: 1171 | version "2.1.1" 1172 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 1173 | dependencies: 1174 | is-fullwidth-code-point "^2.0.0" 1175 | strip-ansi "^4.0.0" 1176 | 1177 | string_decoder@~1.0.3: 1178 | version "1.0.3" 1179 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" 1180 | dependencies: 1181 | safe-buffer "~5.1.0" 1182 | 1183 | strip-ansi@^3.0.0: 1184 | version "3.0.1" 1185 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1186 | dependencies: 1187 | ansi-regex "^2.0.0" 1188 | 1189 | strip-ansi@^4.0.0: 1190 | version "4.0.0" 1191 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 1192 | dependencies: 1193 | ansi-regex "^3.0.0" 1194 | 1195 | strip-bom@^3.0.0: 1196 | version "3.0.0" 1197 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1198 | 1199 | strip-json-comments@~2.0.1: 1200 | version "2.0.1" 1201 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1202 | 1203 | supports-color@^2.0.0: 1204 | version "2.0.0" 1205 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1206 | 1207 | supports-color@^4.0.0: 1208 | version "4.5.0" 1209 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" 1210 | dependencies: 1211 | has-flag "^2.0.0" 1212 | 1213 | table@^4.0.1: 1214 | version "4.0.2" 1215 | resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" 1216 | dependencies: 1217 | ajv "^5.2.3" 1218 | ajv-keywords "^2.1.0" 1219 | chalk "^2.1.0" 1220 | lodash "^4.17.4" 1221 | slice-ansi "1.0.0" 1222 | string-width "^2.1.1" 1223 | 1224 | text-table@~0.2.0: 1225 | version "0.2.0" 1226 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1227 | 1228 | through@^2.3.6: 1229 | version "2.3.8" 1230 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1231 | 1232 | tmp@^0.0.33: 1233 | version "0.0.33" 1234 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 1235 | dependencies: 1236 | os-tmpdir "~1.0.2" 1237 | 1238 | to-fast-properties@^2.0.0: 1239 | version "2.0.0" 1240 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1241 | 1242 | tryit@^1.0.1: 1243 | version "1.0.3" 1244 | resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" 1245 | 1246 | type-check@~0.3.2: 1247 | version "0.3.2" 1248 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 1249 | dependencies: 1250 | prelude-ls "~1.1.2" 1251 | 1252 | typedarray@^0.0.6: 1253 | version "0.0.6" 1254 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 1255 | 1256 | ua-parser-js@^0.7.9: 1257 | version "0.7.17" 1258 | resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" 1259 | 1260 | util-deprecate@~1.0.1: 1261 | version "1.0.2" 1262 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1263 | 1264 | validate-npm-package-license@^3.0.1: 1265 | version "3.0.1" 1266 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" 1267 | dependencies: 1268 | spdx-correct "~1.0.0" 1269 | spdx-expression-parse "~1.0.0" 1270 | 1271 | whatwg-fetch@>=0.10.0: 1272 | version "2.0.3" 1273 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" 1274 | 1275 | which@^1.2.9: 1276 | version "1.3.0" 1277 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 1278 | dependencies: 1279 | isexe "^2.0.0" 1280 | 1281 | wordwrap@~1.0.0: 1282 | version "1.0.0" 1283 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 1284 | 1285 | wrappy@1: 1286 | version "1.0.2" 1287 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1288 | 1289 | write@^0.2.1: 1290 | version "0.2.1" 1291 | resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" 1292 | dependencies: 1293 | mkdirp "^0.5.1" 1294 | 1295 | yallist@^2.1.2: 1296 | version "2.1.2" 1297 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 1298 | --------------------------------------------------------------------------------