diff --git a/WKRCloudStats/WKRCloudStats/ViewController+Player.swift b/WKRCloudStats/WKRCloudStats/ViewController+Player.swift
index 0c8a834..4428832 100644
--- a/WKRCloudStats/WKRCloudStats/ViewController+Player.swift
+++ b/WKRCloudStats/WKRCloudStats/ViewController+Player.swift
@@ -16,7 +16,8 @@ extension ViewController {
     func queryPlayerStats() {
         textView.textStorage?.append(NSAttributedString(string: "Querying Player Stats\n"))
 
-        let query = CKQuery(recordType: "UserStats", predicate: NSPredicate(value: true))
+        let recordType = isUsingUserStatsV3 ? "UserStatsv3" : "UserStats"
+        let query = CKQuery(recordType: "UserStatsv3", predicate: NSPredicate(value: true))
         query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
 
         let queryOperation = CKQueryOperation(query: query)
@@ -58,7 +59,7 @@ extension ViewController {
     // MARK: - Processing
 
     private func processPlayerStats() {
-        let keys = [
+        let v1Keys = [
             "CustomName",
             "DeviceName",
             "GCAlias",
@@ -78,6 +79,68 @@ extension ViewController {
             "ModifiedAt"
         ]
 
+        let v3Keys = [
+            "CustomNames",
+            "DeviceNames",
+            "GCAliases",
+
+            "gkFastestTime",
+            "gkHelp",
+            "gkInvitedToMatch",
+            "gkMatch",
+            "gkPages",
+            "gkPixelsScrolled",
+            "gkPoints",
+            "gkPressedJoin",
+            "gkRaceDNF",
+            "gkRaceFinishFirst",
+            "gkRaceFinishSecond",
+            "gkRaceFinishThird",
+            "gkRaces",
+            "gkTotalPlayers",
+            "gkTotalTime",
+            "gkUniquePlayers",
+            "gkVotes",
+            "mpcFastestTime",
+            "mpcHelp",
+            "mpcMatch",
+            "mpcPages",
+            "mpcPixelsScrolled",
+            "mpcPoints",
+            "mpcPressedHost",
+            "mpcPressedJoin",
+            "mpcRaceDNF",
+            "mpcRaceFinishFirst",
+            "mpcRaceFinishSecond",
+            "mpcRaceFinishThird",
+            "mpcRaces",
+            "mpcTotalPlayers",
+            "mpcTotalTime",
+            "mpcUniquePlayers",
+            "mpcVotes",
+            "multiplayerAverage",
+            "soloFastestTime",
+            "soloHelp",
+            "soloMatch",
+            "soloPages",
+            "soloPixelsScrolled",
+            "soloPressedHost",
+            "soloRaceDNF",
+            "soloRaceFinishFirst",
+            "soloRaces",
+            "soloTotalTime",
+            "soloVotes",
+            "triggeredEasterEgg",
+
+            "osVersion",
+            "coreVersion",
+            "coreBuild",
+            "CreatedAt",
+            "ModifiedAt"
+        ]
+
+        let keys = isUsingUserStatsV3 ? v3Keys : v1Keys
+
         var csvString = ""
         for key in keys {
             csvString += key + ","
@@ -86,7 +149,7 @@ extension ViewController {
         for record in playerRecords {
             for key in keys {
                 if let object = record.object(forKey: key) {
-                    csvString += "\(object)"
+                    csvString += "\(object)".replacingOccurrences(of: ",", with: "|").replacingOccurrences(of: "\n", with: "")
                 } else if key == "CreatedAt", let date = record.creationDate {
                     csvString += "\(date)"
                 } else if key == "ModifiedAt", let date = record.modificationDate {
diff --git a/WKRCloudStats/WKRCloudStats/ViewController.swift b/WKRCloudStats/WKRCloudStats/ViewController.swift
index 35edc18..444f4b0 100644
--- a/WKRCloudStats/WKRCloudStats/ViewController.swift
+++ b/WKRCloudStats/WKRCloudStats/ViewController.swift
@@ -19,6 +19,8 @@ class ViewController: NSViewController {
     var playerRecords = [CKRecord]()
     let publicDB = CKContainer(identifier: "iCloud.com.andrewfinke.wikiraces").publicCloudDatabase
 
+    var isUsingUserStatsV3 = true
+    
     // MARK: - View Life Cycle
 
     override func viewDidLoad() {
diff --git a/WKRKit/WKRKit/Info.plist b/WKRKit/WKRKit/Info.plist
index d8e819c..3d87ba2 100644
--- a/WKRKit/WKRKit/Info.plist
+++ b/WKRKit/WKRKit/Info.plist
@@ -17,7 +17,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>3.6.4</string>
 	<key>CFBundleVersion</key>
-	<string>8694</string>
+	<string>8765</string>
 	<key>NSPrincipalClass</key>
 	<string></string>
 </dict>
diff --git a/WKRPython/requirements.txt b/WKRPython/requirements.txt
index ff160f4..58f4ddd 100644
--- a/WKRPython/requirements.txt
+++ b/WKRPython/requirements.txt
@@ -26,7 +26,7 @@ six=1.12.0=py37_0
 soupsieve=1.7.1=py37_0
 sqlite=3.26.0=ha441bb4_0
 tk=8.6.8=ha441bb4_0
-urllib3=1.24.1=py37_0
+urllib3=1.24.2=py37_0
 wheel=0.32.3=py37_0
 xz=5.2.4=h1de35cc_4
 zlib=1.2.11=h1de35cc_3
diff --git a/WKRUIKit/WKRUIKit/Info.plist b/WKRUIKit/WKRUIKit/Info.plist
index 9958f82..44fc18c 100644
--- a/WKRUIKit/WKRUIKit/Info.plist
+++ b/WKRUIKit/WKRUIKit/Info.plist
@@ -17,7 +17,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>3.6.4</string>
 	<key>CFBundleVersion</key>
-	<string>9202</string>
+	<string>9274</string>
 	<key>NSPrincipalClass</key>
 	<string></string>
 </dict>
diff --git a/WikiRaces.xcworkspace/contents.xcworkspacedata b/WikiRaces.xcworkspace/contents.xcworkspacedata
index 60f8a07..7b98d1b 100644
--- a/WikiRaces.xcworkspace/contents.xcworkspacedata
+++ b/WikiRaces.xcworkspace/contents.xcworkspacedata
@@ -11,9 +11,9 @@
       location = "group:WKRUIKit/WKRUIKit.xcodeproj">
    </FileRef>
    <FileRef
-      location = "group:WKRCloudStats/WKRCloudStats.xcodeproj">
+      location = "group:WKRArticlesPreviewer/WKRArticlesPreviewer.xcodeproj">
    </FileRef>
    <FileRef
-      location = "group:WKRArticlesPreviewer/WKRArticlesPreviewer.xcodeproj">
+      location = "group:WKRCloudStats/WKRCloudStats.xcodeproj">
    </FileRef>
 </Workspace>
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FIRAnalyticsConnector.framework/FIRAnalyticsConnector b/WikiRaces/Shared/Frameworks/Analytics/FIRAnalyticsConnector.framework/FIRAnalyticsConnector
index 1898de6c..58ca891 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FIRAnalyticsConnector.framework/FIRAnalyticsConnector and b/WikiRaces/Shared/Frameworks/Analytics/FIRAnalyticsConnector.framework/FIRAnalyticsConnector differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/FirebaseABTesting b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/FirebaseABTesting
index abb4d3f..35331ff 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/FirebaseABTesting and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/FirebaseABTesting differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRExperimentController.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRExperimentController.h
index abd2959..abb4a4c 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRExperimentController.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRExperimentController.h
@@ -12,6 +12,7 @@ extern const ABTExperimentPayload_ExperimentOverflowPolicy FIRDefaultExperimentO
 
 /// This class is for Firebase services to handle experiments updates to Firebase Analytics.
 /// Experiments can be set, cleared and updated through this controller.
+NS_SWIFT_NAME(ExperimentController)
 @interface FIRExperimentController : NSObject
 
 /// Returns the FIRExperimentController singleton.
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h
index a245a81..11730ea 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h
@@ -3,18 +3,23 @@
 NS_ASSUME_NONNULL_BEGIN
 
 /// Default event name for when an experiment is set.
-extern NSString *const FIRSetExperimentEventName;
+extern NSString *const FIRSetExperimentEventName NS_SWIFT_NAME(DefaultSetExperimentEventName);
 /// Default event name for when an experiment is activated.
-extern NSString *const FIRActivateExperimentEventName;
+extern NSString *const FIRActivateExperimentEventName
+    NS_SWIFT_NAME(DefaultActivateExperimentEventName);
 /// Default event name for when an experiment is cleared.
-extern NSString *const FIRClearExperimentEventName;
+extern NSString *const FIRClearExperimentEventName
+    NS_SWIFT_NAME(DefaultClearExperimentEventName);
 /// Default event name for when an experiment times out for being activated.
-extern NSString *const FIRTimeoutExperimentEventName;
+extern NSString *const FIRTimeoutExperimentEventName
+    NS_SWIFT_NAME(DefaultTimeoutExperimentEventName);
 /// Default event name for when an experiment is expired as it reaches the end of TTL.
-extern NSString *const FIRExpireExperimentEventName;
+extern NSString *const FIRExpireExperimentEventName
+    NS_SWIFT_NAME(DefaultExpireExperimentEventName);
 
 /// An Experiment Lifecycle Event Object that specifies the name of the experiment event to be
 /// logged by Firebase Analytics.
+NS_SWIFT_NAME(LifecycleEvents)
 @interface FIRLifecycleEvents : NSObject
 
 /// Event name for when an experiment is set. It is default to FIRSetExperimentEventName and can be
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Modules/module.modulemap b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Modules/module.modulemap
index 603022f..0ab6367 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Modules/module.modulemap
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseABTesting.framework/Modules/module.modulemap
@@ -1,7 +1,9 @@
 framework module FirebaseABTesting {
   umbrella header "FirebaseABTesting.h"
   export *
-  module * { export *}
-  link "z"
+  module * { export * }
+  link framework "CoreFoundation"
+  link framework "Foundation"
   link framework "Security"
-  link framework "SystemConfiguration"}
+  link framework "SystemConfiguration"
+}
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/FirebaseAnalytics b/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/FirebaseAnalytics
index b5d8a4a..12f18f9 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/FirebaseAnalytics and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/FirebaseAnalytics differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
index f50707f..132aef7 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
@@ -15,3 +15,15 @@
 /// The method used to sign in. For example, "google", "facebook" or "twitter".
 static NSString *const kFIRUserPropertySignUpMethod
     NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method";
+
+/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user.
+/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the
+/// <a href="https://firebase.google.com/support/guides/disable-analytics">documentation</a> for
+/// more details and information about related settings.
+///
+/// <pre>
+///     [FIRAnalytics setUserPropertyString:@"NO"
+///                                 forName:kFIRUserPropertyAllowAdPersonalizationSignals];
+/// </pre>
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals
+    NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads";
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/FirebaseCore b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/FirebaseCore
index 259ee58..f9a88af 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/FirebaseCore and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/FirebaseCore differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h
deleted file mode 100644
index add4a38..0000000
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- * This class provides configuration fields for Firebase Analytics.
- */
-NS_SWIFT_NAME(AnalyticsConfiguration)
-DEPRECATED_MSG_ATTRIBUTE("Use these methods directly on the `Analytics` class.")
-@interface FIRAnalyticsConfiguration : NSObject
-
-/**
- * Returns the shared instance of FIRAnalyticsConfiguration.
- */
-+ (FIRAnalyticsConfiguration *)sharedInstance NS_SWIFT_NAME(shared());
-
-/**
- * Deprecated.
- * Sets the minimum engagement time in seconds required to start a new session. The default value
- * is 10 seconds.
- */
-- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval
-    DEPRECATED_MSG_ATTRIBUTE(
-        "Sessions are started immediately. More information at https://bit.ly/2FU46av");
-
-/**
- * Sets the interval of inactivity in seconds that terminates the current session. The default
- * value is 1800 seconds (30 minutes).
- */
-- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval;
-
-/**
- * Sets whether analytics collection is enabled for this app on this device. This setting is
- * persisted across app sessions. By default it is enabled.
- */
-- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRConfiguration.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRConfiguration.h
index b88fcaf..8de3b07 100644
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRConfiguration.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FIRConfiguration.h
@@ -16,14 +16,12 @@
 
 #import <Foundation/Foundation.h>
 
-#import "FIRAnalyticsConfiguration.h"
-#import "FIRLoggerLevel.h"
+#import <FirebaseCore/FIRLoggerLevel.h>
 
 NS_ASSUME_NONNULL_BEGIN
 
 /**
- * This interface provides global level properties that the developer can tweak, and the singleton
- * of the Firebase Analytics configuration class.
+ * This interface provides global level properties that the developer can tweak.
  */
 NS_SWIFT_NAME(FirebaseConfiguration)
 @interface FIRConfiguration : NSObject
@@ -31,11 +29,6 @@ NS_SWIFT_NAME(FirebaseConfiguration)
 /** Returns the shared configuration object. */
 @property(class, nonatomic, readonly) FIRConfiguration *sharedInstance NS_SWIFT_NAME(shared);
 
-/** The configuration class for Firebase Analytics. */
-@property(nonatomic, readwrite)
-    FIRAnalyticsConfiguration *analyticsConfiguration DEPRECATED_MSG_ATTRIBUTE(
-        "Use the methods available here directly on the `Analytics` class.");
-
 /**
  * Sets the logging level for internal Firebase logging. Firebase will only log messages
  * that are logged at or below loggerLevel. The messages are logged both to the Xcode
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FirebaseCore.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FirebaseCore.h
index fa26f69..95119ae 100644
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FirebaseCore.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCore.framework/Headers/FirebaseCore.h
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#import "FIRAnalyticsConfiguration.h"
 #import "FIRApp.h"
 #import "FIRConfiguration.h"
 #import "FIRLoggerLevel.h"
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics
index 784272d..89054cf 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/Modules/module.modulemap b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/Modules/module.modulemap
index ce076e0..7bfc4b2 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/Modules/module.modulemap
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseCoreDiagnostics.framework/Modules/module.modulemap
@@ -2,6 +2,8 @@ framework module FirebaseCoreDiagnostics {
   export *
   module * { export * }
   link "z"
+  link framework "Foundation"
   link framework "Security"
   link framework "SystemConfiguration"
+  link framework "UIKit"
 }
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/FirebaseInstanceID b/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/FirebaseInstanceID
index b4eb9f5..ebc44f1 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/FirebaseInstanceID and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/FirebaseInstanceID differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/Headers/FIRInstanceID.h b/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/Headers/FIRInstanceID.h
index d95995a..c187d55 100644
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/Headers/FIRInstanceID.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseInstanceID.framework/Headers/FIRInstanceID.h
@@ -208,14 +208,6 @@ NS_SWIFT_NAME(InstanceID)
  */
 - (void)instanceIDWithHandler:(FIRInstanceIDResultHandler)handler;
 
-/**
- *  Returns a Firebase Messaging scoped token for the firebase app.
- *
- *  @return Returns the stored token if the device has registered with Firebase Messaging, otherwise
- *          returns nil.
- */
-- (nullable NSString *)token __deprecated_msg("Use instanceIDWithHandler: instead.");
-
 /**
  *  Returns a token that authorizes an Entity (example: cloud service) to perform
  *  an action on behalf of the application identified by Instance ID.
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/FirebasePerformance b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/FirebasePerformance
index 8924a3d..982ed23 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/FirebasePerformance and b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/FirebasePerformance differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRPerformance.h b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRPerformance.h
index e7444a3..bdaeda2 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRPerformance.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRPerformance.h
@@ -2,8 +2,9 @@
 
 #import "FIRTrace.h"
 
-/** This class allows you to configure the Firebase Performance Reporting SDK. It also provides the
- *  interfaces to create timers and enable or disable automatic metrics capture.
+/**
+ * This class allows you to configure the Firebase Performance Reporting SDK. It also provides the
+ * interfaces to create timers and enable or disable automatic metrics capture.
  *
  * This SDK uses a Firebase Instance ID token to identify the app instance and periodically sends
  * data to the Firebase backend. (see `[FIRInstanceID getIDWithHandler:]`).
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRTrace.h b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRTrace.h
index a226cda..02d1d79 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRTrace.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Headers/FIRTrace.h
@@ -28,33 +28,6 @@ NS_SWIFT_NAME(Trace)
  */
 - (void)stop;
 
-/**
- * Increments the counter for the provided counter name by 1. If it is a new counter name, the
- * counter value will be initialized to 1. Does nothing if the trace has not been started or has
- * already been stopped.
- *
- * Note: This API has been deprecated. Please use -incrementMetric:byInt: instead.
- *
- * @param counterName The name of the counter to increment.
- */
-- (void)incrementCounterNamed:(nonnull NSString *)counterName
-    NS_SWIFT_NAME(incrementCounter(named:))
-    DEPRECATED_MSG_ATTRIBUTE("Please use -incrementMetric:byInt: instead.");
-
-/**
- * Increments the counter for the provided counter name with the provided value. If it is a new
- * counter name, the counter value will be initialized to the value. Does nothing if the trace has
- * not been started or has already been stopped.
- *
- * Note: This API has been deprecated. Please use -incrementMetric:byInt: instead.
- *
- * @param counterName The name of the counter to increment.
- * @param incrementValue The value the counter would be incremented with.
- */
-- (void)incrementCounterNamed:(nonnull NSString *)counterName by:(NSInteger)incrementValue
-    NS_SWIFT_NAME(incrementCounter(named:by:))
-    DEPRECATED_MSG_ATTRIBUTE("Please use -incrementMetric:byInt: instead.");
-
 #pragma mark - Metrics API
 
 /**
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Modules/module.modulemap b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Modules/module.modulemap
index 91041cd..8919ffa 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Modules/module.modulemap
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebasePerformance.framework/Modules/module.modulemap
@@ -5,7 +5,9 @@ framework module FirebasePerformance {
   link "c++"
   link "sqlite3"
   link "z"
+  link framework "CoreFoundation"
   link framework "CoreTelephony"
+  link framework "Foundation"
   link framework "QuartzCore"
   link framework "Security"
   link framework "StoreKit"
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/FirebaseRemoteConfig b/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/FirebaseRemoteConfig
index d860dcd..ca67ada 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/FirebaseRemoteConfig and b/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/FirebaseRemoteConfig differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/Modules/module.modulemap b/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/Modules/module.modulemap
index bfabd85..018acb5 100755
--- a/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/Modules/module.modulemap
+++ b/WikiRaces/Shared/Frameworks/Analytics/FirebaseRemoteConfig.framework/Modules/module.modulemap
@@ -1,10 +1,13 @@
 framework module FirebaseRemoteConfig {
   umbrella header "FirebaseRemoteConfig.h"
   export *
-  module * { export *}
+  module * { export * }
   link "sqlite3"
   link "z"
+  link framework "CoreFoundation"
+  link framework "Foundation"
   link framework "Security"
   link framework "StoreKit"
   link framework "SystemConfiguration"
-  link framework "UIKit"}
+  link framework "UIKit"
+}
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GTMSessionFetcher.framework/GTMSessionFetcher b/WikiRaces/Shared/Frameworks/Analytics/GTMSessionFetcher.framework/GTMSessionFetcher
index 5a3361f..3e75324 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/GTMSessionFetcher.framework/GTMSessionFetcher and b/WikiRaces/Shared/Frameworks/Analytics/GTMSessionFetcher.framework/GTMSessionFetcher differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleAppMeasurement.framework/GoogleAppMeasurement b/WikiRaces/Shared/Frameworks/Analytics/GoogleAppMeasurement.framework/GoogleAppMeasurement
index 01ee574..2561d1a 100755
Binary files a/WikiRaces/Shared/Frameworks/Analytics/GoogleAppMeasurement.framework/GoogleAppMeasurement and b/WikiRaces/Shared/Frameworks/Analytics/GoogleAppMeasurement.framework/GoogleAppMeasurement differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/GoogleToolboxForMac b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/GoogleToolboxForMac
index c632e5c..705418c 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/GoogleToolboxForMac and b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/GoogleToolboxForMac differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMLocalizedString.h b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMLocalizedString.h
deleted file mode 100644
index c49b8a9..0000000
--- a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMLocalizedString.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-//  GTMLocalizedString.h
-//
-//  Copyright (c) 2010 Google Inc. All rights reserved.
-//
-//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
-//  use this file except in compliance with the License.  You may obtain a copy
-//  of the License at
-//
-//  http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-//  License for the specific language governing permissions and limitations under
-//  the License.
-//
-
-#import <Foundation/Foundation.h>
-#import "GTMDefines.h"
-
-// The NSLocalizedString macros do not have NS_FORMAT_ARGUMENT modifiers put
-// on them which means you get warnings on Snow Leopard with when
-// GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES and you do things like:
-// NSString *foo
-//   = [NSString stringWithFormat:NSLocalizedString(@"blah %@", nil), @"bar"];
-// The GTMLocalizedString functions fix that for you so you can do:
-// NSString *foo
-//   = [NSString stringWithFormat:GTMLocalizedString(@"blah %@", nil), @"bar"];
-// and you will compile cleanly.
-// If you use genstrings you can call it with
-// genstrings -s GTMLocalizedString ...
-// and it should work as expected.
-// You can override how GTM gets its localized strings (if you are using
-// something other than NSLocalizedString) by redefining
-// GTMLocalizedStringWithDefaultValueInternal.
-
-#ifndef GTMLocalizedStringWithDefaultValueInternal
-  #define GTMLocalizedStringWithDefaultValueInternal \
-      NSLocalizedStringWithDefaultValue
-#endif
-
-GTM_INLINE NS_FORMAT_ARGUMENT(1) NSString *GTMLocalizedString(
-    NSString *key,  NSString *comment) {
-  return GTMLocalizedStringWithDefaultValueInternal(key,
-                                                    nil,
-                                                    [NSBundle mainBundle],
-                                                    @"",
-                                                    comment);
-}
-
-GTM_INLINE NS_FORMAT_ARGUMENT(1) NSString *GTMLocalizedStringFromTable(
-    NSString *key, NSString *tableName, NSString *comment) {
-  return GTMLocalizedStringWithDefaultValueInternal(key,
-                                                    tableName,
-                                                    [NSBundle mainBundle],
-                                                    @"",
-                                                    comment);
-}
-
-GTM_INLINE NS_FORMAT_ARGUMENT(1) NSString *GTMLocalizedStringFromTableInBundle(
-    NSString *key,  NSString *tableName, NSBundle *bundle, NSString *comment) {
-  return GTMLocalizedStringWithDefaultValueInternal(key,
-                                                    tableName,
-                                                    bundle,
-                                                    @"",
-                                                    comment);
-}
-
-GTM_INLINE NS_FORMAT_ARGUMENT(1) NSString *GTMLocalizedStringWithDefaultValue(
-    NSString *key, NSString *tableName, NSBundle *bundle, NSString *value,
-    NSString *comment) {
-  return GTMLocalizedStringWithDefaultValueInternal(key,
-                                                    tableName,
-                                                    bundle,
-                                                    value,
-                                                    comment);
-}
-
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMStringEncoding.h b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMStringEncoding.h
deleted file mode 100644
index 24fa0bc..0000000
--- a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMStringEncoding.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-//  GTMStringEncoding.h
-//
-//  Copyright 2010 Google Inc.
-//
-//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
-//  use this file except in compliance with the License.  You may obtain a copy
-//  of the License at
-//
-//  http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-//  License for the specific language governing permissions and limitations under
-//  the License.
-//
-
-#import <Foundation/Foundation.h>
-#import "GTMDefines.h"
-
-// A generic class for arbitrary base-2 to 128 string encoding and decoding.
-@interface GTMStringEncoding : NSObject {
- @private
-  NSData *charMapData_;
-  char *charMap_;
-  int reverseCharMap_[128];
-  int shift_;
-  int mask_;
-  BOOL doPad_;
-  char paddingChar_;
-  int padLen_;
-}
-
-// Create a new, autoreleased GTMStringEncoding object with a standard encoding.
-+ (id)binaryStringEncoding;
-+ (id)hexStringEncoding;
-+ (id)rfc4648Base32StringEncoding;
-+ (id)rfc4648Base32HexStringEncoding;
-+ (id)crockfordBase32StringEncoding;
-+ (id)rfc4648Base64StringEncoding;
-+ (id)rfc4648Base64WebsafeStringEncoding;
-
-// Create a new, autoreleased GTMStringEncoding object with the given string,
-// as described below.
-+ (id)stringEncodingWithString:(NSString *)string;
-
-// Initialize a new GTMStringEncoding object with the string.
-//
-// The length of the string must be a power of 2, at least 2 and at most 128.
-// Only 7-bit ASCII characters are permitted in the string.
-//
-// These characters are the canonical set emitted during encoding.
-// If the characters have alternatives (e.g. case, easily transposed) then use
-// addDecodeSynonyms: to configure them.
-- (id)initWithString:(NSString *)string;
-
-// Add decoding synonyms as specified in the synonyms argument.
-//
-// It should be a sequence of one previously reverse mapped character,
-// followed by one or more non-reverse mapped character synonyms.
-// Only 7-bit ASCII characters are permitted in the string.
-//
-// e.g. If a GTMStringEncoder object has already been initialised with a set
-// of characters excluding I, L and O (to avoid confusion with digits) and you
-// want to accept them as digits you can call addDecodeSynonyms:@"0oO1iIlL".
-- (void)addDecodeSynonyms:(NSString *)synonyms;
-
-// A sequence of characters to ignore if they occur during encoding.
-// Only 7-bit ASCII characters are permitted in the string.
-- (void)ignoreCharacters:(NSString *)chars;
-
-// Indicates whether padding is performed during encoding.
-- (BOOL)doPad;
-- (void)setDoPad:(BOOL)doPad;
-
-// Sets the padding character to use during encoding.
-- (void)setPaddingChar:(char)c;
-
-// Encode a raw binary buffer to a 7-bit ASCII string.
-- (NSString *)encode:(NSData *)data __attribute__((deprecated("Use encode:error:")));
-- (NSString *)encodeString:(NSString *)string __attribute__((deprecated("Use encodeString:error:")));
-
-- (NSString *)encode:(NSData *)data error:(NSError **)error;
-- (NSString *)encodeString:(NSString *)string error:(NSError **)error;
-
-// Decode a 7-bit ASCII string to a raw binary buffer.
-- (NSData *)decode:(NSString *)string __attribute__((deprecated("Use decode:error:")));
-- (NSString *)stringByDecoding:(NSString *)string __attribute__((deprecated("Use stringByDecoding:error:")));
-
-- (NSData *)decode:(NSString *)string error:(NSError **)error;
-- (NSString *)stringByDecoding:(NSString *)string error:(NSError **)error;
-
-@end
-
-FOUNDATION_EXPORT NSString *const GTMStringEncodingErrorDomain;
-FOUNDATION_EXPORT NSString *const GTMStringEncodingBadCharacterIndexKey;  // NSNumber
-
-typedef NS_ENUM(NSInteger, GTMStringEncodingError) {
-  // Unable to convert a buffer to NSASCIIStringEncoding.
-  GTMStringEncodingErrorUnableToConverToAscii = 1024,
-  // Unable to convert a buffer to NSUTF8StringEncoding.
-  GTMStringEncodingErrorUnableToConverToUTF8,
-  // Encountered a bad character.
-  // GTMStringEncodingBadCharacterIndexKey will have the index of the character.
-  GTMStringEncodingErrorUnknownCharacter,
-  // The data had a padding character in the middle of the data. Padding characters
-  // can only be at the end.
-  GTMStringEncodingErrorExpectedPadding,
-  // There is unexpected data at the end of the data that could not be decoded.
-  GTMStringEncodingErrorIncompleteTrailingData,
-};
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMTypeCasting.h b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMTypeCasting.h
deleted file mode 100644
index 0c5899f..0000000
--- a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMTypeCasting.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-//  GTMTypeCasting.h
-//
-//  Copyright 2010 Google Inc.
-//
-//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
-//  use this file except in compliance with the License.  You may obtain a copy
-//  of the License at
-//
-//  http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-//  License for the specific language governing permissions and limitations under
-//  the License.
-//
-
-#import <Foundation/Foundation.h>
-#import "GTMDefines.h"
-
-// These are some basic macros for making down-casting safer in Objective C.
-// They are loosely based on the same cast types with similar names in C++.
-// A typical usage would look like this:
-//
-// Bar* b = [[Bar alloc] init];
-// Foo* a = GTM_STATIC_CAST(Foo, b);
-//
-// Note that it's GTM_STATIC_CAST(Foo, b) and not GTM_STATIC_CAST(Foo*, b).
-//
-// GTM_STATIC_CAST runs only in debug mode, and will assert if and only if:
-//   - object is non nil
-//   - [object isKindOfClass:[cls class]] returns nil
-//
-// otherwise it returns object.
-//
-// GTM_DYNAMIC_CAST runs in both debug and release and will return nil if
-//   - object is nil
-//   - [object isKindOfClass:[cls class]] returns nil
-//
-// otherwise it returns object.
-//
-
-// Support functions for dealing with casting.
-GTM_INLINE id GTMDynamicCastSupport(Class cls, id object) {
-  _GTMDevAssert(cls, @"Nil Class");
-  return [object isKindOfClass:cls] ? object : nil;
-}
-
-GTM_INLINE id GTMStaticCastSupport(Class cls, id object) {
-  id value = nil;
-  if (object) {
-    value = GTMDynamicCastSupport(cls, object);
-    _GTMDevAssert(value, @"Could not cast %@ to class %@", object, cls);
-  }
-  return value;
-}
-
-#ifndef GTM_STATIC_CAST
-  #ifdef DEBUG
-    #define GTM_STATIC_CAST(type, object) \
-      ((type *) GTMStaticCastSupport([type class], object))
-  #else
-    #define GTM_STATIC_CAST(type, object) ((type *) (object))
-  #endif
-#endif
-
-#ifndef GTM_DYNAMIC_CAST
-  #define GTM_DYNAMIC_CAST(type, object) \
-    ((type *) GTMDynamicCastSupport([type class], object))
-#endif
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMURLBuilder.h b/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMURLBuilder.h
deleted file mode 100644
index f333ec4..0000000
--- a/WikiRaces/Shared/Frameworks/Analytics/GoogleToolboxForMac.framework/Headers/GTMURLBuilder.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-//  GTMURLBuilder.h
-//
-//  Copyright 2012 Google Inc.
-//
-//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
-//  use this file except in compliance with the License.  You may obtain a copy
-//  of the License at
-//
-//  http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-//  License for the specific language governing permissions and limitations
-//  under the License.
-//
-
-//
-// Class for creating URLs. It handles URL encoding of parameters.
-//
-// Usage example:
-//
-// GTMURLBuilder *URLBuilder =
-//     [GTMURLBuilder builderWithString:@"http://www.google.com"];
-// [URLBuilder setValue:@"abc" forParameter:@"q"];
-// NSURL *URL = [URLBuilder URL];
-//
-// NOTE: Apps targeting iOS 8 or OS X 10.10 and later should use
-//       NSURLComponents and NSURLQueryItem to create URLs with
-//       query arguments instead of using this class.
-
-
-#import <Foundation/Foundation.h>
-#import "GTMDefines.h"
-
-#if (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) \
-|| (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
-__deprecated_msg("GTMURLBuilder is obsolete; update your app to use NSURLComponents queryItems property instead.")
-#endif
-@interface GTMURLBuilder : NSObject {
- @private
-  NSMutableDictionary *params_;
-}
-
-@property(nonatomic, readonly) NSString *baseURLString;
-
-// |URLString| is expected to be a valid URL with already escaped parameter
-// values.
-+ (GTMURLBuilder *)builderWithString:(NSString *)URLString;
-+ (GTMURLBuilder *)builderWithURL:(NSURL *)URL;
-
-// |URLString| The base URL to which parameters will be appended.
-// If the URL already contains parameters, they should already be encoded.
-- (id)initWithString:(NSString *)URLString;
-- (void)setValue:(NSString *)value forParameter:(NSString *)parameter;
-- (void)setIntegerValue:(NSInteger)value forParameter:(NSString *)parameter;
-- (NSString *)valueForParameter:(NSString *)parameter;
-// Returns 0 if there is no value for |parameter| or if the value cannot
-// be parsed into an NSInteger. Use valueForParameter if you want to make
-// sure that the value is set before attempting the parsing.
-- (NSInteger)integerValueForParameter:(NSString *)parameter;
-- (void)removeParameter:(NSString *)parameter;
-- (void)setParameters:(NSDictionary *)parameters;
-- (NSDictionary *)parameters;
-- (NSURL *)URL;
-- (NSString *)URLString;
-
-// Case-sensitive comparison of the URL. Also protocol and host are compared
-// as case-sensitive strings. The order of URL parameters is ignored.
-- (BOOL)isEqual:(GTMURLBuilder *)URLBuilder;
-
-@end
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/GoogleUtilities b/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/GoogleUtilities
index 7941a7d..38ce2ca 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/GoogleUtilities and b/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/GoogleUtilities differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/Headers/GULLoggerCodes.h b/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/Headers/GULLoggerCodes.h
index b71c037..fd22ba6 100644
--- a/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/Headers/GULLoggerCodes.h
+++ b/WikiRaces/Shared/Frameworks/Analytics/GoogleUtilities.framework/Headers/GULLoggerCodes.h
@@ -16,20 +16,21 @@
 
 typedef NS_ENUM(NSInteger, GULSwizzlerMessageCode) {
   // App Delegate Swizzling.
-  kGULSwizzlerMessageCodeAppDelegateSwizzling000 = 1000,  // I-SWZ001000
-  kGULSwizzlerMessageCodeAppDelegateSwizzling001 = 1001,  // I-SWZ001001
-  kGULSwizzlerMessageCodeAppDelegateSwizzling002 = 1002,  // I-SWZ001002
-  kGULSwizzlerMessageCodeAppDelegateSwizzling003 = 1003,  // I-SWZ001003
-  kGULSwizzlerMessageCodeAppDelegateSwizzling004 = 1004,  // I-SWZ001004
-  kGULSwizzlerMessageCodeAppDelegateSwizzling005 = 1005,  // I-SWZ001005
-  kGULSwizzlerMessageCodeAppDelegateSwizzling006 = 1006,  // I-SWZ001006
-  kGULSwizzlerMessageCodeAppDelegateSwizzling007 = 1007,  // I-SWZ001007
-  kGULSwizzlerMessageCodeAppDelegateSwizzling008 = 1008,  // I-SWZ001008
-  kGULSwizzlerMessageCodeAppDelegateSwizzling009 = 1009,  // I-SWZ001009
-  kGULSwizzlerMessageCodeAppDelegateSwizzling010 = 1010,  // I-SWZ001010
-  kGULSwizzlerMessageCodeAppDelegateSwizzling011 = 1011,  // I-SWZ001011
-  kGULSwizzlerMessageCodeAppDelegateSwizzling012 = 1012,  // I-SWZ001012
-  kGULSwizzlerMessageCodeAppDelegateSwizzling013 = 1013,  // I-SWZ001013
+  kGULSwizzlerMessageCodeAppDelegateSwizzling000 = 1000,                 // I-SWZ001000
+  kGULSwizzlerMessageCodeAppDelegateSwizzling001 = 1001,                 // I-SWZ001001
+  kGULSwizzlerMessageCodeAppDelegateSwizzling002 = 1002,                 // I-SWZ001002
+  kGULSwizzlerMessageCodeAppDelegateSwizzling003 = 1003,                 // I-SWZ001003
+  kGULSwizzlerMessageCodeAppDelegateSwizzling004 = 1004,                 // I-SWZ001004
+  kGULSwizzlerMessageCodeAppDelegateSwizzling005 = 1005,                 // I-SWZ001005
+  kGULSwizzlerMessageCodeAppDelegateSwizzling006 = 1006,                 // I-SWZ001006
+  kGULSwizzlerMessageCodeAppDelegateSwizzling007 = 1007,                 // I-SWZ001007
+  kGULSwizzlerMessageCodeAppDelegateSwizzling008 = 1008,                 // I-SWZ001008
+  kGULSwizzlerMessageCodeAppDelegateSwizzling009 = 1009,                 // I-SWZ001009
+  kGULSwizzlerMessageCodeAppDelegateSwizzling010 = 1010,                 // I-SWZ001010
+  kGULSwizzlerMessageCodeAppDelegateSwizzling011 = 1011,                 // I-SWZ001011
+  kGULSwizzlerMessageCodeAppDelegateSwizzling012 = 1012,                 // I-SWZ001012
+  kGULSwizzlerMessageCodeAppDelegateSwizzling013 = 1013,                 // I-SWZ001013
+  kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate = 1014,  // I-SWZ001014
 
   // Method Swizzling.
   kGULSwizzlerMessageCodeMethodSwizzling000 = 2000,  // I-SWZ002000
diff --git a/WikiRaces/Shared/Frameworks/Analytics/Protobuf.framework/Protobuf b/WikiRaces/Shared/Frameworks/Analytics/Protobuf.framework/Protobuf
index a64e607..ba7b25a 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/Protobuf.framework/Protobuf and b/WikiRaces/Shared/Frameworks/Analytics/Protobuf.framework/Protobuf differ
diff --git a/WikiRaces/Shared/Frameworks/Analytics/nanopb.framework/nanopb b/WikiRaces/Shared/Frameworks/Analytics/nanopb.framework/nanopb
index b2a02e8..ef80760 100644
Binary files a/WikiRaces/Shared/Frameworks/Analytics/nanopb.framework/nanopb and b/WikiRaces/Shared/Frameworks/Analytics/nanopb.framework/nanopb differ
diff --git a/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCConnectViewController/MPCConnectViewController+Invite.swift b/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCConnectViewController/MPCConnectViewController+Invite.swift
index 6ed17a7..846284a 100644
--- a/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCConnectViewController/MPCConnectViewController+Invite.swift	
+++ b/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCConnectViewController/MPCConnectViewController+Invite.swift	
@@ -93,7 +93,8 @@ extension MPCConnectViewController: MCNearbyServiceAdvertiserDelegate, MCSession
     // MARK: - MCAdvertiserAssistantDelegate
 
     func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) {
-
+        let info = "didNotStartAdvertisingPeer: " + error.localizedDescription
+        PlayerAnonymousMetrics.log(event: .error(info))
     }
 
     func advertiser(_ advertiser: MCNearbyServiceAdvertiser,
diff --git a/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCHostViewController/MPCHostViewController.swift b/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCHostViewController/MPCHostViewController.swift
index 2b033df..89a736f 100644
--- a/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCHostViewController/MPCHostViewController.swift	
+++ b/WikiRaces/Shared/Menu View Controllers/Connect View Controllers/Multipeer Connectivity/MPCHostViewController/MPCHostViewController.swift	
@@ -226,6 +226,8 @@ internal class MPCHostViewController: UITableViewController, MCSessionDelegate,
     }
 
     func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
+        let info = "didNotStartBrowsingForPeers: " + error.localizedDescription
+        PlayerAnonymousMetrics.log(event: .error(info))
         listenerUpdate?(.cancel)
     }
 
diff --git a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+Manager.swift b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+Manager.swift
index 91f245d..d32d073 100644
--- a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+Manager.swift	
+++ b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+Manager.swift	
@@ -28,7 +28,29 @@ extension GameViewController {
         switch gameUpdate {
         case .state(let state):
             PlayerAnonymousMetrics.log(event: .gameState("Transition: \(state)."))
-            transition(to: state)
+
+            func startTransition(to state: WKRGameState) {
+                transitionState = .inProgress
+                transition(to: state, completion: { [weak self] in
+                    guard let self = self else { return }
+                    switch self.transitionState {
+                    case .none, .inProgress:
+                        self.transitionState = .none
+                    case .quitting(let quitState):
+                        if quitState == .waiting {
+                            self.performQuit()
+                        }
+                    }
+                })
+            }
+
+            if transitionState == .none {
+                startTransition(to: state)
+            } else {
+                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
+                    startTransition(to: state)
+                }
+            }
         case .error(let error):
             DispatchQueue.main.async {
                 self.errorOccurred(error)
@@ -38,29 +60,33 @@ extension GameViewController {
         case .playerRaceLinkCountForCurrentRace(let linkCount):
             webView?.text = linkCount.description
         case .playerStatsForLastRace(let points, let place, let webViewPixelsScrolled):
-            guard let raceType = statRaceType else { return }
-            PlayerStatsManager.shared.completedRace(type: raceType,
-                                             points: points,
-                                             place: place,
-                                             timeRaced: timeRaced,
-                                             pixelsScrolled: webViewPixelsScrolled)
-
-            let event: PlayerAnonymousMetrics.Event
-            switch raceType {
-            case .mpc:
-                event = .mpcRaceCompleted
-            case .gameKit:
-                event = .gkRaceCompleted
-            case .solo:
-                event = .soloRaceCompleted
-            }
-            PlayerAnonymousMetrics.log(event: event,
-                                       attributes: [
-                                        "Time": timeRaced,
-                                        "Points": points,
-                                        "WebViewScrolled": webViewPixelsScrolled
-                ])
+            processRaceStats(points: points, place: place, webViewPixelsScrolled: webViewPixelsScrolled)
+        }
+    }
+
+    private func processRaceStats(points: Int, place: Int?, webViewPixelsScrolled: Int) {
+        guard let raceType = statRaceType else { return }
+        PlayerStatsManager.shared.completedRace(type: raceType,
+                                                points: points,
+                                                place: place,
+                                                timeRaced: timeRaced,
+                                                pixelsScrolled: webViewPixelsScrolled)
+
+        let event: PlayerAnonymousMetrics.Event
+        switch raceType {
+        case .mpc:
+            event = .mpcRaceCompleted
+        case .gameKit:
+            event = .gkRaceCompleted
+        case .solo:
+            event = .soloRaceCompleted
         }
+        PlayerAnonymousMetrics.log(event: event,
+                                   attributes: [
+                                    "Time": timeRaced,
+                                    "Points": points,
+                                    "WebViewScrolled": webViewPixelsScrolled
+            ])
     }
 
     private func votingUpdate(_ votingUpdate: WKRGameManager.VotingUpdate) {
@@ -102,8 +128,8 @@ extension GameViewController {
     }
 
     private func errorOccurred(_ error: WKRFatalError) {
-        guard self.view.window != nil  && !isPlayerQuitting else { return }
-        isPlayerQuitting = true
+        guard self.view.window != nil && !isErrorPresented else { return }
+        isErrorPresented = true
 
         webView?.isUserInteractionEnabled = false
         navigationItem.leftBarButtonItem?.isEnabled = false
@@ -113,7 +139,7 @@ extension GameViewController {
                                                 message: error.message,
                                                 preferredStyle: .alert)
         let quitAction = UIAlertAction(title: "Menu", style: .default) { [weak self] _ in
-            self?.playerQuit()
+            self?.attemptQuit()
         }
         alertController.addAction(quitAction)
         self.dismissActiveController(completion: {
@@ -174,33 +200,37 @@ extension GameViewController {
 
     // MARK: - Transitions
 
-    private func transition(to state: WKRGameState) {
-        guard !isPlayerQuitting, state != gameState else { return }
-        gameState = state
+    private func transition(to state: WKRGameState, completion: @escaping () -> Void) {
+        guard state != gameState else {
+            completion()
+            return
+        }
 
+        gameState = state
         switch state {
         case .voting:
-            transitionToVoting()
+            transitionToVoting(completion: completion)
         case .results, .hostResults, .points:
-            transitionToResults()
+            transitionToResults(completion: completion)
         case .race:
-            transitionToRace()
-        default: break
+            transitionToRace(completion: completion)
+        default:
+            completion()
         }
     }
 
-    private func transitionToVoting() {
+    private func transitionToVoting(completion: @escaping () -> Void) {
         self.title = ""
         navigationController?.navigationBar.isHidden = true
         dismissActiveController(completion: { [weak self] in
-            self?.showVotingController()
+            self?.showVotingController(completion: completion)
         })
         navigationItem.leftBarButtonItem = nil
         navigationItem.rightBarButtonItem = nil
         setupNewWebView()
     }
 
-    private func showVotingController() {
+    private func showVotingController(completion: @escaping () -> Void) {
         let controller = VotingViewController()
         controller.voteInfo = gameManager.voteInfo
         controller.quitAlertController = quitAlertController(raceStarted: false)
@@ -223,7 +253,7 @@ extension GameViewController {
                     stat.increment()
                 }
             case .quit:
-                self.playerQuit()
+                self.attemptQuit()
             }
         }
 
@@ -235,14 +265,15 @@ extension GameViewController {
         present(navController, animated: true) { [weak self] in
             self?.connectingLabel.alpha = 0.0
             self?.activityIndicatorView.alpha = 0.0
+            completion()
         }
     }
 
-    private func transitionToResults() {
+    private func transitionToResults(completion: @escaping () -> Void) {
         raceTimer?.invalidate()
         if activeViewController != resultsViewController || resultsViewController == nil {
             dismissActiveController(completion: { [weak self] in
-                self?.showResultsController()
+                self?.showResultsController(completion: completion)
                 UIView.animate(withDuration: WKRAnimationDurationConstants.gameFadeOut,
                                delay: WKRAnimationDurationConstants.gameFadeOutDelay,
                                options: .beginFromCurrentState,
@@ -255,6 +286,7 @@ extension GameViewController {
             })
         } else {
             resultsViewController?.state = gameState
+            completion()
         }
         navigationItem.leftBarButtonItem = nil
         navigationItem.rightBarButtonItem = nil
@@ -264,7 +296,7 @@ extension GameViewController {
         }
     }
 
-    private func showResultsController() {
+    private func showResultsController(completion: @escaping () -> Void) {
         let controller = ResultsViewController()
         controller.localPlayer = gameManager.localPlayer
         controller.addPlayersViewController = gameManager.hostNetworkInterface()
@@ -279,7 +311,7 @@ extension GameViewController {
             case .readyButtonPressed:
                 self.gameManager.player(.ready)
             case .quit:
-                self.playerQuit()
+                self.attemptQuit()
             }
         }
 
@@ -291,10 +323,11 @@ extension GameViewController {
         present(navController, animated: true) { [weak self] in
             self?.connectingLabel.alpha = 0.0
             self?.activityIndicatorView.alpha = 0.0
+            completion()
         }
     }
 
-    private func transitionToRace() {
+    private func transitionToRace(completion: @escaping () -> Void) {
         navigationController?.navigationBar.isHidden = false
         timeRaced = 0
         raceTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self] _ in
@@ -309,7 +342,7 @@ extension GameViewController {
         connectingLabel.alpha = 0.0
         activityIndicatorView.alpha = 0.0
 
-        dismissActiveController(completion: nil)
+        dismissActiveController(completion: completion)
 
         if networkConfig.isHost {
             PlayerAnonymousMetrics.log(event: .hostStartedRace,
diff --git a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+UI.swift b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+UI.swift
index 8b56f0e..fad49c3 100644
--- a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+UI.swift	
+++ b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController+UI.swift	
@@ -158,21 +158,31 @@ extension GameViewController {
         let quitAction = UIAlertAction(title: "Leave Match", style: .destructive) {  [weak self] _ in
             PlayerAnonymousMetrics.log(event: .userAction("quitAlertController:quit"))
             PlayerAnonymousMetrics.log(event: .quitRace, attributes: nil)
-            self?.playerQuit()
+            self?.attemptQuit()
         }
         alertController.addAction(quitAction)
 
         return alertController
     }
 
-    func playerQuit() {
-        DispatchQueue.main.async {
-            self.isPlayerQuitting = true
-            self.resetActiveControllers()
-            self.gameManager.player(.quit)
-            NotificationCenter.default.post(name: NSNotification.Name.localPlayerQuit,
-                                            object: nil)
+    func attemptQuit() {
+        guard transitionState == TransitionState.none || transitionState == TransitionState.inProgress else {
+            return
         }
+
+        if transitionState == .none {
+            performQuit()
+        } else {
+            transitionState = .quitting(.waiting)
+        }
+    }
+
+    func performQuit() {
+        transitionState = .quitting(.inProgress)
+        resetActiveControllers()
+        gameManager.player(.quit)
+        NotificationCenter.default.post(name: NSNotification.Name.localPlayerQuit,
+                                        object: nil)
     }
 
 }
diff --git a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController.swift b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController.swift
index 434908c..d075523 100644
--- a/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController.swift	
+++ b/WikiRaces/Shared/Race View Controllers/GameViewController/GameViewController.swift	
@@ -14,9 +14,24 @@ import WKRUIKit
 
 internal class GameViewController: UIViewController {
 
+    // MARK: - Types
+
+    enum TransitionState: Equatable {
+        //swiftlint:disable:next nesting
+        enum QuitState {
+            case waiting, inProgress
+        }
+        case none, inProgress, quitting(QuitState)
+    }
+
     // MARK: - Game Properties
 
-    var isPlayerQuitting = false
+    var transitionState = TransitionState.none {
+        didSet {
+            PlayerAnonymousMetrics.log(event: .gameState("TransitionState: \(transitionState)"))
+        }
+    }
+    var isErrorPresented = false
     var isConfigured = false
 
     var timeRaced = 0
diff --git a/WikiRaces/Shared/Race View Controllers/HistoryViewController/HistoryViewController.swift b/WikiRaces/Shared/Race View Controllers/HistoryViewController/HistoryViewController.swift
index 8c8bd58..368a499 100644
--- a/WikiRaces/Shared/Race View Controllers/HistoryViewController/HistoryViewController.swift	
+++ b/WikiRaces/Shared/Race View Controllers/HistoryViewController/HistoryViewController.swift	
@@ -156,6 +156,7 @@ internal class HistoryViewController: UITableViewController, SFSafariViewControl
             if shouldUpdateStatsCount {
                 tableView.reloadSections(IndexSet(integer: 1), with: .none)
             }
+
         }, completion: { _ in
             self.isTableViewAnimating = false
             if self.deferredUpdate {
@@ -187,9 +188,6 @@ internal class HistoryViewController: UITableViewController, SFSafariViewControl
     // MARK: - Table view data source
 
     override func numberOfSections(in tableView: UITableView) -> Int {
-        if player?.stats == nil {
-            return 1
-        }
         return 2
     }
 
diff --git a/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController+TableView.swift b/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController+TableView.swift
index aa6efd8..bc374e6 100644
--- a/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController+TableView.swift	
+++ b/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController+TableView.swift	
@@ -37,7 +37,9 @@ extension ResultsViewController: UITableViewDataSource, UITableViewDelegate {
             let sessionResults = resultsInfo.sessionResults(at: index)
             cell.updateStandings(for: sessionResults)
         default:
-            fatalError("Unexpected state \(state)")
+            // Unexpected state
+            cell.isShowingActivityIndicatorView = false
+            cell.isShowingCheckmark = false
         }
     }
 
diff --git a/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController.swift b/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController.swift
index befdb93..3f364d1 100644
--- a/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController.swift	
+++ b/WikiRaces/Shared/Race View Controllers/ResultsViewController/ResultsViewController.swift	
@@ -315,6 +315,8 @@ internal class ResultsViewController: CenteredTableViewController {
     override func overlayButtonPressed() {
         PlayerAnonymousMetrics.log(event: .userAction(#function))
 
+        UISelectionFeedbackGenerator().selectionChanged()
+
         addPlayersBarButtonItem?.isEnabled = false
         shareResultsBarButtonItem?.isEnabled = false
 
diff --git a/WikiRaces/Shared/Race View Controllers/VotingViewController/VotingViewController+TableView.swift b/WikiRaces/Shared/Race View Controllers/VotingViewController/VotingViewController+TableView.swift
index 98b753d..faf263c 100644
--- a/WikiRaces/Shared/Race View Controllers/VotingViewController/VotingViewController+TableView.swift	
+++ b/WikiRaces/Shared/Race View Controllers/VotingViewController/VotingViewController+TableView.swift	
@@ -28,6 +28,7 @@ extension VotingViewController: UITableViewDataSource, UITableViewDelegate {
 
     func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
         guard let lastIndexPath = tableView.indexPathForSelectedRow else {
+            UISelectionFeedbackGenerator().selectionChanged()
             return indexPath
         }
         if lastIndexPath == indexPath {
diff --git a/WikiRaces/WikiRaces (UI Catalog)/ViewController.swift b/WikiRaces/WikiRaces (UI Catalog)/ViewController.swift
index a6f0b25..1ece483 100644
--- a/WikiRaces/WikiRaces (UI Catalog)/ViewController.swift	
+++ b/WikiRaces/WikiRaces (UI Catalog)/ViewController.swift	
@@ -59,7 +59,7 @@ internal class ViewController: UIViewController {
 //                            } else if arc4random() % 30 == 0 {
 //                                player.state = .forfeited
                             } else {
-                                player.finishedViewingLastPage(pointsScrolled: 5)
+                                player.finishedViewingLastPage(pixelsScrolled: 5)
                                 player.nowViewing(page: page, linkHere: arc4random() % 5 == 0)
                             }
 
diff --git a/WikiRaces/WikiRaces/Info.plist b/WikiRaces/WikiRaces/Info.plist
index 8f350dc..3fcc5e9 100644
--- a/WikiRaces/WikiRaces/Info.plist
+++ b/WikiRaces/WikiRaces/Info.plist
@@ -15,9 +15,9 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>3.6.4</string>
+	<string>3.6.5</string>
 	<key>CFBundleVersion</key>
-	<string>5598</string>
+	<string>5652</string>
 	<key>ITSAppUsesNonExemptEncryption</key>
 	<false/>
 	<key>LSRequiresIPhoneOS</key>