[
  {
    "path": ".gitattributes",
    "content": "*.pbxproj -text\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.idea\n.DS_Store\ndist/\nbuild/\n/android/react-native-image-crop-tools.iml\n/android/.gradle\ncontents.xcworkspacedata\nxcuserdata\n.vscode\n"
  },
  {
    "path": ".npmignore",
    "content": "src/\nExample/\npreviews/\nREADME.md\ntsconfig.json\ntslint.json\nnode_modules\n.prettierrc\n.watchmanconfig\n.idea\n/android/build/\n/android/.gradle\n.vscode\nREADME.md"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"printWidth\": 120,\n  \"trailingComma\": \"es5\",\n  \"singleQuote\": true\n}"
  },
  {
    "path": ".watchmanconfig",
    "content": "{\n  \"ignore_dirs\": [\n    \"node_modules\"\n  ]\n}\n"
  },
  {
    "path": "README.md",
    "content": "# react-native-image-crop-tools\n\n## Previews\n<p float=\"left\">\n  <img src=\"https://github.com/hhunaid/react-native-image-crop-tools/blob/master/previews/android-preview.gif?raw=true\" width=\"150\" />\n  <img src=\"https://github.com/hhunaid/react-native-image-crop-tools/blob/master/previews/ios-preview.gif?raw=true\" width=\"150\" /> \n</p>\n\n## Getting started\n\n`$ yarn add react-native-image-crop-tools`\n\n### Automatic installation\n\nOnly RN > 0.61.x is supported.\n- Android: Installation is automatic.\n- iOS: Run `pod install`in `ios` folder.\n   \n### Why another cropping library?\n\nMost cropping tools available for RN are usually wrappers over popular native tools which itself isn't a bad thing. But this means you are stuck with their UI and feature set. The ones made in RN are not the most optimized and correct tools.\n\n## Features\n\n1. Native views. Which means performance even on low end devices.\n2. You can embed the view into you own UI. It's not very customizable (yet)\n3. Change and lock/unlock aspect ratio on the fly (This is the main reason I am making this library)\n\n# NOTE\n\nThis library is not supposed to work directly with remote images. There are very few usecases for that. You need to provide a sourceUrl string for a local file which you can obtain from image pickers or by downloading a remote file with rn-fetch-blob\n\n## Usage\n```javascript\nimport { CropView } from 'react-native-image-crop-tools';\n\n        <CropView\n          sourceUrl={uri}\n          style={styles.cropView}\n          ref={cropViewRef}\n          onImageCrop={(res) => console.warn(res)}\n          keepAspectRatio\n          aspectRatio={{width: 16, height: 9}}\n        />\n```\n\nTwo methods are exposed on the ref you can use them as follows\n\n```javascript\n  this.cropViewRef.saveImage(true, 90 // image quality percentage)\n  this.cropViewRef.rotateImage(true // true for clockwise, false for counterclockwise)\n```\n\n### Props\n\n| Name | Description | Default |\n| ---- | ----------- | ------- |\n| sourceUrl | URL of the source image | `null` |\n| aspectRatio | Aspect ratio of the cropped image | `null` |\n| keepAspectRatio | Locks the aspect ratio to given aspect ratio | `false` |\n| iosDimensionSwapEnabled | (iOS Only) Swaps the width and height of the crop rectangle upon rotation | `false` |\n\n#### TODO:\n\n- [x] Add screenshots\n- [x] Support transparency\n- [ ] Add access to prebuilt UI for those who want to use it.\n"
  },
  {
    "path": "android/README.md",
    "content": "README\n======\n\nIf you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm:\n\n1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed\n2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK\n```\nndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle\nsdk.dir=/Users/{username}/Library/Android/sdk\n```\n3. Delete the `maven` folder\n4. Run `./gradlew installArchives`\n5. Verify that latest set of generated files is in the maven folder with the correct version number\n"
  },
  {
    "path": "android/build.gradle",
    "content": "def safeExtGet(prop, fallback) {\n    rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback\n}\n\nbuildscript {\n    ext.kotlin_version = '1.7.20'\n    repositories {\n        google()\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:7.3.1'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n        flatDir {\n            dirs 'libs'\n        }\n    }\n}\n\napply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\n\nandroid {\n    compileSdkVersion safeExtGet('compileSdkVersion', 31)\n    defaultConfig {\n        minSdkVersion safeExtGet('minSdkVersion', 17)\n        targetSdkVersion safeExtGet('targetSdkVersion', 31)\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    api \"com.facebook.react:react-native:+\"\n    implementation 'com.github.CanHub:Android-Image-Cropper:4.1.0'\n    implementation\"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n}\n"
  },
  {
    "path": "android/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.parsempo.ImageCropTools\">\n\n</manifest>\n"
  },
  {
    "path": "android/src/main/java/com/parsempo/ImageCropTools/ImageCropToolsModule.kt",
    "content": "package com.parsempo.ImageCropTools\n\nimport com.facebook.react.bridge.ReactApplicationContext\nimport com.facebook.react.bridge.ReactContextBaseJavaModule\n\nclass ImageCropToolsModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {\n    override fun getName(): String {\n        return \"ImageCropTools\"\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/parsempo/ImageCropTools/ImageCropToolsPackage.kt",
    "content": "package com.parsempo.ImageCropTools\n\nimport com.facebook.react.ReactPackage\nimport com.facebook.react.bridge.NativeModule\nimport com.facebook.react.bridge.ReactApplicationContext\nimport com.facebook.react.uimanager.ViewManager\n\nclass ImageCropToolsPackage : ReactPackage {\n    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {\n        return mutableListOf(ImageCropToolsModule(reactContext))\n    }\n\n    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {\n        return mutableListOf(ImageCropViewManager())\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/parsempo/ImageCropTools/ImageCropViewManager.kt",
    "content": "package com.parsempo.ImageCropTools\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport com.facebook.react.bridge.Arguments\nimport com.facebook.react.bridge.ReadableArray\nimport com.facebook.react.bridge.ReadableMap\nimport com.facebook.react.common.MapBuilder\nimport com.facebook.react.uimanager.SimpleViewManager\nimport com.facebook.react.uimanager.ThemedReactContext\nimport com.facebook.react.uimanager.annotations.ReactProp\nimport com.canhub.cropper.CropImageView\nimport com.facebook.react.uimanager.events.RCTEventEmitter\nimport java.io.File\nimport java.util.*\n\nclass ImageCropViewManager: SimpleViewManager<CropImageView>() {\n    companion object {\n        const val REACT_CLASS = \"CropView\"\n        const val ON_IMAGE_SAVED = \"onImageSaved\"\n        const val SOURCE_URL_PROP = \"sourceUrl\"\n        const val KEEP_ASPECT_RATIO_PROP = \"keepAspectRatio\"\n        const val ASPECT_RATIO_PROP = \"cropAspectRatio\"\n        const val SAVE_IMAGE_COMMAND = 1\n        const val ROTATE_IMAGE_COMMAND = 2\n        const val SAVE_IMAGE_COMMAND_NAME = \"saveImage\"\n        const val ROTATE_IMAGE_COMMAND_NAME = \"rotateImage\"\n    }\n\n    override fun createViewInstance(reactContext: ThemedReactContext): CropImageView {\n        val view =  CropImageView(reactContext)\n        view.setOnCropImageCompleteListener { _, result ->\n            if (result.isSuccessful) {\n                val map = Arguments.createMap()\n                map.putString(\"uri\", result.getUriFilePath(reactContext, true).toString())\n                map.putInt(\"x\", result.cropRect!!.left)\n                map.putInt(\"y\", result.cropRect!!.top)\n                map.putInt(\"width\", result.cropRect!!.width())\n                map.putInt(\"height\", result.cropRect!!.height())\n                reactContext.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(\n                        view.id,\n                        ON_IMAGE_SAVED,\n                        map\n                )\n            }\n        }\n        return view\n    }\n\n    override fun getName(): String {\n        return REACT_CLASS\n    }\n\n    override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {\n        return MapBuilder.of(\n                ON_IMAGE_SAVED,\n                MapBuilder.of(\"registrationName\", ON_IMAGE_SAVED)\n        )\n    }\n\n    override fun getCommandsMap(): MutableMap<String, Int> {\n        return MapBuilder.of(\n                SAVE_IMAGE_COMMAND_NAME, SAVE_IMAGE_COMMAND,\n                ROTATE_IMAGE_COMMAND_NAME, ROTATE_IMAGE_COMMAND\n        )\n    }\n\n    override fun receiveCommand(root: CropImageView, commandId: Int, args: ReadableArray?) {\n        when (commandId) {\n            SAVE_IMAGE_COMMAND -> {\n                val preserveTransparency = args?.getBoolean(0) ?: false\n                var extension = \"jpg\"\n                var format = Bitmap.CompressFormat.JPEG\n                if (preserveTransparency && root.croppedImage!!.hasAlpha()) {\n                    extension = \"png\"\n                    format = Bitmap.CompressFormat.PNG\n                }\n                val path = File(root.context.cacheDir, \"${UUID.randomUUID()}.$extension\").toURI().toString()\n                val quality = args?.getInt(1) ?: 100\n\n                root.croppedImageAsync(format, quality, customOutputUri = Uri.parse(path))\n            }\n            ROTATE_IMAGE_COMMAND -> {\n                val clockwise = args?.getBoolean(0) ?: true\n                root.rotateImage(if (clockwise) 90 else -90)\n            }\n        }\n    }\n\n    @ReactProp(name = SOURCE_URL_PROP)\n    fun setSourceUrl(view: CropImageView, url: String?) {\n        url?.let {\n            view.setImageUriAsync(Uri.parse(it))\n        }\n    }\n\n    @ReactProp(name = KEEP_ASPECT_RATIO_PROP)\n    fun setFixedAspectRatio(view: CropImageView, fixed: Boolean) {\n        view.setFixedAspectRatio(fixed)\n    }\n\n    @ReactProp(name = ASPECT_RATIO_PROP)\n    fun setAspectRatio(view: CropImageView, aspectRatio: ReadableMap?) {\n        if (aspectRatio != null) {\n            view.setAspectRatio(aspectRatio.getInt(\"width\"), aspectRatio.getInt(\"height\"))\n        }else {\n            view.clearAspectRatio()\n        }\n    }\n}\n"
  },
  {
    "path": "ios/CropViewManager.h",
    "content": "//\n//  Header.h\n//  react-native-image-crop-tools\n//\n//  Created by Hunaid Hassan on 06/01/2020.\n//\n\n#import <React/RCTViewManager.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CropViewManager : RCTViewManager\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "ios/CropViewManager.m",
    "content": "//\n//  CropViewManager.m\n//  react-native-image-crop-tools\n//\n//  Created by Hunaid Hassan on 31/12/2019.\n//\n\n#import \"CropViewManager.h\"\n#import \"RCTCropView.h\"\n#import <React/RCTUIManager.h>\n\n@implementation CropViewManager\n\nRCT_EXPORT_MODULE()\n\n-(UIView *)view {\n    return [[RCTCropView alloc] init];\n}\n\nRCT_EXPORT_VIEW_PROPERTY(sourceUrl, NSString)\nRCT_EXPORT_VIEW_PROPERTY(onImageSaved, RCTDirectEventBlock)\nRCT_EXPORT_VIEW_PROPERTY(keepAspectRatio, BOOL)\nRCT_EXPORT_VIEW_PROPERTY(cropAspectRatio, CGSize)\nRCT_EXPORT_VIEW_PROPERTY(iosDimensionSwapEnabled, BOOL)\n\n\nRCT_EXPORT_METHOD(saveImage:(nonnull NSNumber*) reactTag\n                  preserveTransparency:(BOOL) preserveTransparency\n                  quality:(nonnull NSNumber *) quality) {\n    [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {\n        RCTCropView *cropView = (RCTCropView *)viewRegistry[reactTag];\n        CGRect cropFrame = [cropView getCropFrame];\n        UIImage *image = [cropView getCroppedImage];\n\n        NSString *extension = @\"jpg\";\n        if ([[image valueForKey:@\"hasAlpha\"] boolValue] && preserveTransparency) {\n            extension = @\"png\";\n        }\n\n        NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];\n        NSURL *url = [[paths firstObject] URLByAppendingPathComponent:[NSString stringWithFormat:@\"%@.%@\", [[NSUUID UUID] UUIDString], extension]];\n\n        if ([[image valueForKey:@\"hasAlpha\"] boolValue] && preserveTransparency) {\n            [UIImagePNGRepresentation(image) writeToURL:url atomically:YES];\n        }else {\n            [UIImageJPEGRepresentation(image, [quality floatValue] / 100.0f) writeToURL:url atomically:YES];\n        }\n\n        cropView.onImageSaved(@{\n            @\"uri\": url.absoluteString,\n            @\"width\": [NSNumber numberWithDouble:cropFrame.size.width],\n            @\"height\": [NSNumber numberWithDouble:cropFrame.size.height],\n            @\"x\": [NSNumber numberWithDouble:cropFrame.origin.x],\n            @\"y\": [NSNumber numberWithDouble:cropFrame.origin.y]\n        });\n    }];\n}\n\nRCT_EXPORT_METHOD(rotateImage:(nonnull NSNumber*) reactTag clockwise:(BOOL) clockwise) {\n    [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {\n        RCTCropView *cropView = (RCTCropView *)viewRegistry[reactTag];\n        [cropView rotateImage:clockwise];\n    }];\n}\n\n@end\n"
  },
  {
    "path": "ios/RCTCropView.h",
    "content": "//\n//  RCTCropView.h\n//  react-native-image-crop-tools\n//\n//  Created by Hunaid Hassan on 06/01/2020.\n//\n\n#import <React/RCTView.h>\n#import <Photos/Photos.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RCTCropView : RCTView\n\n@property (nonatomic, strong) NSString * sourceUrl;\n@property (atomic, assign) BOOL keepAspectRatio;\n@property (atomic, assign) BOOL iosDimensionSwapEnabled;\n@property (nonatomic, assign) CGSize cropAspectRatio;\n@property (nonatomic, strong) RCTDirectEventBlock onImageSaved;\n\n- (UIImage *)getCroppedImage;\n- (CGRect)getCropFrame;\n- (void)rotateImage:(BOOL)clockwise;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "ios/RCTCropView.m",
    "content": "//\n//  RCTCropView.m\n//  react-native-image-crop-tools\n//\n//  Created by Hunaid Hassan on 06/01/2020.\n//\n\n#import \"RCTCropView.h\"\n#import <TOCropViewController/TOCropView.h>\n#import <TOCropViewController/UIImage+CropRotate.h>\n#import <Photos/Photos.h>\n\n\n@implementation RCTCropView {\n    TOCropView * _inlineCropView;\n}\n\n@synthesize sourceUrl, keepAspectRatio, cropAspectRatio, iosDimensionSwapEnabled;\n\n- (void)layoutSubviews {\n    if (_inlineCropView == nil) {\n        if([sourceUrl rangeOfString:@\"ph://\"].location == 0) {\n            NSString *url = [sourceUrl stringByReplacingOccurrencesOfString:@\"ph://\" withString:@\"\"];\n            PHImageRequestOptions * requestOptions = [[PHImageRequestOptions alloc] init];\n            requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;\n            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;\n            requestOptions.synchronous = YES;\n\n            PHAsset *photosAsset = [PHAsset fetchAssetsWithLocalIdentifiers:@[url] options: nil].lastObject;\n            PHImageManager *manager = [PHImageManager defaultManager];\n            __block UIImage *blockImage;\n            [manager requestImageForAsset:photosAsset\n                               targetSize:PHImageManagerMaximumSize\n                              contentMode:PHImageContentModeDefault\n                                  options:requestOptions\n                            resultHandler:^void(UIImage *image, NSDictionary *info) {\n                blockImage = image;\n            }];\n            _inlineCropView = [[TOCropView alloc] initWithImage:blockImage];\n        } else {\n            UIImage * image =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:sourceUrl]]];\n            _inlineCropView = [[TOCropView alloc] initWithImage:image];\n        }\n        _inlineCropView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;\n        _inlineCropView.frame = self.bounds;\n        if (self->keepAspectRatio) {\n            _inlineCropView.aspectRatioLockEnabled = keepAspectRatio;\n        }\n        if (self->iosDimensionSwapEnabled) {\n            _inlineCropView.aspectRatioLockDimensionSwapEnabled = iosDimensionSwapEnabled;\n        }\n        if (!CGSizeEqualToSize(self -> cropAspectRatio, CGSizeZero)) {\n            _inlineCropView.aspectRatio = self->cropAspectRatio;\n        }\n        [_inlineCropView moveCroppedContentToCenterAnimated:NO];\n        [_inlineCropView performInitialSetup];\n\n        [self addSubview:_inlineCropView];\n    }\n}\n\n- (UIImage *)getCroppedImage {\n    return [_inlineCropView.image croppedImageWithFrame:_inlineCropView.imageCropFrame angle:_inlineCropView.angle circularClip:NO];\n}\n\n- (CGRect)getCropFrame {\n    return _inlineCropView.imageCropFrame;\n}\n\n- (void)setCropAspectRatio:(CGSize)aspectRatio {\n    if (_inlineCropView) {\n        _inlineCropView.aspectRatio = aspectRatio;\n    }\n    self->cropAspectRatio = aspectRatio;\n}\n\n-(CGSize)cropAspectRatio {\n    return _inlineCropView.aspectRatio;\n}\n\n- (void)setKeepAspectRatio:(BOOL)keepAspectRatio {\n    if (_inlineCropView) {\n        _inlineCropView.aspectRatioLockEnabled = keepAspectRatio;\n    }\n    self->keepAspectRatio = keepAspectRatio;\n}\n\n- (BOOL)keepAspectRatio {\n    return _inlineCropView.aspectRatioLockEnabled;\n}\n\n- (void)setIosDimensionSwapEnabled:(BOOL)iosDimensionSwapEnabled {\n    if (_inlineCropView) {\n        _inlineCropView.aspectRatioLockDimensionSwapEnabled = iosDimensionSwapEnabled;\n    }\n    self->iosDimensionSwapEnabled = iosDimensionSwapEnabled;\n}\n\n- (BOOL)iosDimensionSwapEnabled {\n    return _inlineCropView.aspectRatioLockDimensionSwapEnabled;\n}\n\n- (void)rotateImage:(BOOL)clockwise {\n    [_inlineCropView rotateImageNinetyDegreesAnimated:YES clockwise:clockwise];\n}\n\n@end\n"
  },
  {
    "path": "ios/react-native-image-crop-tools.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 55;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t20E26B5827222734001DE3D2 /* CropViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 20E26B5527222734001DE3D2 /* CropViewManager.m */; };\n\t\t20E26B5927222734001DE3D2 /* RCTCropView.m in Sources */ = {isa = PBXBuildFile; fileRef = 20E26B5727222734001DE3D2 /* RCTCropView.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t20E26B46272226EF001DE3D2 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"include/$(PRODUCT_NAME)\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t20E26B48272226EF001DE3D2 /* libreact-native-image-crop-tools.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = \"libreact-native-image-crop-tools.a\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t20E26B5427222734001DE3D2 /* CropViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CropViewManager.h; sourceTree = \"<group>\"; };\n\t\t20E26B5527222734001DE3D2 /* CropViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CropViewManager.m; sourceTree = \"<group>\"; };\n\t\t20E26B5627222734001DE3D2 /* RCTCropView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTCropView.h; sourceTree = \"<group>\"; };\n\t\t20E26B5727222734001DE3D2 /* RCTCropView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCropView.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t20E26B45272226EF001DE3D2 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t20E26B3F272226EF001DE3D2 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t20E26B5427222734001DE3D2 /* CropViewManager.h */,\n\t\t\t\t20E26B5527222734001DE3D2 /* CropViewManager.m */,\n\t\t\t\t20E26B5627222734001DE3D2 /* RCTCropView.h */,\n\t\t\t\t20E26B5727222734001DE3D2 /* RCTCropView.m */,\n\t\t\t\t20E26B49272226EF001DE3D2 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t20E26B49272226EF001DE3D2 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t20E26B48272226EF001DE3D2 /* libreact-native-image-crop-tools.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t20E26B47272226EF001DE3D2 /* react-native-image-crop-tools */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 20E26B51272226EF001DE3D2 /* Build configuration list for PBXNativeTarget \"react-native-image-crop-tools\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t20E26B44272226EF001DE3D2 /* Sources */,\n\t\t\t\t20E26B45272226EF001DE3D2 /* Frameworks */,\n\t\t\t\t20E26B46272226EF001DE3D2 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"react-native-image-crop-tools\";\n\t\t\tproductName = \"react-native-image-crop-tools\";\n\t\t\tproductReference = 20E26B48272226EF001DE3D2 /* libreact-native-image-crop-tools.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t20E26B40272226EF001DE3D2 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = 1;\n\t\t\t\tLastUpgradeCheck = 1300;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t20E26B47272226EF001DE3D2 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 13.0;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 20E26B43272226EF001DE3D2 /* Build configuration list for PBXProject \"react-native-image-crop-tools\" */;\n\t\t\tcompatibilityVersion = \"Xcode 13.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 20E26B3F272226EF001DE3D2;\n\t\t\tproductRefGroup = 20E26B49272226EF001DE3D2 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t20E26B47272226EF001DE3D2 /* react-native-image-crop-tools */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t20E26B44272226EF001DE3D2 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t20E26B5927222734001DE3D2 /* RCTCropView.m in Sources */,\n\t\t\t\t20E26B5827222734001DE3D2 /* CropViewManager.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t20E26B4F272226EF001DE3D2 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t20E26B50272226EF001DE3D2 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t20E26B52272226EF001DE3D2 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_TEAM = 5NJK8TB2FJ;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t20E26B53272226EF001DE3D2 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_TEAM = 5NJK8TB2FJ;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t20E26B43272226EF001DE3D2 /* Build configuration list for PBXProject \"react-native-image-crop-tools\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t20E26B4F272226EF001DE3D2 /* Debug */,\n\t\t\t\t20E26B50272226EF001DE3D2 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t20E26B51272226EF001DE3D2 /* Build configuration list for PBXNativeTarget \"react-native-image-crop-tools\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t20E26B52272226EF001DE3D2 /* Debug */,\n\t\t\t\t20E26B53272226EF001DE3D2 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 20E26B40272226EF001DE3D2 /* Project object */;\n}\n"
  },
  {
    "path": "ios/react-native-image-crop-tools.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-native-image-crop-tools\",\n  \"title\": \"React Native Image Crop Tools\",\n  \"version\": \"1.8.0\",\n  \"description\": \"Native image crop tools with embeddable UI and on the fly aspect ratio switchin\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"build\": \"tsc\",\n    \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"src/**/*.tsx\\\" \\\"src/**/*.js\\\"\",\n    \"lint\": \"tslint -p tsconfig.json --fix\",\n    \"prepublishOnly\": \"npm run lint\",\n    \"preversion\": \"npm run lint\",\n    \"version\": \"npm run format && git add -A src\",\n    \"postversion\": \"git push && git push --tags\"\n  },\n  \"main\": \"dist/index.js\",\n  \"types\": \"dist/index.d.ts\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/hhunaid/react-native-image-crop-tools.git\",\n    \"baseUrl\": \"https://github.com/hhunaid/react-native-image-crop-tools\"\n  },\n  \"keywords\": [\n    \"react-native\",\n    \"crop\",\n    \"cropping\",\n    \"image\",\n    \"rotate\",\n    \"native\",\n    \"react\",\n    \"typescript\"\n  ],\n  \"author\": {\n    \"name\": \"Hunaid Hassan\",\n    \"email\": \"hhunaid@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"readmeFilename\": \"README.md\",\n  \"peerDependencies\": {\n    \"react\": \">=16.0.0\",\n    \"react-native\": \">=0.59.0-rc.0 <1.0.x\"\n  },\n  \"devDependencies\": {\n    \"react\": \"^16.9.0\",\n    \"react-native\": \"^0.61.0\",\n    \"tslint\": \"^5.17.0\",\n    \"tslint-config-prettier\": \"^1.18.0\",\n    \"tslint-react\": \"^4.0.0\",\n    \"typescript\": \"^3.7.2\",\n    \"prettier\": \"^1.19.1\",\n    \"@types/react-native\": \"^0.60.23\"\n  }\n}\n"
  },
  {
    "path": "react-native-image-crop-tools.podspec",
    "content": "require \"json\"\n\npackage = JSON.parse(File.read(File.join(__dir__, \"package.json\")))\n\nPod::Spec.new do |s|\n  s.name         = \"react-native-image-crop-tools\"\n  s.version      = package[\"version\"]\n  s.summary      = package[\"description\"]\n  s.description  = <<-DESC\n                  react-native-image-crop-tools\n                   DESC\n  s.homepage     = \"https://github.com/hhunaid/react-native-image-crop-tools\"\n  s.license      = \"MIT\"\n  s.authors      = { \"Hunaid Hassan\" => \"hhunaid@gmail.com\" }\n  s.platforms    = { :ios => \"9.0\" }\n  s.source       = { :git => \"https://github.com/hhunaid/react-native-image-crop-tools.git\", :tag => \"#{s.version}\" }\n\n  s.source_files = \"ios/**/*.{h,m}\"\n  s.requires_arc = true\n\n  s.dependency \"React-Core\"\n  s.dependency 'TOCropViewController', '2.5.3'\nend\n\n"
  },
  {
    "path": "src/crop-view.component.tsx",
    "content": "import React, { createRef } from 'react';\nimport {\n  findNodeHandle,\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  StyleProp,\n  UIManager,\n  ViewStyle,\n} from 'react-native';\n\nconst RCTCropView = requireNativeComponent('CropView');\n\ntype Response = {\n  uri: string;\n  width: number;\n  height: number;\n  x: number;\n  y: number;\n};\n\ntype Props = {\n  sourceUrl: string;\n  style?: StyleProp<ViewStyle>;\n  onImageCrop?: (res: Response) => void;\n  keepAspectRatio?: boolean;\n  aspectRatio?: { width: number; height: number };\n  iosDimensionSwapEnabled?: boolean;\n};\n\nclass CropView extends React.PureComponent<Props> {\n  public static defaultProps = {\n    keepAspectRatio: false,\n    iosDimensionSwapEnabled: false,\n  };\n\n  private viewRef = createRef<any>();\n\n  public saveImage = (preserveTransparency: boolean = true, quality: number = 90) => {\n    UIManager.dispatchViewManagerCommand(\n      findNodeHandle(this.viewRef.current!),\n      UIManager.getViewManagerConfig('CropView').Commands.saveImage,\n      [preserveTransparency, quality]\n    );\n  };\n\n  public rotateImage = (clockwise: boolean = true) => {\n    UIManager.dispatchViewManagerCommand(\n      findNodeHandle(this.viewRef.current!),\n      UIManager.getViewManagerConfig('CropView').Commands.rotateImage,\n      [clockwise]\n    );\n  };\n\n  public render() {\n    const { onImageCrop, aspectRatio, ...rest } = this.props;\n\n    return (\n      <RCTCropView\n        ref={this.viewRef}\n        cropAspectRatio={aspectRatio}\n        onImageSaved={(event: NativeSyntheticEvent<Response>) => {\n          onImageCrop!(event.nativeEvent);\n        }}\n        {...rest}\n      />\n    );\n  }\n}\n\nexport default CropView;\n"
  },
  {
    "path": "src/index.ts",
    "content": "import CropView from './crop-view.component';\n\nexport { CropView };\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"declaration\": true,\n    \"outDir\": \"./dist\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"jsx\": \"react\",\n    \"typeRoots\": [\n      \"./node_modules/@types\"\n    ],\n    \"lib\": [\"es6\"],\n    \"moduleResolution\": \"node\",\n    \"target\": \"esnext\"\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"files\": [\"src/index.ts\"],\n  \"exclude\": [\n    \"node_modules\",\n    \"**/__tests__/*\",\n    \"dist\"\n  ]\n}"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"extends\": [\n    \"tslint:recommended\",\n    \"tslint-config-prettier\"\n  ],\n  \"rules\": {\n    \"interface-over-type-literal\": false,\n    \"object-literal-sort-keys\": false,\n    \"variable-name\": {\n      \"options\": [\n        \"check-format\",\n        \"allow-leading-underscore\",\n        \"allow-pascal-case\"\n      ]\n    },\n    \"no-unused-variable\": true,\n    \"no-shadowed-variable\": false\n  }\n}\n"
  }
]