diff --git a/windows/RNFS.Net46/DiskUtil.cs b/windows/RNFS.Net46/DiskUtil.cs
new file mode 100644
index 00000000..612aa374
--- /dev/null
+++ b/windows/RNFS.Net46/DiskUtil.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RNFS
+{
+ public struct DiskStatus
+ {
+ public ulong free;
+ public ulong total;
+ }
+
+ public class DiskUtil
+ {
+ // Pinvoke for API function
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
+ out ulong lpFreeBytesAvailable,
+ out ulong lpTotalNumberOfBytes,
+ out ulong lpTotalNumberOfFreeBytes);
+
+ public static bool DriveFreeBytes(string folderName, out DiskStatus status)
+ {
+ if (string.IsNullOrEmpty(folderName))
+ {
+ throw new ArgumentNullException("folderName");
+ }
+
+ if (!folderName.EndsWith("\\"))
+ {
+ folderName += '\\';
+ }
+
+ ulong dummy;
+ if (GetDiskFreeSpaceEx(folderName, out status.free, out status.total, out dummy))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/windows/RNFS.Net46/Properties/AssemblyInfo.cs b/windows/RNFS.Net46/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..3efc649d
--- /dev/null
+++ b/windows/RNFS.Net46/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RNFS")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RNFS")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
+
+[assembly: InternalsVisibleTo("RNFS.Tests")]
\ No newline at end of file
diff --git a/windows/RNFS.Net46/Properties/RNFS.rd.xml b/windows/RNFS.Net46/Properties/RNFS.rd.xml
new file mode 100644
index 00000000..039c5da3
--- /dev/null
+++ b/windows/RNFS.Net46/Properties/RNFS.rd.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/windows/RNFS.Net46/RNFS.Net46.csproj b/windows/RNFS.Net46/RNFS.Net46.csproj
new file mode 100644
index 00000000..9292e437
--- /dev/null
+++ b/windows/RNFS.Net46/RNFS.Net46.csproj
@@ -0,0 +1,71 @@
+
+
+
+
+ Debug
+ x64
+ {746610D0-8693-11E7-A20D-BF83F7366778}
+ Library
+ Properties
+ RNFS
+ RNFS
+ v4.6
+ 512
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+
+ False
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+ $(SolutionDir)\packages\Syroot.Windows.IO.KnownFolders.1.2.1\lib\net452\Syroot.KnownFolders.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {22cbff9c-fe36-43e8-a246-266c7635e662}
+ ReactNative.Net46
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/windows/RNFS.Net46/RNFSManager.cs b/windows/RNFS.Net46/RNFSManager.cs
new file mode 100644
index 00000000..3fbb078e
--- /dev/null
+++ b/windows/RNFS.Net46/RNFSManager.cs
@@ -0,0 +1,612 @@
+using Newtonsoft.Json.Linq;
+using ReactNative.Bridge;
+using ReactNative.Modules.Core;
+using ReactNative.Modules.Network;
+using Syroot.Windows.IO;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+//using Windows.ApplicationModel;
+//using Windows.Storage;
+
+namespace RNFS
+{
+ class RNFSManager : ReactContextNativeModuleBase
+ {
+ private const int FileType = 0;
+ private const int DirectoryType = 1;
+
+ private static readonly IReadOnlyDictionary> s_hashAlgorithms =
+ new Dictionary>
+ {
+ { "md5", () => MD5.Create() },
+ { "sha1", () => SHA1.Create() },
+ { "sha256", () => SHA256.Create() },
+ { "sha384", () => SHA384.Create() },
+ { "sha512", () => SHA512.Create() },
+ };
+
+ private readonly TaskCancellationManager _tasks = new TaskCancellationManager();
+ private readonly HttpClient _httpClient = new HttpClient();
+
+ private RCTNativeAppEventEmitter _emitter;
+
+ public RNFSManager(ReactContext reactContext)
+ : base(reactContext)
+ {
+ }
+
+ public override string Name
+ {
+ get
+ {
+ return "RNFSManager";
+ }
+ }
+
+ internal RCTNativeAppEventEmitter Emitter
+ {
+ get
+ {
+ if (_emitter == null)
+ {
+ return Context.GetJavaScriptModule();
+ }
+
+ return _emitter;
+ }
+ set
+ {
+ _emitter = value;
+ }
+ }
+
+ [Obsolete]
+ public override IReadOnlyDictionary Constants
+ {
+ get
+ {
+ var constants = new Dictionary
+ {
+ { "RNFSMainBundlePath", AppDomain.CurrentDomain.BaseDirectory },
+ { "RNFSCachesDirectoryPath", KnownFolders.Downloads.Path },
+ { "RNFSRoamingDirectoryPath", KnownFolders.RoamingAppData.Path },
+ { "RNFSDocumentDirectoryPath", KnownFolders.Documents.Path },
+ { "RNFSTemporaryDirectoryPath", KnownFolders.InternetCache.Path },
+ { "RNFSPicturesDirectoryPath", KnownFolders.CameraRoll.Path },
+ { "RNFSFileTypeRegular", 0 },
+ { "RNFSFileTypeDirectory", 1 },
+ };
+
+ return constants;
+ }
+ }
+
+ [ReactMethod]
+ public async void writeFile(string filepath, string base64Content, JObject options, IPromise promise)
+ {
+ try
+ {
+ // TODO: open file on background thread?
+ using (var file = File.OpenWrite(filepath))
+ {
+ var data = Convert.FromBase64String(base64Content);
+ await file.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
+ }
+
+ promise.Resolve(null);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void appendFile(string filepath, string base64Content, IPromise promise)
+ {
+ try
+ {
+ // TODO: open file on background thread?
+ using (var file = File.Open(filepath, FileMode.Append))
+ {
+ var data = Convert.FromBase64String(base64Content);
+ await file.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
+ }
+
+ promise.Resolve(null);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void write(string filepath, string base64Content, int position, IPromise promise)
+ {
+ try
+ {
+ // TODO: open file on background thread?
+ using (var file = File.OpenWrite(filepath))
+ {
+ if (position >= 0)
+ {
+ file.Position = position;
+ }
+
+ var data = Convert.FromBase64String(base64Content);
+ await file.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
+ }
+
+ promise.Resolve(null);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public void exists(string filepath, IPromise promise)
+ {
+ try
+ {
+ promise.Resolve(File.Exists(filepath) || Directory.Exists(filepath));
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void readFile(string filepath, IPromise promise)
+ {
+ try
+ {
+ if (!File.Exists(filepath))
+ {
+ RejectFileNotFound(promise, filepath);
+ return;
+ }
+
+ // TODO: open file on background thread?
+ string base64Content;
+ using (var file = File.OpenRead(filepath))
+ {
+ var length = (int)file.Length;
+ var buffer = new byte[length];
+ await file.ReadAsync(buffer, 0, length).ConfigureAwait(false);
+ base64Content = Convert.ToBase64String(buffer);
+ }
+
+ promise.Resolve(base64Content);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void read(string filepath, int length, int position, IPromise promise)
+ {
+ try
+ {
+ if (!File.Exists(filepath))
+ {
+ RejectFileNotFound(promise, filepath);
+ return;
+ }
+
+ // TODO: open file on background thread?
+ string base64Content;
+ using (var file = File.OpenRead(filepath))
+ {
+ file.Position = position;
+ var buffer = new byte[length];
+ await file.ReadAsync(buffer, 0, length).ConfigureAwait(false);
+ base64Content = Convert.ToBase64String(buffer);
+ }
+
+ promise.Resolve(base64Content);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void hash(string filepath, string algorithm, IPromise promise)
+ {
+ var hashAlgorithmFactory = default(Func);
+ if (!s_hashAlgorithms.TryGetValue(algorithm, out hashAlgorithmFactory))
+ {
+ promise.Reject(null, "Invalid hash algorithm.");
+ return;
+ }
+
+ try
+ {
+ if (!File.Exists(filepath))
+ {
+ RejectFileNotFound(promise, filepath);
+ return;
+ }
+
+ await Task.Run(() =>
+ {
+ var hexBuilder = new StringBuilder();
+ using (var hashAlgorithm = hashAlgorithmFactory())
+ {
+ hashAlgorithm.Initialize();
+ var hash = default(byte[]);
+ using (var file = File.OpenRead(filepath))
+ {
+ hash = hashAlgorithm.ComputeHash(file);
+ }
+
+ foreach (var b in hash)
+ {
+ hexBuilder.Append(string.Format("{0:x2}", b));
+ }
+ }
+
+ promise.Resolve(hexBuilder.ToString());
+ }).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public void moveFile(string filepath, string destPath, JObject options, IPromise promise)
+ {
+ try
+ {
+ // TODO: move file on background thread?
+ File.Move(filepath, destPath);
+ promise.Resolve(true);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void copyFile(string filepath, string destPath, JObject options, IPromise promise)
+ {
+ try
+ {
+ await Task.Run(() => File.Copy(filepath, destPath)).ConfigureAwait(false);
+ promise.Resolve(null);
+
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void readDir(string directory, IPromise promise)
+ {
+ try
+ {
+ await Task.Run(() =>
+ {
+ var info = new DirectoryInfo(directory);
+ if (!info.Exists)
+ {
+ promise.Reject(null, "Folder does not exist");
+ return;
+ }
+
+ var fileMaps = new JArray();
+ foreach (var item in info.EnumerateFileSystemInfos())
+ {
+ var fileMap = new JObject
+ {
+ { "mtime", ConvertToUnixTimestamp(item.LastWriteTime) },
+ { "name", item.Name },
+ { "path", item.FullName },
+ };
+
+ var fileItem = item as FileInfo;
+ if (fileItem != null)
+ {
+ fileMap.Add("type", FileType);
+ fileMap.Add("size", fileItem.Length);
+ }
+ else
+ {
+ fileMap.Add("type", DirectoryType);
+ fileMap.Add("size", 0);
+ }
+
+ fileMaps.Add(fileMap);
+ }
+
+ promise.Resolve(fileMaps);
+ });
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, directory, ex);
+ }
+ }
+
+ [ReactMethod]
+ public void stat(string filepath, IPromise promise)
+ {
+ try
+ {
+ FileSystemInfo fileSystemInfo = new FileInfo(filepath);
+ if (!fileSystemInfo.Exists)
+ {
+ fileSystemInfo = new DirectoryInfo(filepath);
+ if (!fileSystemInfo.Exists)
+ {
+ promise.Reject(null, "File does not exist.");
+ return;
+ }
+ }
+
+ var fileInfo = fileSystemInfo as FileInfo;
+ var statMap = new JObject
+ {
+ { "ctime", ConvertToUnixTimestamp(fileSystemInfo.CreationTime) },
+ { "mtime", ConvertToUnixTimestamp(fileSystemInfo.LastWriteTime) },
+ { "size", fileInfo?.Length ?? 0 },
+ { "type", fileInfo != null ? FileType: DirectoryType },
+ };
+
+ promise.Resolve(statMap);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void unlink(string filepath, IPromise promise)
+ {
+ try
+ {
+ var directoryInfo = new DirectoryInfo(filepath);
+ var fileInfo = default(FileInfo);
+ if (directoryInfo.Exists)
+ {
+ await Task.Run(() => Directory.Delete(filepath, true)).ConfigureAwait(false);
+ }
+ else if ((fileInfo = new FileInfo(filepath)).Exists)
+ {
+ await Task.Run(() => File.Delete(filepath)).ConfigureAwait(false);
+ }
+ else
+ {
+ promise.Reject(null, "File does not exist.");
+ return;
+ }
+
+ promise.Resolve(null);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void mkdir(string filepath, JObject options, IPromise promise)
+ {
+ try
+ {
+ await Task.Run(() => Directory.CreateDirectory(filepath)).ConfigureAwait(false);
+ promise.Resolve(null);
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public async void downloadFile(JObject options, IPromise promise)
+ {
+ var filepath = options.Value("toFile");
+
+ try
+ {
+ var url = new Uri(options.Value("fromUrl"));
+ var jobId = options.Value("jobId");
+ var headers = (JObject)options["headers"];
+ var progressDivider = options.Value("progressDivider");
+
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
+ foreach (var header in headers)
+ {
+ request.Headers.Add(header.Key, header.Value.Value());
+ }
+
+ await _tasks.AddAndInvokeAsync(jobId, token =>
+ ProcessRequestAsync(promise, request, filepath, jobId, progressDivider, token));
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ [ReactMethod]
+ public void stopDownload(int jobId)
+ {
+ _tasks.Cancel(jobId);
+ }
+
+ [ReactMethod]
+ public async void getFSInfo(IPromise promise)
+ {
+ try
+ {
+ DiskStatus status = new DiskStatus();
+ DiskUtil.DriveFreeBytes(KnownFolders.RoamingAppData.Path, out status);
+ promise.Resolve(new JObject
+ {
+ { "freeSpace", status.free },
+ { "totalSpace", status.total },
+ });
+ }
+ catch (Exception)
+ {
+ promise.Reject(null, "getFSInfo is not available");
+ }
+ }
+
+ [ReactMethod]
+ public async void touch(string filepath, double mtime, double ctime, IPromise promise)
+ {
+ try
+ {
+ await Task.Run(() =>
+ {
+ var fileInfo = new FileInfo(filepath);
+ if (!fileInfo.Exists)
+ {
+ using (File.Create(filepath)) { }
+ }
+
+ fileInfo.CreationTimeUtc = ConvertFromUnixTimestamp(ctime);
+ fileInfo.LastWriteTimeUtc = ConvertFromUnixTimestamp(mtime);
+
+ promise.Resolve(fileInfo.FullName);
+ });
+ }
+ catch (Exception ex)
+ {
+ Reject(promise, filepath, ex);
+ }
+ }
+
+ public override void OnReactInstanceDispose()
+ {
+ _tasks.CancelAllTasks();
+ _httpClient.Dispose();
+ }
+
+ private async Task ProcessRequestAsync(IPromise promise, HttpRequestMessage request, string filepath, int jobId, int progressIncrement, CancellationToken token)
+ {
+ try
+ {
+ using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token))
+ {
+ var headersMap = new JObject();
+ foreach (var header in response.Headers)
+ {
+ headersMap.Add(header.Key, string.Join(",", header.Value));
+ }
+
+ var contentLength = response.Content.Headers.ContentLength;
+ SendEvent($"DownloadBegin-{jobId}", new JObject
+ {
+ { "jobId", jobId },
+ { "statusCode", (int)response.StatusCode },
+ { "contentLength", contentLength },
+ { "headers", headersMap },
+ });
+
+ // TODO: open file on background thread?
+ long totalRead = 0;
+ using (var fileStream = File.OpenWrite(filepath))
+ using (var stream = await response.Content.ReadAsStreamAsync())
+ {
+ var contentLengthForProgress = contentLength ?? -1;
+ var nextProgressIncrement = progressIncrement;
+ var buffer = new byte[8 * 1024];
+ var read = 0;
+ while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
+ {
+ token.ThrowIfCancellationRequested();
+
+ await fileStream.WriteAsync(buffer, 0, read);
+ if (contentLengthForProgress >= 0)
+ {
+ totalRead += read;
+ if (totalRead * 100 / contentLengthForProgress >= nextProgressIncrement ||
+ totalRead == contentLengthForProgress)
+ {
+ SendEvent("DownloadProgress-" + jobId, new JObject
+ {
+ { "jobId", jobId },
+ { "contentLength", contentLength },
+ { "bytesWritten", totalRead },
+ });
+
+ nextProgressIncrement += progressIncrement;
+ }
+ }
+ }
+ }
+
+ promise.Resolve(new JObject
+ {
+ { "jobId", jobId },
+ { "statusCode", (int)response.StatusCode },
+ { "bytesWritten", totalRead },
+ });
+ }
+ }
+ finally
+ {
+ request.Dispose();
+ }
+ }
+
+ private void Reject(IPromise promise, String filepath, Exception ex)
+ {
+ if (ex is FileNotFoundException) {
+ RejectFileNotFound(promise, filepath);
+ return;
+ }
+
+ promise.Reject(ex);
+ }
+
+ private void RejectFileNotFound(IPromise promise, String filepath)
+ {
+ promise.Reject("ENOENT", "ENOENT: no such file or directory, open '" + filepath + "'");
+ }
+
+ private void SendEvent(string eventName, JObject eventData)
+ {
+ Emitter.emit(eventName, eventData);
+ }
+
+ public static double ConvertToUnixTimestamp(DateTime date)
+ {
+ var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ var diff = date.ToUniversalTime() - origin;
+ return Math.Floor(diff.TotalSeconds);
+ }
+
+ public static DateTime ConvertFromUnixTimestamp(double timestamp)
+ {
+ var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ var diff = TimeSpan.FromSeconds(timestamp);
+ var dateTimeUtc = origin + diff;
+ return dateTimeUtc.ToLocalTime();
+ }
+ }
+}
diff --git a/windows/RNFS.Net46/RNFSPackage.cs b/windows/RNFS.Net46/RNFSPackage.cs
new file mode 100644
index 00000000..ecd67ccb
--- /dev/null
+++ b/windows/RNFS.Net46/RNFSPackage.cs
@@ -0,0 +1,53 @@
+using ReactNative.Bridge;
+using ReactNative.Modules.Core;
+using ReactNative.UIManager;
+using System;
+using System.Collections.Generic;
+
+namespace RNFS
+{
+ ///
+ /// Package defining core framework modules (e.g., ).
+ /// It should be used for modules that require special integration with
+ /// other framework parts (e.g., with the list of packages to load view
+ /// managers from).
+ ///
+ public class RNFSPackage : IReactPackage
+ {
+ ///
+ /// Creates the list of native modules to register with the react
+ /// instance.
+ ///
+ /// The react application context.
+ /// The list of native modules.
+ public IReadOnlyList CreateNativeModules(ReactContext reactContext)
+ {
+ return new List
+ {
+ new RNFSManager(reactContext),
+ };
+ }
+
+ ///
+ /// Creates the list of JavaScript modules to register with the
+ /// react instance.
+ ///
+ /// The list of JavaScript modules.
+ public IReadOnlyList CreateJavaScriptModulesConfig()
+ {
+ return new List(0);
+ }
+
+ ///
+ /// Creates the list of view managers that should be registered with
+ /// the .
+ ///
+ /// The react application context.
+ /// The list of view managers.
+ public IReadOnlyList CreateViewManagers(
+ ReactContext reactContext)
+ {
+ return new List(0);
+ }
+ }
+}
diff --git a/windows/RNFS.Net46/packages.config b/windows/RNFS.Net46/packages.config
new file mode 100644
index 00000000..b427c04e
--- /dev/null
+++ b/windows/RNFS.Net46/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/windows/RNFS.sln b/windows/RNFS.sln
index f8475f26..4d8dc9a3 100644
--- a/windows/RNFS.sln
+++ b/windows/RNFS.sln
@@ -12,6 +12,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChakraBridge", "..\node_mod
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RNFS.Tests", "RNFS.Tests\RNFS.Tests.csproj", "{8D2229AC-F6EC-4FBD-9AAC-FE4792DA98C6}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RNFS.Net46", "RNFS.Net46\RNFS.Net46.csproj", "{8F7EE18F-8E79-4648-B442-9554443BE262}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.projitems*{c7673ad5-e3aa-468c-a5fd-fa38154e205c}*SharedItemsImports = 4
@@ -111,6 +113,24 @@ Global
{8D2229AC-F6EC-4FBD-9AAC-FE4792DA98C6}.Release|x86.ActiveCfg = Release|x86
{8D2229AC-F6EC-4FBD-9AAC-FE4792DA98C6}.Release|x86.Build.0 = Release|x86
{8D2229AC-F6EC-4FBD-9AAC-FE4792DA98C6}.Release|x86.Deploy.0 = Release|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|ARM.ActiveCfg = Debug|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|ARM.Build.0 = Debug|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|x64.ActiveCfg = Debug|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|x64.Build.0 = Debug|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|x86.ActiveCfg = Debug|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Debug|x86.Build.0 = Debug|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|ARM.ActiveCfg = Development|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|ARM.Build.0 = Development|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|x64.ActiveCfg = Development|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|x64.Build.0 = Development|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|x86.ActiveCfg = Development|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Development|x86.Build.0 = Development|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|ARM.ActiveCfg = Release|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|ARM.Build.0 = Release|ARM
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|x64.ActiveCfg = Release|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|x64.Build.0 = Release|x64
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|x86.ActiveCfg = Release|x86
+ {8F7EE18F-8E79-4648-B442-9554443BE262}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE