diff --git a/README.md b/README.md index 9e098956f..cd482cb7a 100644 --- a/README.md +++ b/README.md @@ -223,21 +223,41 @@ Will call the specified method when a barcode is detected in the camera's view. Event contains `data` (the data in the barcode) and `bounds` (the rectangle which outlines the barcode.) -The following barcode types can be recognised: +The following barcode types can be recognised for iOS: - `aztec` -- `code128` - `code39` - `code39mod43` - `code93` -- `ean13` +- `code128` +- `datamatrix` (when available) - `ean8` +- `ean13` +- `interleaved2of5` (when available) +- `itf14` (when available) - `pdf417` - `qr` - `upce` -- `interleaved2of5` (when available) -- `itf14` (when available) -- `datamatrix` (when available) + +The following barcode types can be recognised for Android: + +- `aztec` +- `codabar` +- `code39` +- `code93` +- `code128` +- `datamatrix` +- `ean8` +- `ean13` +- `itf14` +- `maxicode` +- `qr` +- `pdf417` +- `rss` +- `rss14` +- `upca` +- `upce` +- `upc` The barcode type is provided in the `data` object. @@ -245,6 +265,19 @@ The barcode type is provided in the `data` object. An array of barcode types to search for. Defaults to all types listed above. No effect if `onBarCodeRead` is undefined. +Use static const `Camera.constants.BarCodeType` for selecting scan types in `barCodeTypes` and to very the results in `onBarCodeRead`. + +#### `barcodeFinderVisible` + +Displays an rectangle over the camera to show the area of barcode scanning. If this is used the actual area that is scanned in cropped to the rectangle. This can significantly increase the performance. + +Adjust size and style: +`barcodeFinderWidth`, +`barcodeFinderHeight`, +`barcodeFinderBorderColor`, +`barcodeFinderBorderWidth` + + #### `flashMode` Values: diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java index e433f9d5d..4f5b7c093 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java @@ -22,6 +22,9 @@ public class RCTCamera { private static final Resolution RESOLUTION_720P = new Resolution(1280, 720); private static final Resolution RESOLUTION_1080P = new Resolution(1920, 1080); private boolean _barcodeScannerEnabled = false; + private boolean _barcodeFinderVisible = false; + private float _barcodeFinderWidth = 0; + private float _barcodeFinderHeight = 0; private List _barCodeTypes = null; private int _orientation = -1; private int _actualDeviceOrientation = 0; @@ -168,6 +171,30 @@ public void setBarcodeScannerEnabled(boolean barcodeScannerEnabled) { _barcodeScannerEnabled = barcodeScannerEnabled; } + public void setBarcodeFinderVisible(boolean barcodeFinderVisible) { + _barcodeFinderVisible = barcodeFinderVisible; + } + + public boolean barcodeFinderVisible() { + return _barcodeFinderVisible; + } + + public void setBarcodeFinderWidth(float barcodeFinderWidth) { + _barcodeFinderWidth = barcodeFinderWidth; + } + + public float barcodeFinderWidth() { + return _barcodeFinderWidth; + } + + public void setBarcodeFinderHeight(float barcodeFinderHeight) { + _barcodeFinderHeight = barcodeFinderHeight; + } + + public float barcodeFinderHeight() { + return _barcodeFinderHeight; + } + public List getBarCodeTypes() { return _barCodeTypes; } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java index 10b59f9c5..8cd93d390 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java @@ -165,7 +165,23 @@ private Map getAspectConstants() { private Map getBarCodeConstants() { return Collections.unmodifiableMap(new HashMap() { { - // @TODO add barcode types + put("aztec", "AZTEC"); + put("codabar", "CODABAR"); + put("code128", "CODE_128"); + put("code93", "CODE_93"); + put("code39", "CODE_39"); + put("datamatrix", "DATA_MATRIX"); + put("ean13", "EAN_13"); + put("ean8", "EAN_8"); + put("itf14", "ITF"); + put("maxicode", "MAXICODE"); + put("pdf417", "PDF_417"); + put("qr", "QR_CODE"); + put("rss14", "RSS_14"); + put("rss", "RSS_EXPANDED"); + put("upca", "UPC_A"); + put("upce", "UPC_E"); + put("upc", "UPC_EAN_EXTENSION"); } }); } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java index f9fe98ede..a05c3bd2b 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java @@ -119,6 +119,18 @@ public void setBarcodeScannerEnabled(boolean barcodeScannerEnabled) { RCTCamera.getInstance().setBarcodeScannerEnabled(barcodeScannerEnabled); } + public void setBarcodeFinderVisible(boolean barcodeFinderVisible) { + RCTCamera.getInstance().setBarcodeFinderVisible(barcodeFinderVisible); + } + + public void setBarcodeFinderWidth(float barcodeFinderWidth) { + RCTCamera.getInstance().setBarcodeFinderWidth(barcodeFinderWidth); + } + + public void setBarcodeFinderHeight(float barcodeFinderHeight) { + RCTCamera.getInstance().setBarcodeFinderHeight(barcodeFinderHeight); + } + public void setBarCodeTypes(List types) { RCTCamera.getInstance().setBarCodeTypes(types); } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java index e308474d3..415533330 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java @@ -49,6 +49,15 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText // reader instance for the barcode scanner private final MultiFormatReader _multiFormatReader = new MultiFormatReader(); + private static Camera.Parameters getCameraParameters(Camera camera) { + try { + return camera != null ? camera.getParameters() : null; + } catch (RuntimeException e) { + // The camera has been released + return null; + } + } + public RCTCameraViewFinder(Context context, int type) { super(context); this.setSurfaceTextureListener(this); @@ -137,7 +146,7 @@ synchronized private void startCamera() { _isStarting = true; try { _camera = RCTCamera.getInstance().acquireCameraInstance(_cameraType); - Camera.Parameters parameters = _camera.getParameters(); + Camera.Parameters parameters = getCameraParameters(_camera); final boolean isCaptureModeStill = (_captureMode == RCTCameraModule.RCT_CAMERA_CAPTURE_MODE_STILL); final boolean isCaptureModeVideo = (_captureMode == RCTCameraModule.RCT_CAMERA_CAPTURE_MODE_VIDEO); @@ -306,26 +315,44 @@ protected Void doInBackground(Void... ignored) { return null; } - Camera.Size size = camera.getParameters().getPreviewSize(); + Camera.Parameters parameters = getCameraParameters(camera); + if (parameters == null) { + // The camera was released after onPreviewFrame() was called + // but before this async task actually ran + return null; + } + + Camera.Size size = parameters.getPreviewSize(); + int x = 0; + int y = 0; int width = size.width; int height = size.height; - // rotate for zxing if orientation is portrait - if (RCTCamera.getInstance().getActualDeviceOrientation() == 0) { - byte[] rotated = new byte[imageData.length]; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - rotated[x * height + height - y - 1] = imageData[x + y * width]; + try { + // If using a barcode finder, limit the search area + if ( RCTCamera.getInstance().barcodeFinderVisible() ){ + x = (width/2) - ((int)RCTCamera.getInstance().barcodeFinderWidth()/2); + y = (height/2) - ((int)RCTCamera.getInstance().barcodeFinderHeight()/2); + width = (int)RCTCamera.getInstance().barcodeFinderWidth(); + height = (int)RCTCamera.getInstance().barcodeFinderHeight(); + } + + // rotate for zxing if orientation is portrait + if (RCTCamera.getInstance().getActualDeviceOrientation() == 0) { + byte[] rotated = new byte[imageData.length]; + for (int ypos = y; ypos < height; ypos++) { + for (int xpos = x; xpos < width; xpos++) { + rotated[xpos * height + height - ypos - 1] = imageData[xpos + ypos * width]; + } } + int tmp = width; + width = height; + height = tmp; + imageData = rotated; } - width = size.height; - height = size.width; - imageData = rotated; - } - try { - PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(imageData, width, height, 0, 0, width, height, false); + PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(imageData, width, height, x, y, width, height, false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result = _multiFormatReader.decodeWithState(bitmap); @@ -359,26 +386,32 @@ protected Void doInBackground(Void... ignored) { @Override public boolean onTouchEvent(MotionEvent event) { - // Get the pointer ID - Camera.Parameters params = _camera.getParameters(); - int action = event.getAction(); - - - if (event.getPointerCount() > 1) { - // handle multi-touch events - if (action == MotionEvent.ACTION_POINTER_DOWN) { - mFingerSpacing = getFingerSpacing(event); - } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { - _camera.cancelAutoFocus(); - handleZoom(event, params); - } - } else { - // handle single touch events - if (action == MotionEvent.ACTION_UP) { - handleFocus(event, params); - } - } - return true; + // Get the pointer ID + if (_camera == null) { + return false; + } + + Camera.Parameters params = getCameraParameters(_camera); + if (params != null) { + // Get the pointer ID + int action = event.getAction(); + + if (event.getPointerCount() > 1) { + // handle multi-touch events + if (action == MotionEvent.ACTION_POINTER_DOWN) { + mFingerSpacing = getFingerSpacing(event); + } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { + _camera.cancelAutoFocus(); + handleZoom(event, params); + } + } else { + // handle single touch events + if (action == MotionEvent.ACTION_UP) { + handleFocus(event, params); + } + } + } + return true; } private void handleZoom(MotionEvent event, Camera.Parameters params) { diff --git a/barcode-finder.js b/barcode-finder.js new file mode 100644 index 000000000..eb78ff565 --- /dev/null +++ b/barcode-finder.js @@ -0,0 +1,116 @@ +import React, { + Component +} from 'react'; +import PropTypes from 'prop-types'; +import { + Platform, + StyleSheet, + View, +} from 'react-native'; + +class BarcodeFinder extends Component { + constructor(props) { + super(props); + } + + getSizeStyles() { + return ({ + width: this.props.width, + height: this.props.height + }); + } + + render() { + return ( + + + + + + + + + ); + } +}; + +BarcodeFinder.propTypes = { + borderWidth: PropTypes.number, + borderColor: PropTypes.string, + width: PropTypes.number, + height: PropTypes.number +}; + +var styles = StyleSheet.create({ + container: { + alignItems: 'center', + justifyContent: 'center', + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + finder: { + alignItems: 'center', + justifyContent: 'center', + }, + topLeftEdge: { + position: 'absolute', + top: 0, + left: 0, + width: 40, + height: 20, + }, + topRightEdge: { + position: 'absolute', + top: 0, + right: 0, + width: 40, + height: 20, + }, + bottomLeftEdge: { + position: 'absolute', + bottom: 0, + left: 0, + width: 40, + height: 20, + }, + bottomRightEdge: { + position: 'absolute', + bottom: 0, + right: 0, + width: 40, + height: 20, + }, +}); + +module.exports = BarcodeFinder; diff --git a/index.js b/index.js index f1957e9e1..d6b785c44 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ import { View, ViewPropTypes } from 'react-native'; +import BarcodeFinder from './barcode-finder'; const CameraManager = NativeModules.CameraManager || NativeModules.CameraModule; const CAMERA_REF = 'camera'; @@ -116,7 +117,12 @@ export default class Camera extends Component { type: PropTypes.oneOfType([ PropTypes.string, PropTypes.number - ]) + ]), + barcodeFinderVisible: PropTypes.bool, + barcodeFinderWidth: PropTypes.number, + barcodeFinderHeight: PropTypes.number, + barcodeFinderBorderColor: PropTypes.string, + barcodeFinderBorderWidth: PropTypes.number }; static defaultProps = { @@ -134,6 +140,11 @@ export default class Camera extends Component { torchMode: CameraManager.TorchMode.off, mirrorImage: false, barCodeTypes: Object.values(CameraManager.BarCodeType), + barcodeFinderVisible: false, + barcodeFinderWidth: 200, + barcodeFinderHeight: 200, + barcodeFinderBorderColor: "rgba(255,255,255,0.6)", + barcodeFinderBorderWidth: 1, }; static checkDeviceAuthorizationStatus = CameraManager.checkDeviceAuthorizationStatus; @@ -201,7 +212,14 @@ export default class Camera extends Component { const style = [styles.base, this.props.style]; const nativeProps = convertNativeProps(this.props); - return ; + return ( + {this.props.barcodeFinderVisible && } + ); } _onBarCodeRead = (data) => { diff --git a/ios/RCTCameraManager.h b/ios/RCTCameraManager.h index bf32d23e4..75d4dadcd 100644 --- a/ios/RCTCameraManager.h +++ b/ios/RCTCameraManager.h @@ -71,6 +71,9 @@ typedef NS_ENUM(NSInteger, RCTCameraTorchMode) { @property (nonatomic, assign) NSInteger videoTarget; @property (nonatomic, assign) NSInteger orientation; @property (nonatomic, assign) BOOL mirrorImage; +@property (nonatomic, assign) BOOL barcodeFinderVisible; +@property (nonatomic, assign) float barcodeFinderWidth; +@property (nonatomic, assign) float barcodeFinderHeight; @property (nonatomic, strong) NSArray* barCodeTypes; @property (nonatomic, strong) RCTPromiseResolveBlock videoResolve; @property (nonatomic, strong) RCTPromiseRejectBlock videoReject; diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 231008055..3dd53d7d0 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -293,6 +293,18 @@ - (void)setFlashMode { self.barCodeTypes = [RCTConvert NSArray:json]; } +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderVisible, BOOL, RCTCamera) { + self.barcodeFinderVisible = [RCTConvert BOOL:json]; +} + +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderWidth, float, RCTCamera) { + self.barcodeFinderWidth = [RCTConvert float:json]; +} + +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderHeight, float, RCTCamera) { + self.barcodeFinderHeight = [RCTConvert float:json]; +} + RCT_CUSTOM_VIEW_PROPERTY(captureAudio, BOOL, RCTCamera) { BOOL captureAudio = [RCTConvert BOOL:json]; if (captureAudio) { @@ -312,6 +324,7 @@ - (NSArray *)customDirectEventTypes - (id)init { if ((self = [super init])) { self.mirrorImage = false; + self.barcodeFinderVisible = false; self.sessionQueue = dispatch_queue_create("cameraManagerQueue", DISPATCH_QUEUE_SERIAL); @@ -447,6 +460,13 @@ - (void)startSession { [self.session addOutput:metadataOutput]; [metadataOutput setMetadataObjectTypes:self.barCodeTypes]; self.metadataOutput = metadataOutput; + if (self.barcodeFinderVisible) { + double cameraViewWidth = [[UIScreen mainScreen] bounds].size.height; + double cameraViewHeight = [[UIScreen mainScreen] bounds].size.width; + CGRect scanLimit = CGRectMake((cameraViewHeight/2)-(self.barcodeFinderHeight/2),(cameraViewWidth/2)-(self.barcodeFinderWidth/2), self.barcodeFinderHeight, self.barcodeFinderWidth); + [self.previewLayer metadataOutputRectOfInterestForRect: scanLimit]; + } + } __weak RCTCameraManager *weakSelf = self; diff --git a/package-lock.json b/package-lock.json index 3776169d5..1b832b4a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,46 +2,12 @@ "name": "react-native-camera", "version": "0.10.0", "lockfileVersion": 1, + "requires": true, "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=" - }, - "babel-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=" - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=" - }, - "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "core-js": { "version": "2.4.1", @@ -51,167 +17,102 @@ "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=" + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.18" + } + }, + "fbjs": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.14.tgz", + "integrity": "sha1-0dviviVMNakeCfMfnNUKQLKg7Rw=", + "requires": { + "core-js": "2.4.1", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.14" + } }, "iconv-lite": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" }, - "inquirer": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", - "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "jschardet": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.4.2.tgz", - "integrity": "sha1-KqEH8UKvQSHRRWWdRPUIMJYeaZo=" - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.6.3", + "whatwg-fetch": "2.0.3" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } }, "node-fetch": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", - "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=" + "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=" - }, - "opencollective": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", - "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=" - }, - "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=" - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=" - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=" - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "string-width": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=" + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.5.10", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", + "integrity": "sha1-J5ffwxJhguOpXj37suiT3ddFYVQ=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "ua-parser-js": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", + "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=" + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" } } }