[
  {
    "path": "Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '9.0'\n\ntarget 'Spotify' do\n  use_frameworks!\n\n  pod 'SDWebImage'\n  pod 'Appirater'\n  pod 'Firebase/Analytics'\n\nend\n"
  },
  {
    "path": "Pods/Appirater/Appirater.h",
    "content": "/*\n This file is part of Appirater.\n \n Copyright (c) 2012, Arash Payan\n All rights reserved.\n \n Permission is hereby granted, free of charge, to any person\n obtaining a copy of this software and associated documentation\n files (the \"Software\"), to deal in the Software without\n restriction, including without limitation the rights to use,\n copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following\n conditions:\n \n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.\n */\n/*\n * Appirater.h\n * appirater\n *\n * Created by Arash Payan on 9/5/09.\n * http://arashpayan.com\n * Copyright 2012 Arash Payan. All rights reserved.\n */\n\n#import <Foundation/Foundation.h>\n#import <StoreKit/StoreKit.h>\n#import \"AppiraterDelegate.h\"\n\nextern NSString *const kAppiraterFirstUseDate;\nextern NSString *const kAppiraterUseCount;\nextern NSString *const kAppiraterSignificantEventCount;\nextern NSString *const kAppiraterCurrentVersion;\nextern NSString *const kAppiraterRatedCurrentVersion;\nextern NSString *const kAppiraterDeclinedToRate;\nextern NSString *const kAppiraterReminderRequestDate;\n\n/*!\n Your localized app's name.\n */\n#define APPIRATER_LOCALIZED_APP_NAME    [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@\"CFBundleDisplayName\"]\n\n/*!\n Your app's name.\n */\n#define APPIRATER_APP_NAME\t\t\t\tAPPIRATER_LOCALIZED_APP_NAME ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:@\"CFBundleDisplayName\"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:@\"CFBundleName\"]\n\n/*!\n This is the message your users will see once they've passed the day+launches\n threshold.\n */\n#define APPIRATER_LOCALIZED_MESSAGE     NSLocalizedStringFromTableInBundle(@\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\", @\"AppiraterLocalizable\", [Appirater bundle], nil)\n#define APPIRATER_MESSAGE\t\t\t\t[NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE, APPIRATER_APP_NAME]\n\n/*!\n This is the title of the message alert that users will see.\n */\n#define APPIRATER_LOCALIZED_MESSAGE_TITLE   NSLocalizedStringFromTableInBundle(@\"Rate %@\", @\"AppiraterLocalizable\", [Appirater bundle], nil)\n#define APPIRATER_MESSAGE_TITLE             [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE_TITLE, APPIRATER_APP_NAME]\n\n/*!\n The text of the button that rejects reviewing the app.\n */\n#define APPIRATER_CANCEL_BUTTON\t\t\tNSLocalizedStringFromTableInBundle(@\"No, Thanks\", @\"AppiraterLocalizable\", [Appirater bundle], nil)\n\n/*!\n Text of button that will send user to app review page.\n */\n#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedStringFromTableInBundle(@\"Rate %@\", @\"AppiraterLocalizable\", [Appirater bundle], nil)\n#define APPIRATER_RATE_BUTTON\t\t\t[NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]\n\n/*!\n Text for button to remind the user to review later.\n */\n#define APPIRATER_RATE_LATER\t\t\tNSLocalizedStringFromTableInBundle(@\"Remind me later\", @\"AppiraterLocalizable\", [Appirater bundle], nil)\n\n@interface Appirater : NSObject <UIAlertViewDelegate, SKStoreProductViewControllerDelegate>\n\n/*!\n UIAlertController for iOS 8 and later, otherwise UIAlertView\n */\n@property(nonatomic, strong) id ratingAlert;\n@property(nonatomic) BOOL openInAppStore;\n#if __has_feature(objc_arc_weak)\n@property(nonatomic, weak) NSObject <AppiraterDelegate> *delegate;\n#else\n@property(nonatomic, unsafe_unretained) NSObject <AppiraterDelegate> *delegate;\n#endif\n\n/*!\n Tells Appirater that the app has launched, and on devices that do NOT\n support multitasking, the 'uses' count will be incremented. You should\n call this method at the end of your application delegate's\n application:didFinishLaunchingWithOptions: method.\n \n If the app has been used enough to be rated (and enough significant events),\n you can suppress the rating alert\n by passing NO for canPromptForRating. The rating alert will simply be postponed\n until it is called again with YES for canPromptForRating. The rating alert\n can also be triggered by appEnteredForeground: and userDidSignificantEvent:\n (as long as you pass YES for canPromptForRating in those methods).\n */\n+ (void)appLaunched:(BOOL)canPromptForRating;\n\n/*!\n Tells Appirater that the app was brought to the foreground on multitasking\n devices. You should call this method from the application delegate's\n applicationWillEnterForeground: method.\n \n If the app has been used enough to be rated (and enough significant events),\n you can suppress the rating alert\n by passing NO for canPromptForRating. The rating alert will simply be postponed\n until it is called again with YES for canPromptForRating. The rating alert\n can also be triggered by appLaunched: and userDidSignificantEvent:\n (as long as you pass YES for canPromptForRating in those methods).\n */\n+ (void)appEnteredForeground:(BOOL)canPromptForRating;\n\n/*!\n Tells Appirater that the user performed a significant event. A significant\n event is whatever you want it to be. If you're app is used to make VoIP\n calls, then you might want to call this method whenever the user places\n a call. If it's a game, you might want to call this whenever the user\n beats a level boss.\n \n If the user has performed enough significant events and used the app enough,\n you can suppress the rating alert by passing NO for canPromptForRating. The\n rating alert will simply be postponed until it is called again with YES for\n canPromptForRating. The rating alert can also be triggered by appLaunched:\n and appEnteredForeground: (as long as you pass YES for canPromptForRating\n in those methods).\n */\n+ (void)userDidSignificantEvent:(BOOL)canPromptForRating;\n\n/*!\n Tells Appirater to try and show the prompt (a rating alert). The prompt will be showed\n if there is connection available, the user hasn't declined to rate\n or hasn't rated current version.\n \n You could call to show the prompt regardless Appirater settings,\n e.g., in case of some special event in your app.\n */\n+ (void)tryToShowPrompt;\n\n/*!\n Tells Appirater to show the prompt (a rating alert).\n Similar to tryToShowPrompt, but without checks (the prompt is always displayed).\n Passing false will hide the rate later button on the prompt.\n  \n The only case where you should call this is if your app has an\n explicit \"Rate this app\" command somewhere. This is similar to rateApp,\n but instead of jumping to the review directly, an intermediary prompt is displayed.\n */\n+ (void)forceShowPrompt:(BOOL)displayRateLaterButton;\n\n/*!\n Tells Appirater to open the App Store page where the user can specify a\n rating for the app. Also records the fact that this has happened, so the\n user won't be prompted again to rate the app.\n\n The only case where you should call this directly is if your app has an\n explicit \"Rate this app\" command somewhere.  In all other cases, don't worry\n about calling this -- instead, just call the other functions listed above,\n and let Appirater handle the bookkeeping of deciding when to ask the user\n whether to rate the app.\n */\n+ (void)rateApp;\n\n/*!\n Tells Appirater to immediately close any open rating modals (e.g. StoreKit rating VCs).\n*/\n+ (void)closeModal;\n\n/*!\n Asks Appirater if the user has declined to rate;\n*/\n- (BOOL)userHasDeclinedToRate;\n\n/*!\n Asks Appirater if the user has rated the current version.\n Note that this is not a guarantee that the user has actually rated the app in the \n app store, but they've just clicked the rate button on the Appirater dialog. \n*/\n- (BOOL)userHasRatedCurrentVersion;\n\n@end\n\n@interface Appirater(Configuration)\n\n/*!\n Set your Apple generated software id here.\n */\n+ (void) setAppId:(NSString*)appId;\n\n/*!\n Users will need to have the same version of your app installed for this many\n days before they will be prompted to rate it.\n */\n+ (void) setDaysUntilPrompt:(double)value;\n\n/*!\n An example of a 'use' would be if the user launched the app. Bringing the app\n into the foreground (on devices that support it) would also be considered\n a 'use'. You tell Appirater about these events using the two methods:\n [Appirater appLaunched:]\n [Appirater appEnteredForeground:]\n \n Users need to 'use' the same version of the app this many times before\n before they will be prompted to rate it.\n */\n+ (void) setUsesUntilPrompt:(NSInteger)value;\n\n/*!\n A significant event can be anything you want to be in your app. In a\n telephone app, a significant event might be placing or receiving a call.\n In a game, it might be beating a level or a boss. This is just another\n layer of filtering that can be used to make sure that only the most\n loyal of your users are being prompted to rate you on the app store.\n If you leave this at a value of -1, then this won't be a criterion\n used for rating. To tell Appirater that the user has performed\n a significant event, call the method:\n [Appirater userDidSignificantEvent:];\n */\n+ (void) setSignificantEventsUntilPrompt:(NSInteger)value;\n\n\n/*!\n Once the rating alert is presented to the user, they might select\n 'Remind me later'. This value specifies how long (in days) Appirater\n will wait before reminding them.\n */\n+ (void) setTimeBeforeReminding:(double)value;\n\n/*!\n Set customized title for alert view.\n */\n+ (void) setCustomAlertTitle:(NSString *)title;\n\n/*!\n Set customized message for alert view.\n */\n+ (void) setCustomAlertMessage:(NSString *)message;\n\n/*!\n Set customized cancel button title for alert view.\n */\n+ (void) setCustomAlertCancelButtonTitle:(NSString *)cancelTitle;\n\n/*!\n Set customized rate button title for alert view.\n */\n+ (void) setCustomAlertRateButtonTitle:(NSString *)rateTitle;\n\n/*!\n Set customized rate later button title for alert view.\n */\n+ (void) setCustomAlertRateLaterButtonTitle:(NSString *)rateLaterTitle;\n\n/*!\n 'YES' will show the Appirater alert everytime. Useful for testing how your message\n looks and making sure the link to your app's review page works.\n */\n+ (void) setDebug:(BOOL)debug;\n\n/*!\n Set the delegate if you want to know when Appirater does something\n */\n+ (void)setDelegate:(id<AppiraterDelegate>)delegate;\n\n/*!\n Set whether or not Appirater uses animation (currently respected when pushing modal StoreKit rating VCs).\n */\n+ (void)setUsesAnimation:(BOOL)animation;\n\n/*!\n If set to YES, Appirater will open App Store link (instead of SKStoreProductViewController on iOS 6). Default YES.\n */\n+ (void)setOpenInAppStore:(BOOL)openInAppStore;\n\n/*!\n If set to YES, the main bundle will always be used to load localized strings.\n Set this to YES if you have provided your own custom localizations in AppiraterLocalizable.strings\n in your main bundle.  Default is NO.\n */\n+ (void)setAlwaysUseMainBundle:(BOOL)useMainBundle;\n\n@end\n\n\n/*!\n Methods in this interface are public out of necessity, but may change without notice\n */\n@interface Appirater(Unsafe)\n\n/*!\n The bundle localized strings will be loaded from.\n*/\n+(NSBundle *)bundle;\n\n@end\n\n@interface Appirater(Deprecated)\n\n/*!\n DEPRECATED: While still functional, it's better to use\n appLaunched:(BOOL)canPromptForRating instead.\n \n Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.\n */\n+ (void)appLaunched __attribute__((deprecated)); \n\n/*!\n DEPRECATED: While still functional, it's better to use\n tryToShowPrompt instead.\n \n Calls [Appirater tryToShowPrompt]. See tryToShowPrompt for details of functionality.\n */\n+ (void)showPrompt __attribute__((deprecated));\n\n@end\n"
  },
  {
    "path": "Pods/Appirater/Appirater.m",
    "content": "/*\n This file is part of Appirater.\n \n Copyright (c) 2012, Arash Payan\n All rights reserved.\n \n Permission is hereby granted, free of charge, to any person\n obtaining a copy of this software and associated documentation\n files (the \"Software\"), to deal in the Software without\n restriction, including without limitation the rights to use,\n copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following\n conditions:\n \n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.\n */\n/*\n * Appirater.m\n * appirater\n *\n * Created by Arash Payan on 9/5/09.\n * http://arashpayan.com\n * Copyright 2012 Arash Payan. All rights reserved.\n */\n\n#import <SystemConfiguration/SystemConfiguration.h>\n#import <CFNetwork/CFNetwork.h>\n#import \"Appirater.h\"\n#include <netinet/in.h>\n\n#if ! __has_feature(objc_arc)\n#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).\n#endif\n\nNSString *const kAppiraterFirstUseDate\t\t\t\t= @\"kAppiraterFirstUseDate\";\nNSString *const kAppiraterUseCount\t\t\t\t\t= @\"kAppiraterUseCount\";\nNSString *const kAppiraterSignificantEventCount\t\t= @\"kAppiraterSignificantEventCount\";\nNSString *const kAppiraterCurrentVersion\t\t\t= @\"kAppiraterCurrentVersion\";\nNSString *const kAppiraterRatedCurrentVersion\t\t= @\"kAppiraterRatedCurrentVersion\";\nNSString *const kAppiraterDeclinedToRate\t\t\t= @\"kAppiraterDeclinedToRate\";\nNSString *const kAppiraterReminderRequestDate\t\t= @\"kAppiraterReminderRequestDate\";\n\nNSString *templateReviewURL = @\"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID\";\nNSString *templateReviewURLiOS7 = @\"itms-apps://itunes.apple.com/app/idAPP_ID\";\nNSString *templateReviewURLiOS8 = @\"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software\";\n\nstatic NSString *_appId;\nstatic double _daysUntilPrompt = 30;\nstatic NSInteger _usesUntilPrompt = 20;\nstatic NSInteger _significantEventsUntilPrompt = -1;\nstatic double _timeBeforeReminding = 1;\nstatic BOOL _debug = NO;\nstatic BOOL _usesAnimation = TRUE;\nstatic UIStatusBarStyle _statusBarStyle;\nstatic BOOL _modalOpen = false;\nstatic BOOL _alwaysUseMainBundle = NO;\n\n@interface Appirater ()\n@property (nonatomic, copy) NSString *alertTitle;\n@property (nonatomic, copy) NSString *alertMessage;\n@property (nonatomic, copy) NSString *alertCancelTitle;\n@property (nonatomic, copy) NSString *alertRateTitle;\n@property (nonatomic, copy) NSString *alertRateLaterTitle;\n@property (nonatomic, strong) NSOperationQueue *eventQueue;\n- (BOOL)connectedToNetwork;\n+ (Appirater*)sharedInstance;\n- (void)showPromptWithChecks:(BOOL)withChecks\n      displayRateLaterButton:(BOOL)displayRateLaterButton;\n- (void)showRatingAlert:(BOOL)displayRateLaterButton;\n- (void)showRatingAlert;\n- (BOOL)ratingAlertIsAppropriate;\n- (BOOL)ratingConditionsHaveBeenMet;\n- (void)incrementUseCount;\n- (void)hideRatingAlert;\n@end\n\n@implementation Appirater\n\n+ (void) setAppId:(NSString *)appId {\n    _appId = appId;\n}\n\n+ (void) setDaysUntilPrompt:(double)value {\n    _daysUntilPrompt = value;\n}\n\n+ (void) setUsesUntilPrompt:(NSInteger)value {\n    _usesUntilPrompt = value;\n}\n\n+ (void) setSignificantEventsUntilPrompt:(NSInteger)value {\n    _significantEventsUntilPrompt = value;\n}\n\n+ (void) setTimeBeforeReminding:(double)value {\n    _timeBeforeReminding = value;\n}\n\n+ (void) setCustomAlertTitle:(NSString *)title\n{\n    [self sharedInstance].alertTitle = title;\n}\n\n+ (void) setCustomAlertMessage:(NSString *)message\n{\n    [self sharedInstance].alertMessage = message;\n}\n\n+ (void) setCustomAlertCancelButtonTitle:(NSString *)cancelTitle\n{\n    [self sharedInstance].alertCancelTitle = cancelTitle;\n}\n\n+ (void) setCustomAlertRateButtonTitle:(NSString *)rateTitle\n{\n    [self sharedInstance].alertRateTitle = rateTitle;\n}\n\n+ (void) setCustomAlertRateLaterButtonTitle:(NSString *)rateLaterTitle\n{\n    [self sharedInstance].alertRateLaterTitle = rateLaterTitle;\n}\n\n+ (void) setDebug:(BOOL)debug {\n    _debug = debug;\n}\n+ (void)setDelegate:(id<AppiraterDelegate>)delegate{\n\tAppirater.sharedInstance.delegate = delegate;\n}\n+ (void)setUsesAnimation:(BOOL)animation {\n\t_usesAnimation = animation;\n}\n+ (void)setOpenInAppStore:(BOOL)openInAppStore {\n    [Appirater sharedInstance].openInAppStore = openInAppStore;\n}\n+ (void)setStatusBarStyle:(UIStatusBarStyle)style {\n\t_statusBarStyle = style;\n}\n+ (void)setModalOpen:(BOOL)open {\n\t_modalOpen = open;\n}\n+ (void)setAlwaysUseMainBundle:(BOOL)alwaysUseMainBundle {\n    _alwaysUseMainBundle = alwaysUseMainBundle;\n}\n\n+ (NSBundle *)bundle\n{\n    NSBundle *bundle;\n\n    if (_alwaysUseMainBundle) {\n        bundle = [NSBundle mainBundle];\n    } else {\n        NSURL *appiraterBundleURL = [[NSBundle mainBundle] URLForResource:@\"Appirater\" withExtension:@\"bundle\"];\n\n        if (appiraterBundleURL) {\n            // Appirater.bundle will likely only exist when used via CocoaPods\n            bundle = [NSBundle bundleWithURL:appiraterBundleURL];\n        } else {\n            bundle = [NSBundle mainBundle];\n        }\n    }\n\n    return bundle;\n}\n\n- (NSString *)alertTitle\n{\n    return _alertTitle ? _alertTitle : APPIRATER_MESSAGE_TITLE;\n}\n\n- (NSString *)alertMessage\n{\n    return _alertMessage ? _alertMessage : APPIRATER_MESSAGE;\n}\n\n- (NSString *)alertCancelTitle\n{\n    return _alertCancelTitle ? _alertCancelTitle : APPIRATER_CANCEL_BUTTON;\n}\n\n- (NSString *)alertRateTitle\n{\n    return _alertRateTitle ? _alertRateTitle : APPIRATER_RATE_BUTTON;\n}\n\n- (NSString *)alertRateLaterTitle\n{\n    return _alertRateLaterTitle ? _alertRateLaterTitle : APPIRATER_RATE_LATER;\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)init {\n    self = [super init];\n    if (self) {\n        if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {\n            self.openInAppStore = YES;\n        } else {\n            self.openInAppStore = NO;\n        }\n    }\n    \n    return self;\n}\n\n- (BOOL)connectedToNetwork {\n    // Create zero addy\n    struct sockaddr_in zeroAddress;\n    bzero(&zeroAddress, sizeof(zeroAddress));\n    zeroAddress.sin_len = sizeof(zeroAddress);\n    zeroAddress.sin_family = AF_INET;\n\t\n    // Recover reachability flags\n    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);\n    SCNetworkReachabilityFlags flags;\n\t\n    Boolean didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);\n    CFRelease(defaultRouteReachability);\n\t\n    if (!didRetrieveFlags)\n    {\n        NSLog(@\"Error. Could not recover network reachability flags\");\n        return NO;\n    }\n\t\n    BOOL isReachable = flags & kSCNetworkFlagsReachable;\n    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;\n\tBOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;\n\t\n\tNSURL *testURL = [NSURL URLWithString:@\"http://www.apple.com/\"];\n\t\n    NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];\n    sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;\n    sessionConfiguration.timeoutIntervalForRequest = 20.0;\n\n    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];\n\n    NSURLSessionTask *task = [session dataTaskWithURL:testURL];\n    [task resume];\n    \n    return ((isReachable && !needsConnection) || nonWiFi) ? ( (task.state != NSURLSessionTaskStateSuspended) ? YES : NO ) : NO;\n}\n\n+ (Appirater*)sharedInstance {\n\tstatic Appirater *appirater = nil;\n\tif (appirater == nil)\n\t{\n        static dispatch_once_t onceToken;\n        dispatch_once(&onceToken, ^{\n            appirater = [[Appirater alloc] init];\n            appirater.eventQueue = [[NSOperationQueue alloc] init];\n            appirater.eventQueue.maxConcurrentOperationCount = 1;\n            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:\n                UIApplicationWillResignActiveNotification object:nil];\n        });\n\t}\n\t\n\treturn appirater;\n}\n\n- (void)showRatingAlert:(BOOL)displayRateLaterButton {\n  id <AppiraterDelegate> delegate = _delegate;\n    \n  if(delegate && [delegate respondsToSelector:@selector(appiraterShouldDisplayAlert:)] && ![delegate appiraterShouldDisplayAlert:self]) {\n      return;\n  }\n  \n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n    if (NSStringFromClass([SKStoreReviewController class]) != nil) {\n#pragma clang diagnostic pop\n        [Appirater rateApp];\n    } else {\n        // Otherwise show a custom Alert\n        NSMutableArray *buttons = [[NSMutableArray alloc] initWithObjects:self.alertRateTitle, nil];\n        if (displayRateLaterButton) {\n            [buttons addObject:self.alertRateLaterTitle];\n        }\n        if (NSStringFromClass([UIAlertController class]) != nil) {\n            [buttons addObject:self.alertCancelTitle];\n            \n            UIAlertController *alert = [UIAlertController alertControllerWithTitle:self.alertTitle message:self.alertMessage preferredStyle:UIAlertControllerStyleAlert];\n            for (NSInteger i = 0; i < buttons.count; i++) {\n                UIAlertActionStyle style = i == buttons.count - 1 ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;\n                [alert addAction:[UIAlertAction actionWithTitle:buttons[i] style:style handler:^(UIAlertAction * _Nonnull action) {\n                    NSString *title = action.title;\n                    NSInteger buttonIndex = -1;\n                    if ([title isEqual:self.alertCancelTitle]) {\n                        buttonIndex = 0;\n                    } else if ([title isEqual:self.alertRateTitle]) {\n                        buttonIndex = 1;\n                    } else if ([title isEqual:self.alertRateLaterTitle]) {\n                        buttonIndex = 2;\n                    }\n                    \n                    [self alertViewDidDismissWithButtonIndex:buttonIndex];\n                }]];\n            }\n            [[Appirater getRootViewController] presentViewController:alert animated:YES completion:nil];\n            self.ratingAlert = alert;\n        } else {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle\n                                                                message:self.alertMessage\n                                                               delegate:self\n                                                      cancelButtonTitle:self.alertCancelTitle\n                                                      otherButtonTitles:nil];\n            for (NSString *button in buttons) {\n                [alertView addButtonWithTitle:button];\n            }\n            self.ratingAlert = alertView;\n            [alertView show];\n#pragma clang diagnostic pop\n        }\n    }\n\n  if (delegate && [delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]) {\n           [delegate appiraterDidDisplayAlert:self];\n  }\n}\n\n- (void)showRatingAlert\n{\n  [self showRatingAlert:true];\n}\n\n// is this an ok time to show the alert? (regardless of whether the rating conditions have been met)\n//\n// things checked here:\n// * connectivity with network\n// * whether user has rated before\n// * whether user has declined to rate\n// * whether rating alert is currently showing visibly\n// things NOT checked here:\n// * time since first launch\n// * number of uses of app\n// * number of significant events\n// * time since last reminder\n- (BOOL)ratingAlertIsAppropriate {\n    return ([self connectedToNetwork]\n            && ![self userHasDeclinedToRate]\n            && ![self isRatingAlertVisible]\n            && ![self userHasRatedCurrentVersion]);\n}\n\n// have the rating conditions been met/earned? (regardless of whether this would be a moment when it's appropriate to show a new rating alert)\n//\n// things checked here:\n// * time since first launch\n// * number of uses of app\n// * number of significant events\n// * time since last reminder\n// things NOT checked here:\n// * connectivity with network\n// * whether user has rated before\n// * whether user has declined to rate\n// * whether rating alert is currently showing visibly\n- (BOOL)ratingConditionsHaveBeenMet {\n\tif (_debug)\n\t\treturn YES;\n\t\n\tNSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n\t\n\tNSDate *dateOfFirstLaunch = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterFirstUseDate]];\n\tNSTimeInterval timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];\n\tNSTimeInterval timeUntilRate = 60 * 60 * 24 * _daysUntilPrompt;\n\tif (timeSinceFirstLaunch < timeUntilRate)\n\t\treturn NO;\n\t\n\t// check if the app has been used enough\n\tNSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount];\n\tif (useCount < _usesUntilPrompt)\n\t\treturn NO;\n\t\n\t// check if the user has done enough significant events\n\tNSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];\n\tif (sigEventCount < _significantEventsUntilPrompt)\n\t\treturn NO;\n\t\n\t// if the user wanted to be reminded later, has enough time passed?\n\tNSDate *reminderRequestDate = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterReminderRequestDate]];\n\tNSTimeInterval timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];\n\tNSTimeInterval timeUntilReminder = 60 * 60 * 24 * _timeBeforeReminding;\n\tif (timeSinceReminderRequest < timeUntilReminder)\n\t\treturn NO;\n\t\n\treturn YES;\n}\n\n- (void)incrementUseCount {\n\t// get the app's version\n\tNSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];\n\t\n\t// get the version number that we've been tracking\n\tNSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n\tNSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];\n\tif (trackingVersion == nil)\n\t{\n\t\ttrackingVersion = version;\n\t\t[userDefaults setObject:version forKey:kAppiraterCurrentVersion];\n\t}\n\t\n\tif (_debug)\n\t\tNSLog(@\"APPIRATER Tracking version: %@\", trackingVersion);\n\t\n\tif ([trackingVersion isEqualToString:version])\n\t{\n\t\t// check if the first use date has been set. if not, set it.\n\t\tNSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];\n\t\tif (timeInterval == 0)\n\t\t{\n\t\t\ttimeInterval = [[NSDate date] timeIntervalSince1970];\n\t\t\t[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];\n\t\t}\n\t\t\n\t\t// increment the use count\n\t\tNSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount];\n\t\tuseCount++;\n\t\t[userDefaults setInteger:useCount forKey:kAppiraterUseCount];\n\t\tif (_debug)\n\t\t\tNSLog(@\"APPIRATER Use count: %@\", @(useCount));\n\t}\n\telse\n\t{\n\t\t// it's a new version of the app, so restart tracking\n\t\t[userDefaults setObject:version forKey:kAppiraterCurrentVersion];\n\t\t[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterFirstUseDate];\n\t\t[userDefaults setInteger:1 forKey:kAppiraterUseCount];\n\t\t[userDefaults setInteger:0 forKey:kAppiraterSignificantEventCount];\n\t\t[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];\n\t\t[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];\n\t\t[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];\n\t}\n\t\n\t[userDefaults synchronize];\n}\n\n- (void)incrementSignificantEventCount {\n\t// get the app's version\n\tNSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];\n\t\n\t// get the version number that we've been tracking\n\tNSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n\tNSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];\n\tif (trackingVersion == nil)\n\t{\n\t\ttrackingVersion = version;\n\t\t[userDefaults setObject:version forKey:kAppiraterCurrentVersion];\n\t}\n\t\n\tif (_debug)\n\t\tNSLog(@\"APPIRATER Tracking version: %@\", trackingVersion);\n\t\n\tif ([trackingVersion isEqualToString:version])\n\t{\n\t\t// check if the first use date has been set. if not, set it.\n\t\tNSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];\n\t\tif (timeInterval == 0)\n\t\t{\n\t\t\ttimeInterval = [[NSDate date] timeIntervalSince1970];\n\t\t\t[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];\n\t\t}\n\t\t\n\t\t// increment the significant event count\n\t\tNSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];\n\t\tsigEventCount++;\n\t\t[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];\n\t\tif (_debug)\n\t\t\tNSLog(@\"APPIRATER Significant event count: %@\", @(sigEventCount));\n\t}\n\telse\n\t{\n\t\t// it's a new version of the app, so restart tracking\n\t\t[userDefaults setObject:version forKey:kAppiraterCurrentVersion];\n\t\t[userDefaults setDouble:0 forKey:kAppiraterFirstUseDate];\n\t\t[userDefaults setInteger:0 forKey:kAppiraterUseCount];\n\t\t[userDefaults setInteger:1 forKey:kAppiraterSignificantEventCount];\n\t\t[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];\n\t\t[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];\n\t\t[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];\n\t}\n\t\n\t[userDefaults synchronize];\n}\n\n- (void)incrementAndRate:(BOOL)canPromptForRating {\n\t[self incrementUseCount];\n\t\n\tif (canPromptForRating &&\n        [self ratingConditionsHaveBeenMet] &&\n        [self ratingAlertIsAppropriate])\n\t{\n        dispatch_async(dispatch_get_main_queue(),\n                       ^{\n                           [self showRatingAlert];\n                       });\n\t}\n}\n\n- (void)incrementSignificantEventAndRate:(BOOL)canPromptForRating {\n\t[self incrementSignificantEventCount];\n\t\n    if (canPromptForRating &&\n        [self ratingConditionsHaveBeenMet] &&\n        [self ratingAlertIsAppropriate])\n\t{\n        dispatch_async(dispatch_get_main_queue(),\n                       ^{\n                           [self showRatingAlert];\n                       });\n\t}\n}\n\n- (BOOL)userHasDeclinedToRate {\n    return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterDeclinedToRate];\n}\n\n- (BOOL)userHasRatedCurrentVersion {\n    return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterRatedCurrentVersion];\n}\n\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wdeprecated-implementations\"\n+ (void)appLaunched {\n\t[Appirater appLaunched:YES];\n}\n#pragma GCC diagnostic pop\n\n+ (void)appLaunched:(BOOL)canPromptForRating {\n    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),\n                   ^{\n                       Appirater *a = [Appirater sharedInstance];\n                       if (_debug) {\n                           dispatch_async(dispatch_get_main_queue(),\n                                          ^{\n                                              [a showRatingAlert];\n                                          });\n                       } else {\n                           [a incrementAndRate:canPromptForRating]; \n                       }\n                   });\n}\n\n- (BOOL)isRatingAlertVisible {\n    if (NSStringFromClass([UIAlertController class]) != nil) {\n        return ((UIAlertController *)self.ratingAlert).view.superview != nil;\n    } else {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n        return ((UIAlertView *)self.ratingAlert).visible;\n#pragma clang diagnostic pop\n    }\n}\n\n- (void)hideRatingAlert {\n\tif ([self isRatingAlertVisible]) {\n        if (_debug) {\n\t\t\tNSLog(@\"APPIRATER Hiding Alert\");\n        }\n        if ([self.ratingAlert respondsToSelector:@selector(dismissWithClickedButtonIndex:animated:)]) {\n            [self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];\n        } else {\n            [self.ratingAlert dismissViewControllerAnimated:NO completion:nil];\n        }\n\t}\t\n}\n\n+ (void)appWillResignActive {\n\tif (_debug)\n\t\tNSLog(@\"APPIRATER appWillResignActive\");\n\t[[Appirater sharedInstance] hideRatingAlert];\n}\n\n+ (void)appEnteredForeground:(BOOL)canPromptForRating {\n    Appirater *a = [Appirater sharedInstance];\n    [a.eventQueue addOperationWithBlock:^{\n        [[Appirater sharedInstance] incrementAndRate:canPromptForRating];\n    }];\n}\n\n+ (void)userDidSignificantEvent:(BOOL)canPromptForRating {\n    Appirater *a = [Appirater sharedInstance];\n    [a.eventQueue addOperationWithBlock:^{\n       [[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating];\n    }];\n}\n\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wdeprecated-implementations\"\n+ (void)showPrompt {\n  [Appirater tryToShowPrompt];\n}\n#pragma GCC diagnostic pop\n\n+ (void)tryToShowPrompt {\n  [[Appirater sharedInstance] showPromptWithChecks:true\n                            displayRateLaterButton:true];\n}\n\n+ (void)forceShowPrompt:(BOOL)displayRateLaterButton {\n  [[Appirater sharedInstance] showPromptWithChecks:false\n                            displayRateLaterButton:displayRateLaterButton];\n}\n\n- (void)showPromptWithChecks:(BOOL)withChecks\n      displayRateLaterButton:(BOOL)displayRateLaterButton {\n  if (withChecks == NO || [self ratingAlertIsAppropriate]) {\n    [self showRatingAlert:displayRateLaterButton];\n  }\n}\n\n+ (id)getRootViewController {\n    UIWindow *window = [[UIApplication sharedApplication] keyWindow];\n    if (window.windowLevel != UIWindowLevelNormal) {\n        NSArray *windows = [[UIApplication sharedApplication] windows];\n        for(window in windows) {\n            if (window.windowLevel == UIWindowLevelNormal) {\n                break;\n            }\n        }\n    }\n    \n    return [Appirater iterateSubViewsForViewController:window]; // iOS 8+ deep traverse\n}\n\n+ (id)iterateSubViewsForViewController:(UIView *) parentView {\n    for (UIView *subView in [parentView subviews]) {\n        UIResponder *responder = [subView nextResponder];\n        if([responder isKindOfClass:[UIViewController class]]) {\n            return [self topMostViewController: (UIViewController *) responder];\n        }\n        id found = [Appirater iterateSubViewsForViewController:subView];\n        if( nil != found) {\n            return found;\n        }\n    }\n    return nil;\n}\n\n+ (UIViewController *) topMostViewController: (UIViewController *) controller {\n\tBOOL isPresenting = NO;\n\tdo {\n\t\t// this path is called only on iOS 6+, so -presentedViewController is fine here.\n\t\tUIViewController *presented = [controller presentedViewController];\n\t\tisPresenting = presented != nil;\n\t\tif(presented != nil) {\n\t\t\tcontroller = presented;\n\t\t}\n\t\t\n\t} while (isPresenting);\n\t\n\treturn controller;\n}\n\n+ (void)rateApp {\n    \n    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n    [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];\n    [userDefaults synchronize];\n\t\n    // Use the built SKStoreReviewController if available (available from iOS 10.3 upwards)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n    if (NSStringFromClass([SKStoreReviewController class]) != nil) {\n        [SKStoreReviewController requestReview];\n#pragma clang diagnostic pop\n        return;\n    }\n\n\t//Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator.\n\tif (![Appirater sharedInstance].openInAppStore && NSStringFromClass([SKStoreProductViewController class]) != nil) {\n\t\t\n\t\tSKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];\n\t\tNSNumber *appId = [NSNumber numberWithInteger:_appId.integerValue];\n\t\t[storeViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier:appId} completionBlock:nil];\n\t\tstoreViewController.delegate = self.sharedInstance;\n        \n        id <AppiraterDelegate> delegate = self.sharedInstance.delegate;\n\t\tif ([delegate respondsToSelector:@selector(appiraterWillPresentModalView:animated:)]) {\n\t\t\t[delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation];\n\t\t}\n\t\t[[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{\n\t\t\t[self setModalOpen:YES];\n\t\t}];\n\t\n\t//Use the standard openUrl method if StoreKit is unavailable.\n\t} else {\n\t\t\n\t\t#if TARGET_IPHONE_SIMULATOR\n\t\tNSLog(@\"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.\");\n\t\t#else\n\t\tNSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@\"APP_ID\" withString:_appId];\n\n\t\t// iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131\n        // Fixes condition @see https://github.com/arashpayan/appirater/issues/205\n\t\tif ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {\n\t\t\treviewURL = [templateReviewURLiOS7 stringByReplacingOccurrencesOfString:@\"APP_ID\" withString:_appId];\n\t\t}\n        // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182\n        else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)\n        {\n            reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@\"APP_ID\" withString:_appId];\n        }\n\n\t\t[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];\n\t\t#endif\n\t}\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {\n    [self alertViewDidDismissWithButtonIndex:buttonIndex];\n}\n#pragma clang diagnostic pop\n\n- (void)alertViewDidDismissWithButtonIndex:(NSInteger)buttonIndex {\n    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n    \n    id <AppiraterDelegate> delegate = _delegate;\n    \n    switch (buttonIndex) {\n        case 0:\n        {\n            // they don't want to rate it\n            [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];\n            [userDefaults synchronize];\n            if(delegate && [delegate respondsToSelector:@selector(appiraterDidDeclineToRate:)]){\n                [delegate appiraterDidDeclineToRate:self];\n            }\n            break;\n        }\n        case 1:\n        {\n            // they want to rate it\n            [Appirater rateApp];\n            if(delegate&& [delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){\n                [delegate appiraterDidOptToRate:self];\n            }\n            break;\n        }\n        case 2:\n            // remind them later\n            [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate];\n            [userDefaults synchronize];\n            if(delegate && [delegate respondsToSelector:@selector(appiraterDidOptToRemindLater:)]){\n                [delegate appiraterDidOptToRemindLater:self];\n            }\n            break;\n        default:\n            break;\n    }\n    \n    self.ratingAlert = nil;\n}\n\n//Delegate call from the StoreKit view.\n- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {\n\t[Appirater closeModal];\n}\n\n//Close the in-app rating (StoreKit) view and restore the previous status bar style.\n+ (void)closeModal {\n\tif (_modalOpen) {\n\t\tBOOL usedAnimation = _usesAnimation;\n\t\t[self setModalOpen:NO];\n\t\t\n\t\t// get the top most controller (= the StoreKit Controller) and dismiss it\n\t\tUIViewController *presentingController = [UIApplication sharedApplication].keyWindow.rootViewController;\n\t\tpresentingController = [self topMostViewController: presentingController];\n\t\t[presentingController dismissViewControllerAnimated:_usesAnimation completion:^{\n            id <AppiraterDelegate> delegate = self.sharedInstance.delegate;\n\t\t\tif ([delegate respondsToSelector:@selector(appiraterDidDismissModalView:animated:)]) {\n\t\t\t\t[delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation];\n\t\t\t}\n\t\t}];\n\t\t[self.class setStatusBarStyle:(UIStatusBarStyle)nil];\n\t}\n}\n\n@end\n"
  },
  {
    "path": "Pods/Appirater/AppiraterDelegate.h",
    "content": "//\n//  AppiraterDelegate.h\n//  Banana Stand\n//\n//  Created by Robert Haining on 9/25/12.\n//  Copyright (c) 2012 News.me. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@class Appirater;\n\n@protocol AppiraterDelegate <NSObject>\n\n@optional\n-(BOOL)appiraterShouldDisplayAlert:(Appirater *)appirater;\n-(void)appiraterDidDisplayAlert:(Appirater *)appirater;\n-(void)appiraterDidDeclineToRate:(Appirater *)appirater;\n-(void)appiraterDidOptToRate:(Appirater *)appirater;\n-(void)appiraterDidOptToRemindLater:(Appirater *)appirater;\n-(void)appiraterWillPresentModalView:(Appirater *)appirater animated:(BOOL)animated;\n-(void)appiraterDidDismissModalView:(Appirater *)appirater animated:(BOOL)animated;\n@end\n"
  },
  {
    "path": "Pods/Appirater/README.md",
    "content": "Introduction\n---------------\n\nAppirater is a class that you can drop into any iPhone app (iOS 4.0 or later) that will help remind your users to review your app on the App Store. The code is released under the MIT/X11, so feel free to modify and share your changes with the world. Read on below for how to get started. If you need any help using, the library, post your questions on [Stack Overflow] [stackoverflow] under the `appirater` tag.\n\nGetting Started\n---------------\n\n### CocoaPods\nTo add Appirater to your app, add `pod \"Appirater\"` to your Podfile.\n\nConfiguration\n-------------\n1. Appirater provides class methods to configure its behavior. See [`Appirater.h`] [Appirater.h] for more information.\n\n```objc\n[Appirater setAppId:@\"552035781\"];\n[Appirater setDaysUntilPrompt:1];\n[Appirater setUsesUntilPrompt:10];\n[Appirater setSignificantEventsUntilPrompt:-1];\n[Appirater setTimeBeforeReminding:2];\n[Appirater setDebug:YES];\n```\n\n2. Call `[Appirater setAppId:@\"yourAppId\"]` with the app id provided by Apple. A good place to do this is at the beginning of your app delegate's `application:didFinishLaunchingWithOptions:` method.\n3. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.\n4. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method.\n5. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app.\n\n### Development\nSetting `[Appirater setDebug:YES]` will ensure that the rating request is shown each time the app is launched.\n\n### Production\nMake sure you set `[Appirater setDebug:NO]` to ensure the request is not shown every time the app is launched. Also make sure that each of these components are set in the `application:didFinishLaunchingWithOptions:` method.\n\nThis example states that the rating request is only shown when the app has been launched 5 times **and** after 7 days.\n\n```objc\n[Appirater setAppId:@\"770699556\"];\n[Appirater setDaysUntilPrompt:7];\n[Appirater setUsesUntilPrompt:5];\n[Appirater setSignificantEventsUntilPrompt:-1];\n[Appirater setTimeBeforeReminding:2];\n[Appirater setDebug:NO];\n[Appirater appLaunched:YES];\n```\n\nIf you wanted to show the request after 5 days only you can set the following:\n\n```objc\n[Appirater setAppId:@\"770699556\"];\n[Appirater setDaysUntilPrompt:5];\n[Appirater setUsesUntilPrompt:0];\n[Appirater setSignificantEventsUntilPrompt:-1];\n[Appirater setTimeBeforeReminding:2];\n[Appirater setDebug:NO];\n[Appirater appLaunched:YES];\n```\n\nSKStoreReviewController\n----------------------\nIn iOS 10.3, [SKStoreReviewController](https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS10_3.html) was introduced which allows rating directly within the app without any additional setup.\n\nAppirater automatically uses `SKStoreReviewController` if available. You'll need to manually link `StoreKit` in your App however.\n\nIf `SKStoreReviewController` is used, Appirater is used only to decide when to show the rating dialog to the user. Keep in mind, that `SKStoreReviewController` automatically limits the number of impressions, so the dialog might be displayed less frequently than your configured conditions might suggest.\n\nLicense\n-------\nCopyright 2017. [Arash Payan] [arash].\nThis library is distributed under the terms of the MIT/X11.\n\nWhile not required, I greatly encourage and appreciate any improvements that you make\nto this library be contributed back for the benefit of all who use Appirater.\n\nPorts for other SDKs\n--------------\nA few people have ported Appirater to other SDKs. The ports are listed here in hopes that they may assist developers of those SDKs. I don't know how closesly (if at all) they track the Objective-C version of Appirater. If you need support for any of the libraries, please contact the maintainer of the port.\n\n+ MonoTouch Binding (using native Appirater). [Github] [monotouchbinding]\n\n[stackoverflow]: http://stackoverflow.com/\n[homepage]: https://arashpayan.com/blog/2009/09/07/presenting-appirater/\n[arash]: https://arashpayan.com\n[Appirater.h]: https://github.com/arashpayan/appirater/blob/master/Appirater.h\n[monotouchbinding]: https://github.com/theonlylawislove/MonoTouch.Appirater\n"
  },
  {
    "path": "Pods/Appirater/ar.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"إذا كنت تستمع باستخدام %@، فهل تمانع بأن تأخذ دقيقة من وقتك لتقيمه؟ لن يستغرق الأمر أكثر من دقيقة. شكرا لدعمك!\";\n\"Rate %@\" = \"قيم %@\";\n\"No, Thanks\" = \"لا شكرا\";\n\"Remind me later\" = \"ذكرني لاحقا\";"
  },
  {
    "path": "Pods/Appirater/ca.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Si li agrada utilitzar %@, li importaria prendre’s un moment per a valorar-lo? No trigarà més d’un minut. Gràcies por la seva col·laboració!\";\n\"Rate %@\" = \"Valorar %@\";\n\"No, Thanks\" = \"No, gràcies\";\n\"Remind me later\" = \"Recordar-m’ho més tard\";"
  },
  {
    "path": "Pods/Appirater/cs.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Pokud se Vám aplikace %@ líbí, mohli byste ji prosím ohodnotit v App Store? Zabere to jen chvilku. Díky za Vaši podporu!\";\n\"Rate %@\" = \"Ohodnotit %@\";\n\"No, Thanks\" = \"Ne, díky\";\n\"Remind me later\" = \"Možná později\";"
  },
  {
    "path": "Pods/Appirater/da.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Hvis du synes om at bruge %@, vil du have noget imod at bruge et kort øjeblik på at bedømme det? Det tager kun et minut. Tak for din støtte!\";\n\"Rate %@\" = \"Bedøm %@\";\n\"No, Thanks\" = \"Nej tak\";\n\"Remind me later\" = \"Påmind mig senere\";\n"
  },
  {
    "path": "Pods/Appirater/de.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Sie nutzen %@ gerne? Dann nehmen Sie sich bitte für eine Bewertung einen Moment Zeit! Es dauert nicht länger als eine Minute. Vielen Dank!\";\n\"Rate %@\" = \"Bewerte %@\";\n\"No, Thanks\" = \"Nein, danke\";\n\"Remind me later\" = \"Später erinnern\";\n"
  },
  {
    "path": "Pods/Appirater/el.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Αν σου αρέσει το %@, θα μπορούσες να αφιερώσεις μια στιγμή για να το βαθμολογήσεις; Η διαδικασία είναι πολύ σύντομη. Ευχαριστούμε για τη στήριξη!\";\n\"Rate %@\" = \"Βαθμολόγηση του %@\";\n\"No, Thanks\" = \"Όχι, ευχαριστώ\";\n\"Remind me later\" = \"Υπενθύμιση αργότερα\";"
  },
  {
    "path": "Pods/Appirater/en.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\";\n\"Rate %@\" = \"Rate %@\";\n\"No, Thanks\" = \"No, thanks\";\n\"Remind me later\" = \"Remind me later\";"
  },
  {
    "path": "Pods/Appirater/es.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Si te ha gustado  %@, ¿te gustaría calificarnos? No te tomará más de un minuto. ¡Gracias por tu colaboración!\";\n\"Rate %@\" = \"Calificar %@\";\n\"No, Thanks\" = \"No, gracias\";\n\"Remind me later\" = \"Recuérdame más tarde\";\n"
  },
  {
    "path": "Pods/Appirater/fa.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"اگر از استفاده برنامه %@ لذت می‌برید، زمان دارید بهش امتیاز دهید؟  بیشتر از یک دقیقه زمان نخواهد گرفت. با تشکر از اینکه ما را همایت می‌کنید.\";\n\"Rate %@\" = \"ارزیابی کردن %@\";\n\"No, Thanks\" = \"نه، مرسی\";\n\"Remind me later\" = \"بعدا\";\n\n"
  },
  {
    "path": "Pods/Appirater/fi.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Jos käytät mielelläsi %@, voisitko käyttää hetken ja arvostella sen? Se ei kestä minuuttia kauempaa. Kiitos tuestasi!\";\n\"Rate %@\" = \"Arvioi %@\";\n\"No, Thanks\" = \"Ei kiitos\";\n\"Remind me later\" = \"Muistuta minua myöhemmin\";"
  },
  {
    "path": "Pods/Appirater/fr.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Si vous aimez %@, voulez-vous prendre un moment pour l'évaluer ? Cela ne vous prendra pas plus d'une minute. Merci de votre soutien !\";\n\"Rate %@\" = \"Évaluer %@\";\n\"No, Thanks\" = \"Non, merci\";\n\"Remind me later\" = \"Me rappeler plus tard\";\n"
  },
  {
    "path": "Pods/Appirater/he.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"אם נהנת להשתמש ב %@, האם תסכים לדרג אותה? זה לא יקח יותר מדקה. תודה על התמיכה!\";\n\"Rate %@\" = \"דרג את %@\";\n\"No, Thanks\" = \"לא תודה\";\n\"Remind me later\" = \"מאוחר יותר\";"
  },
  {
    "path": "Pods/Appirater/hu.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Ha tetszik a %@, ne felejtsd el értékelni az App Store-ban! Csak egy perc az egész. Köszönet a támogatásért!\";\n\"Rate %@\" = \"%@ értékelése\";\n\"No, Thanks\" = \"Most inkább nem\";\n\"Remind me later\" = \"Emlékeztess később\";\n"
  },
  {
    "path": "Pods/Appirater/hy.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Եթե Դուք հաճույքով եք օգտագործում %@-ը, դեմ չե՞ք լինի տրամադրել մեկ րոպե այն գնահատելու համար: Այն չի պահանջի ձեզանից ավելի քան մեկ րոպե: Շնորհակալություն աջակցության համար:\";\n\"Rate %@\" = \"Գնահատել %@-ը\";\n\"No, Thanks\" = \"Ոչ, շնորհակալություն\";\n\"Remind me later\" = \"Հիշեցնել ավելի ուշ\";\n"
  },
  {
    "path": "Pods/Appirater/id.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Jika anda menyukai %@, maukah anda memberikan rating kepada aplikasi ini? Rating hanya memakan waktu kurang dari 1 menit. Terimakasih untuk dukungan anda!\";\n\"Rate %@\" = \"Rating %@\";\n\"No, Thanks\" = \"Tidak, terimakasih\";\n\"Remind me later\" = \"Silakan ingatkan saya lagi\";"
  },
  {
    "path": "Pods/Appirater/it.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Se ti piace %@, perché non dedichi qualche istante a darne una valutazione sull'App Store? Non richiederà più di un minuto. Grazie per il supporto!\";\n\"Rate %@\" = \"Valuta %@\";\n\"No, Thanks\" = \"No, grazie\";\n\"Remind me later\" = \"Ricordamelo più tardi\";"
  },
  {
    "path": "Pods/Appirater/ja.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"%@をお使いいただきありがとうございます。もしよろしければ、ほんの少しだけお時間をいただき評価をお願いできませんか？ご協力感謝いたします！\";\n\"Rate %@\" = \"%@を評価する\";\n\"No, Thanks\" =\"結構です\";\n\"Remind me later\" = \"あとで\";\n"
  },
  {
    "path": "Pods/Appirater/ko.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"%@ 사용이 맘에 드셨나요? 잠시만 시간을 내서 평가를 부탁드리겠습니다. 감사합니다!\";\n\"Rate %@\" = \"%@ 평가하기\";\n\"No, Thanks\" = \"평가하지 않겠습니다\";\n\"Remind me later\" = \"다음에 평가하겠습니다\";"
  },
  {
    "path": "Pods/Appirater/ms.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Jika anda suka %@, bolehkah luangkan sedikit masa untuk beri penarafan? Tak sampai seminit pun. Terima kasih atas sokongan anda!\";\n\"Rate %@\" = \"Tarafkan %@\";\n\"No, Thanks\" = \"Terima kasih saja\";\n\"Remind me later\" = \"Ingatkan saya lain kali\";"
  },
  {
    "path": "Pods/Appirater/nb.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Hvis du liker å bruke %@, kan du ta deg et øyeblikk for å vurdere den? Det vil ikke ta mer enn ett minutt. Takk for din støtte!\";\n\"Rate %@\" = \"Vurder %@\";\n\"No, Thanks\" = \"Nei, takk\";\n\"Remind me later\" = \"Påminn meg senere\";"
  },
  {
    "path": "Pods/Appirater/nl.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Als het gebruik van %@ je bevalt, zou je dan een momentje de tijd willen nemen om het te beoordelen? Het duurt nog geen minuut. Bedankt voor je steun!\";\n\"Rate %@\" = \"%@ beoordelen\";\n\"No, Thanks\" = \"Nee, bedankt\";\n\"Remind me later\" = \"Herinner me er later aan\";\n"
  },
  {
    "path": "Pods/Appirater/pl.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Jeżeli podoba Ci się korzystanie z %@, może zechciałbyś poświęcić chwilę czasu, aby ocenić aplikację? Nie zajmie Ci to więcej niż minutę. Dziękujemy za pomoc!\";\r\n\"Rate %@\" = \"Oceń %@\";\r\n\"No, Thanks\" = \"Nie, dziękuję\";\r\n\"Remind me later\" = \"Przypomnij później\";"
  },
  {
    "path": "Pods/Appirater/pt-BR.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Se você gosta de usar o %@, que tal avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!\";\n\"Rate %@\" = \"Avaliar o %@\";\n\"No, Thanks\" = \"Não, obrigado\";\n\"Remind me later\" = \"Mais tarde\";\n"
  },
  {
    "path": "Pods/Appirater/pt.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Se você gosta de usar o %@, que tal avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!\";\n\"Rate %@\" = \"Avaliar o %@\";\n\"No, Thanks\" = \"Não, obrigado\";\n\"Remind me later\" = \"Mais tarde\";\n"
  },
  {
    "path": "Pods/Appirater/ro.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Dacă îți place %@, acordă-i o notă te rog, nu durează mult. Mulțumim pentru susținere!\";\n\"Rate %@\" = \"Acordă notă pentru %@\";\n\"No, Thanks\" = \"Nu, mulțumesc\";\n\"Remind me later\" = \"Adu-mi aminte mai târziu\";"
  },
  {
    "path": "Pods/Appirater/ru.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Если Вам нравится %@, пожалуйста, поставьте свою оценку. Это займет у Вас не больше одной минуты.\\n Спасибо за поддержку!\";\n\"Rate %@\" = \"Оценить %@\";\n\"No, Thanks\" = \"Нет, спасибо\";\n\"Remind me later\" = \"Напомнить позже\";\n"
  },
  {
    "path": "Pods/Appirater/sk.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Pokiaľ sa Vám páči aplikácia %@, mohli by ste ju prosím ohodnotiť v App Store? Zaberie to len chvíľu. Vďaka za Vašu podporu!\";\n\"Rate %@\" = \"Ohodnotiť %@\";\n\"No, Thanks\" = \"Nie, ďakujem\";\n\"Remind me later\" = \"Pripomenúť neskôr\";"
  },
  {
    "path": "Pods/Appirater/sv.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Om du gillar att använda %@, kan du tänka dig att betygsätta det åt oss? Det tar bara en minut. Tack för hjälpen!\";\n\"Rate %@\" = \"Betygsätt %@\";\n\"No, Thanks\" = \"Nej tack\";\n\"Remind me later\" = \"Påminn mig senare\";\n"
  },
  {
    "path": "Pods/Appirater/th.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"ถ้าคุณกำลังใช้ %@ โปรดสละเวลาสักครู่ในการให้อันดับแก่เรา คุณจะเสียเวลาไม่เกินหนึ่งนาที ขอบคุณสำหรับการสนับสนุน!\";\n\"Rate %@\" = \"ให้อันดับ %@\";\n\"No, Thanks\" = \"ไม่ ขอบคุณ\";\n\"Remind me later\" = \"เตือนฉันภายหลัง\";\n"
  },
  {
    "path": "Pods/Appirater/tr.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Eğer %@ uygulamasını kullanmaktan keyif alıyorsanız, onu değerlendirmek için zaman ayırabilir misiniz? Desteğiniz için teşekkür ederiz!\";\n\"Rate %@\" = \"%@ uygulamasını değerlendir\";\n\"No, Thanks\" = \"Hayır, teşekkürler\";\n\"Remind me later\" = \"Daha sonra hatırlat\";"
  },
  {
    "path": "Pods/Appirater/uk.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Якщо вам сподобалося %@, будь ласка, поставте свою оцінку. Це займає не більше однієї хвилини.\\n Дякуємо за підтримку!\";\n\"Rate %@\" = \"Оцінити %@\";\n\"No, Thanks\" = \"Ні, дякую\";\n\"Remind me later\" = \"Нагадати пізніше\";\n"
  },
  {
    "path": "Pods/Appirater/vi.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"Cảm ơn bạn đã sử dụng ứng dụng %@ trong thời gian qua, bạn có thể dành chút thời gian để đánh giá ứng dụng trong AppStore không?\";\n\"Rate %@\" = \"Đánh giá %@\";\n\"No, Thanks\" = \"Không, xin cảm ơn\";\n\"Remind me later\" = \"Hãy nhắc nhở tôi sau\";"
  },
  {
    "path": "Pods/Appirater/zh-Hans.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"如果你喜欢使用%@，你介意花一点时间给它评分吗？不会超过一分钟。感谢您的支持！\";\n\"Rate %@\" = \"给%@评分\";\n\"No, Thanks\" = \"不，谢谢\";\n\"Remind me later\" = \"稍后提醒我\";\n"
  },
  {
    "path": "Pods/Appirater/zh-Hant.lproj/AppiraterLocalizable.strings",
    "content": "\"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!\" = \"如果你喜歡使用%@，你介意花一點時間給它評分嗎？不會超過一分鐘。感謝您的支持！\";\n\"Rate %@\" = \"給%@評分\";\n\"No, Thanks\" = \"不，謝謝\";\n\"Remind me later\" = \"稍後提醒我\";\n"
  },
  {
    "path": "Pods/Firebase/CoreOnly/Sources/Firebase.h",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <FirebaseCore/FirebaseCore.h>\n\n#if !defined(__has_include)\n  #error \"Firebase.h won't import anything if your compiler doesn't support __has_include. Please \\\n          import the headers individually.\"\n#else\n  #if __has_include(<FirebaseAnalytics/FirebaseAnalytics.h>)\n    #import <FirebaseAnalytics/FirebaseAnalytics.h>\n  #endif\n\n  #if __has_include(<FirebaseAppCheck/FirebaseAppCheck.h>)\n    #import <FirebaseAppCheck/FirebaseAppCheck.h>\n  #endif\n\n  #if __has_include(<FirebaseAppDistribution/FirebaseAppDistribution.h>)\n    #import <FirebaseAppDistribution/FirebaseAppDistribution.h>\n  #endif\n\n  #if __has_include(<FirebaseAuth/FirebaseAuth.h>)\n    #import <FirebaseAuth/FirebaseAuth.h>\n  #endif\n\n  #if __has_include(<FirebaseCrashlytics/FirebaseCrashlytics.h>)\n    #import <FirebaseCrashlytics/FirebaseCrashlytics.h>\n  #endif\n\n  #if __has_include(<FirebaseDatabase/FirebaseDatabase.h>)\n    #import <FirebaseDatabase/FirebaseDatabase.h>\n  #endif\n\n  #if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>)\n    #import <FirebaseDynamicLinks/FirebaseDynamicLinks.h>\n  #endif\n\n  #if __has_include(<FirebaseFirestore/FirebaseFirestore.h>)\n    #import <FirebaseFirestore/FirebaseFirestore.h>\n  #endif\n\n  #if __has_include(<FirebaseFunctions/FirebaseFunctions.h>)\n    #import <FirebaseFunctions/FirebaseFunctions.h>\n  #endif\n\n  #if __has_include(<FirebaseInAppMessaging/FirebaseInAppMessaging.h>)\n    #import <FirebaseInAppMessaging/FirebaseInAppMessaging.h>\n  #endif\n\n  #if __has_include(<FirebaseInstallations/FirebaseInstallations.h>)\n    #import <FirebaseInstallations/FirebaseInstallations.h>\n  #endif\n\n  #if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)\n    #import <FirebaseMessaging/FirebaseMessaging.h>\n  #endif\n\n  #if __has_include(<FirebasePerformance/FirebasePerformance.h>)\n    #import <FirebasePerformance/FirebasePerformance.h>\n  #endif\n\n  #if __has_include(<FirebaseRemoteConfig/FirebaseRemoteConfig.h>)\n    #import <FirebaseRemoteConfig/FirebaseRemoteConfig.h>\n  #endif\n\n  #if __has_include(<FirebaseStorage/FirebaseStorage.h>)\n    #import <FirebaseStorage/FirebaseStorage.h>\n  #endif\n\n#endif  // defined(__has_include)\n"
  },
  {
    "path": "Pods/Firebase/CoreOnly/Sources/module.modulemap",
    "content": "module Firebase {\n  export *\n  header \"Firebase.h\"\n}"
  },
  {
    "path": "Pods/Firebase/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/Firebase/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![License](https://img.shields.io/cocoapods/l/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![Platform](https://img.shields.io/cocoapods/p/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n\n[![Actions Status][gh-abtesting-badge]][gh-actions]\n[![Actions Status][gh-appcheck-badge]][gh-actions]\n[![Actions Status][gh-appdistribution-badge]][gh-actions]\n[![Actions Status][gh-auth-badge]][gh-actions]\n[![Actions Status][gh-cocoapods-integration-badge]][gh-actions]\n[![Actions Status][gh-core-badge]][gh-actions]\n[![Actions Status][gh-core-diagnostics-badge]][gh-actions]\n[![Actions Status][gh-crashlytics-badge]][gh-actions]\n[![Actions Status][gh-database-badge]][gh-actions]\n[![Actions Status][gh-datatransport-badge]][gh-actions]\n[![Actions Status][gh-dynamiclinks-badge]][gh-actions]\n[![Actions Status][gh-firebasepod-badge]][gh-actions]\n[![Actions Status][gh-firestore-badge]][gh-actions]\n[![Actions Status][gh-functions-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-components-badge]][gh-actions]\n[![Actions Status][gh-inappmessaging-badge]][gh-actions]\n[![Actions Status][gh-interop-badge]][gh-actions]\n[![Actions Status][gh-messaging-badge]][gh-actions]\n[![Actions Status][gh-mlmodeldownloader-badge]][gh-actions]\n[![Actions Status][gh-performance-badge]][gh-actions]\n[![Actions Status][gh-remoteconfig-badge]][gh-actions]\n[![Actions Status][gh-storage-badge]][gh-actions]\n[![Actions Status][gh-symbolcollision-badge]][gh-actions]\n[![Actions Status][gh-zip-badge]][gh-actions]\n[![Travis](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)\n\n# Firebase Apple Open Source Development\n\nThis repository contains all Apple platform Firebase SDK source except FirebaseAnalytics\nand FirebaseML.\n\nFirebase is an app development platform with tools to help you build, grow and\nmonetize your app. More information about Firebase can be found on the\n[official Firebase website](https://firebase.google.com).\n\n**Note** _FirebaseCombineSwift_ contains support for Apple's Combine framework. This module is currently under development, and not yet supported for use in production environments. Fore more details, please refer to the [docs](FirebaseCombineSwift/README.md).\n\n## Installation\n\nSee the subsections below for details about the different installation methods.\n1. [Standard pod install](README.md#standard-pod-install)\n1. [Swift Package Manager](SwiftPackageManager.md)\n1. [Installing from the GitHub repo](README.md#installing-from-github)\n1. [Experimental Carthage](README.md#carthage-ios-only)\n\n### Standard pod install\n\nGo to\n[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).\n\n### Swift Package Manager\n\nInstructions for [Swift Package Manager](https://swift.org/package-manager/) support can be\nfound at [SwiftPackageManager.md](SwiftPackageManager.md).\n\n### Installing from GitHub\n\nThese instructions can be used to access the Firebase repo at other branches,\ntags, or commits.\n\n#### Background\n\nSee\n[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)\nfor instructions and options about overriding pod source locations.\n\n#### Accessing Firebase Source Snapshots\n\nAll of the official releases are tagged in this repo and available via CocoaPods. To access a local\nsource snapshot or unreleased branch, use Podfile directives like the following:\n\nTo access FirebaseFirestore via a branch:\n```ruby\npod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\npod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\n```\n\nTo access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:\n\n```ruby\npod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'\npod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'\n```\n\n### Carthage (iOS only)\n\nInstructions for the experimental Carthage distribution are at\n[Carthage](Carthage.md).\n\n### Using Firebase from a Framework or a library\n\n[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md)\n\n## Development\n\nTo develop Firebase software in this repository, ensure that you have at least\nthe following software:\n\n  * Xcode 12.2 (or later)\n\nCocoaPods is still the canonical way to develop, but much of the repo now supports\ndevelopment with Swift Package Manager.\n\n### CocoaPods\n\nInstall\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n```ruby\npod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios\n```\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\nFirestore has a self contained Xcode project. See\n[Firestore/README.md](Firestore/README.md).\n\n#### Development for Catalyst\n* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Swift Package Manager\n* To enable test schemes: `./scripts/setup_spm_tests.sh`\n* `open Package.swift` or double click `Package.swift` in Finder.\n* Xcode will open the project\n  * Choose a scheme for a library to build or test suite to run\n  * Choose a target platform by selecting the run destination along with the scheme\n\n### Adding a New Firebase Pod\n\nSee [AddNewPod.md](AddNewPod.md).\n\n### Managing Headers and Imports\n\nSee [HeadersImports.md](HeadersImports.md).\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n### Running Sample Apps\nIn order to run the sample apps and integration tests, you'll need a valid\n`GoogleService-Info.plist` file. The Firebase Xcode project contains dummy plist\nfiles without real values, but can be replaced with real plist files. To get your own\n`GoogleService-Info.plist` files:\n\n1. Go to the [Firebase Console](https://console.firebase.google.com/)\n2. Create a new Firebase project, if you don't already have one\n3. For each sample app you want to test, create a new Firebase app with the sample app's bundle\nidentifier (e.g. `com.google.Database-Example`)\n4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project.\n\n### Coverage Report Generation\n\nSee [scripts/code_coverage_report/README.md](scripts/code_coverage_report/README.md).\n\n## Specific Component Instructions\nSee the sections below for any special instructions for those components.\n\n### Firebase Auth\n\nIf you're doing specific Firebase Auth development, see\n[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about\nbuilding and running the FirebaseAuth pod along with various samples and tests.\n\n### Firebase Database\n\nThe Firebase Database Integration tests can be run against a locally running Database Emulator\nor against a production instance.\n\nTo run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before\nrunning the integration test.\n\nTo run against a production instance, provide a valid GoogleServices-Info.plist and copy it to\n`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to\n[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are\nrunning.\n\n### Firebase Performance Monitoring\nIf you're doing specific Firebase Performance Monitoring development, see\n[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK\nand [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about\nintegrating Performance with the dev test App.\n\n### Firebase Storage\n\nTo run the Storage Integration tests, follow the instructions in\n[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m).\n\n#### Push Notifications\n\nPush notifications can only be delivered to specially provisioned App IDs in the developer portal.\nIn order to actually test receiving push notifications, you will need to:\n\n1. Change the bundle identifier of the sample app to something you own in your Apple Developer\naccount, and enable that App ID for push notifications.\n2. You'll also need to\n[upload your APNs Provider Authentication Key or certificate to the\nFirebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)\nat **Project Settings > Cloud Messaging > [Your Firebase App]**.\n3. Ensure your iOS device is added to your Apple Developer portal as a test device.\n\n#### iOS Simulator\n\nThe iOS Simulator cannot register for remote notifications, and will not receive push notifications.\nIn order to receive push notifications, you'll have to follow the steps above and run the app on a\nphysical device.\n\n## Building with Firebase on Apple platforms\n\nAt this time, not all of Firebase's products are available across all Apple platforms. However,\nFirebase is constantly evolving and community supported efforts have helped expand Firebase's support.\nTo keep up with the latest info regarding Firebase's support across Apple platforms, refer to\n[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform)\nin Firebase's documentation.\n\n### Community Supported Efforts\n\nWe've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are\nvery grateful!  We'd like to empower as many developers as we can to be able to use Firebase and\nparticipate in the Firebase community.\n\n#### tvOS, macOS, watchOS and Catalyst\nThanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and\nwork on tvOS, macOS, watchOS and Catalyst.\n\nFor tvOS, see the [Sample](Example/tvOSSample).\nFor watchOS, currently only Messaging, Storage and Crashlytics (and their dependencies) have limited\nsupport. See the [Independent Watch App Sample](Example/watchOSSample).\n\nKeep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and\nthis repository is actively developed primarily for iOS. While we can catch basic unit test issues\nwith GitHub Actions, there may be some changes where the SDK no longer works as expected on macOS,\ntvOS or watchOS. If you encounter this, please\n[file an issue](https://github.com/firebase/firebase-ios-sdk/issues).\n\nDuring app setup in the console, you may get to a step that mentions something like \"Checking if the\napp has communicated with our servers\". This relies on Analytics and will not work on\nmacOS/tvOS/watchOS/Catalyst.\n**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.\n\n#### Additional MacOS and Catalyst Notes\n\n* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`\nto Build Settings.\n* For Catalyst, FirebaseFirestore requires signing the\n[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).\n\n#### Additional Crashlytics Notes\n* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are\nnot recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded)\n\n## Roadmap\n\nSee [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source\nplans and directions.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase\niOS SDK.\n\n## License\n\nThe contents of this repository are licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\nYour use of Firebase is governed by the\n[Terms of Service for Firebase Services](https://firebase.google.com/terms/).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg\n[gh-appcheck-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/app_check/badge.svg\n[gh-appdistribution-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/appdistribution/badge.svg\n[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg\n[gh-cocoapods-integration-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/cocoapods-integration/badge.svg\n[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg\n[gh-core-diagnostics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core-diagnostics/badge.svg\n[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg\n[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg\n[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg\n[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg\n[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg\n[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg\n[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg\n[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg\n[gh-google-utilities-components-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities-components/badge.svg\n[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg\n[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg\n[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg\n[gh-mlmodeldownloader-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/mlmodeldownloader/badge.svg\n[gh-performance-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/performance/badge.svg\n[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg\n[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg\n[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg\n[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/Info.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>AvailableLibraries</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>LibraryIdentifier</key>\n\t\t\t<string>ios-arm64_armv7</string>\n\t\t\t<key>LibraryPath</key>\n\t\t\t<string>FirebaseAnalytics.framework</string>\n\t\t\t<key>SupportedArchitectures</key>\n\t\t\t<array>\n\t\t\t\t<string>arm64</string>\n\t\t\t\t<string>armv7</string>\n\t\t\t</array>\n\t\t\t<key>SupportedPlatform</key>\n\t\t\t<string>ios</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>LibraryIdentifier</key>\n\t\t\t<string>ios-arm64_i386_x86_64-simulator</string>\n\t\t\t<key>LibraryPath</key>\n\t\t\t<string>FirebaseAnalytics.framework</string>\n\t\t\t<key>SupportedArchitectures</key>\n\t\t\t<array>\n\t\t\t\t<string>arm64</string>\n\t\t\t\t<string>i386</string>\n\t\t\t\t<string>x86_64</string>\n\t\t\t</array>\n\t\t\t<key>SupportedPlatform</key>\n\t\t\t<string>ios</string>\n\t\t\t<key>SupportedPlatformVariant</key>\n\t\t\t<string>simulator</string>\n\t\t</dict>\n\t</array>\n\t<key>CFBundlePackageType</key>\n\t<string>XFWK</string>\n\t<key>XCFrameworkFormatVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIRAnalytics.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * Provides App Delegate handlers to be used in your App Delegate.\n *\n * To save time integrating Firebase Analytics in an application, Firebase Analytics does not\n * require delegation implementation from the AppDelegate. Instead this is automatically done by\n * Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App\n * Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting\n * it to NO, and adding the methods in this category to corresponding delegation handlers.\n *\n * To handle Universal Links, you must return YES in\n * [UIApplicationDelegate application:didFinishLaunchingWithOptions:].\n */\n@interface FIRAnalytics (AppDelegate)\n\n/**\n * Handles events related to a URL session that are waiting to be processed.\n *\n * For optimal use of Firebase Analytics, call this method from the\n * [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler]\n * method of the app delegate in your app.\n *\n * @param identifier The identifier of the URL session requiring attention.\n * @param completionHandler The completion handler to call when you finish processing the events.\n *     Calling this completion handler lets the system know that your app's user interface is\n *     updated and a new snapshot can be taken.\n */\n+ (void)handleEventsForBackgroundURLSession:(NSString *)identifier\n                          completionHandler:(nullable void (^)(void))completionHandler;\n\n/**\n * Handles the event when the app is launched by a URL.\n *\n * Call this method from [UIApplicationDelegate application:openURL:options:] &#40;on iOS 9.0 and\n * above&#41;, or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] &#40;on\n * iOS 8.x and below&#41; in your app.\n *\n * @param url The URL resource to open. This resource can be a network resource or a file.\n */\n+ (void)handleOpenURL:(NSURL *)url;\n\n/**\n * Handles the event when the app receives data associated with user activity that includes a\n * Universal Link (on iOS 9.0 and above).\n *\n * Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app\n * delegate (on iOS 9.0 and above).\n *\n * @param userActivity The activity object containing the data associated with the task the user\n *     was performing.\n */\n+ (void)handleUserActivity:(id)userActivity;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIRAnalytics.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The type of consent to set. Supported consent types are `ConsentType.adStorage` and\n/// `ConsentType.analyticsStorage`. Omitting a type retains its previous status.\ntypedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType);\nextern FIRConsentType const FIRConsentTypeAdStorage;\nextern FIRConsentType const FIRConsentTypeAnalyticsStorage;\n\n/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and\n/// `ConsentStatus.denied`.\ntypedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus);\nextern FIRConsentStatus const FIRConsentStatusDenied;\nextern FIRConsentStatus const FIRConsentStatusGranted;\n\n/// Sets the applicable end user consent state.\n@interface FIRAnalytics (Consent)\n\n/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this\n/// device. Use the consent settings to specify individual consent type values. Settings are\n/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`.\n///\n/// @param consentSettings An NSDictionary of consent types. Supported consent type keys are\n///   `ConsentType.adStorage` and `ConsentType.analyticsStorage`. Valid values are\n///   `ConsentStatus.granted` and `ConsentStatus.denied`.\n+ (void)setConsent:(NSDictionary<FIRConsentType, FIRConsentStatus> *)consentSettings;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIRAnalytics.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIREventNames.h\"\n#import \"FIRParameterNames.h\"\n#import \"FIRUserPropertyNames.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The top level Firebase Analytics singleton that provides methods for logging events and setting\n/// user properties. See <a href=\"http://goo.gl/gz8SLz\">the developer guides</a> for general\n/// information on using Firebase Analytics in your apps.\n///\n/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling\n///     certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in\n///     unexpected crashes at runtime.\nNS_SWIFT_NAME(Analytics)\n@interface FIRAnalytics : NSObject\n\n/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have\n/// the same parameters. Up to 500 event names are supported. Using predefined events and/or\n/// parameters is recommended for optimal reporting.\n///\n/// The following event names are reserved and cannot be used:\n/// <ul>\n///     <li>ad_activeview</li>\n///     <li>ad_click</li>\n///     <li>ad_exposure</li>\n///     <li>ad_query</li>\n///     <li>ad_reward</li>\n///     <li>adunit_exposure</li>\n///     <li>app_background</li>\n///     <li>app_clear_data</li>\n///     <li>app_exception</li>\n///     <li>app_remove</li>\n///     <li>app_store_refund</li>\n///     <li>app_store_subscription_cancel</li>\n///     <li>app_store_subscription_convert</li>\n///     <li>app_store_subscription_renew</li>\n///     <li>app_update</li>\n///     <li>app_upgrade</li>\n///     <li>dynamic_link_app_open</li>\n///     <li>dynamic_link_app_update</li>\n///     <li>dynamic_link_first_open</li>\n///     <li>error</li>\n///     <li>firebase_campaign</li>\n///     <li>first_open</li>\n///     <li>first_visit</li>\n///     <li>in_app_purchase</li>\n///     <li>notification_dismiss</li>\n///     <li>notification_foreground</li>\n///     <li>notification_open</li>\n///     <li>notification_receive</li>\n///     <li>os_update</li>\n///     <li>session_start</li>\n///     <li>session_start_with_rollout</li>\n///     <li>user_engagement</li>\n/// </ul>\n///\n/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or\n///     underscores. The name must start with an alphabetic character. Some event names are\n///     reserved. See FIREventNames.h for the list of reserved event names. The \"firebase_\",\n///     \"google_\", and \"ga_\" prefixes are reserved and should not be used. Note that event names are\n///     case-sensitive and that logging two events whose names differ only in case will result in\n///     two distinct events. To manually log screen view events, use the `screen_view` event name.\n/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has\n///     no parameters. Parameter names can be up to 40 characters long and must start with an\n///     alphabetic character and contain only alphanumeric characters and underscores. Only NSString\n///     and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are\n///     supported. NSString parameter values can be up to 100 characters long. The \"firebase_\",\n///     \"google_\", and \"ga_\" prefixes are reserved and should not be used for parameter names.\n+ (void)logEventWithName:(NSString *)name\n              parameters:(nullable NSDictionary<NSString *, id> *)parameters\n    NS_SWIFT_NAME(logEvent(_:parameters:));\n\n/// Sets a user property to a given value. Up to 25 user property names are supported. Once set,\n/// user property values persist throughout the app lifecycle and across sessions.\n///\n/// The following user property names are reserved and cannot be used:\n/// <ul>\n///     <li>first_open_time</li>\n///     <li>last_deep_link_referrer</li>\n///     <li>user_id</li>\n/// </ul>\n///\n/// @param value The value of the user property. Values can be up to 36 characters long. Setting the\n///     value to nil removes the user property.\n/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters\n///     or underscores and must start with an alphabetic character. The \"firebase_\", \"google_\", and\n///     \"ga_\" prefixes are reserved and should not be used for user property names.\n+ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name\n    NS_SWIFT_NAME(setUserProperty(_:forName:));\n\n/// Sets the user ID property. This feature must be used in accordance with\n/// <a href=\"https://www.google.com/policies/privacy\">Google's Privacy Policy</a>\n///\n/// @param userID The user ID to ascribe to the user of this app on this device, which must be\n///     non-empty and no more than 256 characters long. Setting userID to nil removes the user ID.\n+ (void)setUserID:(nullable NSString *)userID;\n\n/// Sets whether analytics collection is enabled for this app on this device. This setting is\n/// persisted across app sessions. By default it is enabled.\n///\n/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection.\n+ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;\n\n/// Sets the interval of inactivity in seconds that terminates the current session. The default\n/// value is 1800 seconds (30 minutes).\n///\n/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current\n///     session terminates.\n+ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval;\n\n/// Returns the unique ID for this instance of the application or nil if\n/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`.\n///\n/// @see `FIRAnalytics+Consent.h`\n+ (nullable NSString *)appInstanceID;\n\n/// Clears all analytics data for this instance from the device and resets the app instance ID.\n/// FIRAnalyticsConfiguration values will be reset to the default values.\n+ (void)resetAnalyticsData;\n\n/// Adds parameters that will be set on every event logged from the SDK, including automatic ones.\n/// The values passed in the parameters dictionary will be added to the dictionary of default event\n/// parameters. These parameters persist across app runs. They are of lower precedence than event\n/// parameters, so if an event parameter and a parameter set using this API have the same name, the\n/// value of the event parameter will be used. The same limitations on event parameters apply to\n/// default event parameters.\n///\n/// @param parameters Parameters to be added to the dictionary of parameters added to every event.\n///     They will be added to the dictionary of default event parameters, replacing any existing\n///     parameter with the same name. Valid parameters are NSString and NSNumber (signed 64-bit\n///     integer and 64-bit floating-point number). Setting a key's value to [NSNull null] will clear\n///     that parameter. Passing in a nil dictionary will clear all parameters.\n+ (void)setDefaultEventParameters:(nullable NSDictionary<NSString *, id> *)parameters;\n\n/// Unavailable.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIREventNames.h",
    "content": "/// @file FIREventNames.h\n///\n/// Predefined event names.\n///\n/// An Event is an important occurrence in your app that you want to measure. You can report up to\n/// 500 different types of Events per app and you can associate up to 25 unique parameters with each\n/// Event type. Some common events are suggested below, but you may also choose to specify custom\n/// Event types that are associated with your specific app. Each event type is identified by a\n/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric\n/// characters and underscores (\"_\"), and must start with an alphabetic character. The \"firebase_\",\n/// \"google_\", and \"ga_\" prefixes are reserved and should not be used.\n\n#import <Foundation/Foundation.h>\n\n/// Add Payment Info event. This event signifies that a user has submitted their payment\n/// information. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterPaymentType (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) =\n    @\"add_payment_info\";\n\n/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for\n/// purchase. Add this event to a funnel with @c kFIREventPurchase to gauge the effectiveness of\n/// your checkout process. Note: If you supply the @c kFIRParameterValue parameter, you must also\n/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @\"add_to_cart\";\n\n/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use\n/// this event to identify popular gift items. Note: If you supply the @c kFIRParameterValue\n/// parameter, you must also supply the @c kFIRParameterCurrency parameter so that revenue metrics\n/// can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) =\n    @\"add_to_wishlist\";\n\n/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply\n/// the @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency parameter\n/// so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAdPlatform (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdFormat (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdSource (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdUnitName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) =\n    @\"ad_impression\";\n\n/// App Open event. By logging this event when an App becomes active, developers can understand how\n/// often users leave and return during the course of a Session. Although Sessions are automatically\n/// reported, this event can provide further clarification around the continuous engagement of\n/// app-users.\nstatic NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @\"app_open\";\n\n/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of\n/// checking out. Add this event to a funnel with your @c kFIREventPurchase event to gauge the\n/// effectiveness of your checkout process. Note: If you supply the @c kFIRParameterValue parameter,\n/// you must also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be\n/// computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) =\n    @\"begin_checkout\";\n\n/// Campaign Detail event. Log this event to supply the referral details of a re-engagement\n/// campaign. Note: you must supply at least one of the required parameters kFIRParameterSource,\n/// kFIRParameterMedium or kFIRParameterCampaign. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSource (NSString)</li>\n///     <li>@c kFIRParameterMedium (NSString)</li>\n///     <li>@c kFIRParameterCampaign (NSString)</li>\n///     <li>@c kFIRParameterTerm (NSString) (optional)</li>\n///     <li>@c kFIRParameterContent (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdNetworkClickID (NSString) (optional)</li>\n///     <li>@c kFIRParameterCP1 (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) =\n    @\"campaign_details\";\n\n/// Checkout progress. Params:\n///\n/// <ul>\n///    <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li>\n///    <li>@c kFIRParameterCheckoutOption (NSString) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIREventCheckoutProgress NS_SWIFT_NAME(AnalyticsEventCheckoutProgress) =\n    @\"checkout_progress\";\n\n/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log\n/// this along with @c kFIREventSpendVirtualCurrency to better understand your virtual economy.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>\n///     <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>\n/// </ul>\nstatic NSString *const kFIREventEarnVirtualCurrency\n    NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @\"earn_virtual_currency\";\n\n/// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note:\n/// This is different from the in-app purchase event, which is reported automatically for App\n/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also\n/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterLocation (NSString) (optional)</li>\n///     <li>@c kFIRParameterStartDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterEndDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)\n///         for travel bookings</li>\n///     <li>@c kFIRParameterOrigin (NSString) (optional)</li>\n///     <li>@c kFIRParameterDestination (NSString) (optional)</li>\n///     <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventPurchase constant instead.</b>\nstatic NSString *const kFIREventEcommercePurchase NS_SWIFT_NAME(AnalyticsEventEcommercePurchase) =\n    @\"ecommerce_purchase\";\n\n/// Generate Lead event. Log this event when a lead has been generated in the app to understand the\n/// efficacy of your install and re-engagement campaigns. Note: If you supply the\n/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency\n/// parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) =\n    @\"generate_lead\";\n\n/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use\n/// this event to analyze how popular certain groups or social features are in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterGroupID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @\"join_group\";\n\n/// Level End event. Log this event when the user finishes a level. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevelName (NSString)</li>\n///     <li>@c kFIRParameterSuccess (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @\"level_end\";\n\n/// Level Start event. Log this event when the user starts a new level. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevelName (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @\"level_start\";\n\n/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can\n/// help you gauge the level distribution of your userbase and help you identify certain levels that\n/// are difficult to pass. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterCharacter (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @\"level_up\";\n\n/// Login event. Apps with a login feature can report this event to signify that a user has logged\n/// in.\nstatic NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @\"login\";\n\n/// Post Score event. Log this event when the user posts a score in your gaming app. This event can\n/// help you understand how users are actually performing in your game and it can help you correlate\n/// high scores with certain audiences or behaviors. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterScore (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCharacter (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @\"post_score\";\n\n/// Present Offer event. This event signifies that the app has presented a purchase offer to a user.\n/// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge\n/// your conversion process. Note: If you supply the @c kFIRParameterValue parameter, you must\n/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n///     <li>@c kFIRParameterItemName (NSString)</li>\n///     <li>@c kFIRParameterItemCategory (NSString)</li>\n///     <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventViewPromotion constant instead.</b>\nstatic NSString *const kFIREventPresentOffer NS_SWIFT_NAME(AnalyticsEventPresentOffer) =\n    @\"present_offer\";\n\n/// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded.\n/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventRefund constant instead.</b>\nstatic NSString *const kFIREventPurchaseRefund NS_SWIFT_NAME(AnalyticsEventPurchaseRefund) =\n    @\"purchase_refund\";\n\n/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart.\n/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the @c\n/// kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) =\n    @\"remove_from_cart\";\n\n/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs.\n/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterScreenClass (NSString) (optional)</li>\n///     <li>@c kFIRParameterScreenName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @\"screen_view\";\n\n/// Search event. Apps that support search features can use this event to contextualize search\n/// operations by supplying the appropriate, corresponding parameters. This event can help you\n/// identify the most popular content in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSearchTerm (NSString)</li>\n///     <li>@c kFIRParameterStartDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterEndDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)\n///         for travel bookings</li>\n///     <li>@c kFIRParameterOrigin (NSString) (optional)</li>\n///     <li>@c kFIRParameterDestination (NSString) (optional)</li>\n///     <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>\n/// </ul>\nstatic NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @\"search\";\n\n/// Select Content event. This general purpose event signifies that a user has selected some content\n/// of a certain type in an app. The content can be any object in your app. This event can help you\n/// identify popular content and categories of content in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterContentType (NSString)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) =\n    @\"select_content\";\n\n/// Set checkout option. Params:\n///\n/// <ul>\n///    <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li>\n///    <li>@c kFIRParameterCheckoutOption (NSString)</li>\n/// </ul>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIREventSetCheckoutOption NS_SWIFT_NAME(AnalyticsEventSetCheckoutOption) =\n    @\"set_checkout_option\";\n\n/// Share event. Apps with social features can log the Share event to identify the most viral\n/// content. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterContentType (NSString)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @\"share\";\n\n/// Sign Up event. This event indicates that a user has signed up for an account in your app. The\n/// parameter signifies the method by which the user signed up. Use this event to understand the\n/// different behaviors between logged in and logged out users. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSignUpMethod (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @\"sign_up\";\n\n/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can\n/// help you identify which virtual goods are the most popular objects of purchase. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItemName (NSString)</li>\n///     <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>\n///     <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>\n/// </ul>\nstatic NSString *const kFIREventSpendVirtualCurrency\n    NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @\"spend_virtual_currency\";\n\n/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use\n/// this in a funnel with kFIREventTutorialComplete to understand how many users complete this\n/// process and move on to the full app experience.\nstatic NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) =\n    @\"tutorial_begin\";\n\n/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding\n/// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your\n/// on-boarding process.\nstatic NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) =\n    @\"tutorial_complete\";\n\n/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your\n/// game. Since achievements generally represent the breadth of a gaming experience, this event can\n/// help you understand how many users are experiencing all that your game has to offer. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAchievementID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) =\n    @\"unlock_achievement\";\n\n/// View Item event. This event signifies that a user has viewed an item. Use the appropriate\n/// parameters to contextualize the event. Use this event to discover the most popular items viewed\n/// in your app. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @\"view_item\";\n\n/// View Item List event. Log this event when a user sees a list of items or offerings. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterItemListID (NSString) (optional)</li>\n///     <li>@c kFIRParameterItemListName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) =\n    @\"view_item_list\";\n\n/// View Search Results event. Log this event when the user has been presented with the results of a\n/// search. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSearchTerm (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) =\n    @\"view_search_results\";\n\n/// Add Shipping Info event. This event signifies that a user has submitted their shipping\n/// information. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShippingTier (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) =\n    @\"add_shipping_info\";\n\n/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note:\n/// This is different from the in-app purchase event, which is reported automatically for App\n/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also supply\n/// the @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAffiliation (NSString) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @\"purchase\";\n\n/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the\n/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency parameter so\n/// that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAffiliation (NSString) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @\"refund\";\n\n/// Select Item event. This event signifies that an item was selected by a user from a list. Use the\n/// appropriate parameters to contextualize the event. Use this event to discover the most popular\n/// items selected. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterItemListID (NSString) (optional)</li>\n///     <li>@c kFIRParameterItemListName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @\"select_item\";\n\n/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the\n/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion\n/// applies. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCreativeName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCreativeSlot (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) =\n    @\"select_promotion\";\n\n/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to\n/// analyze your purchase funnel. Note: If you supply the @c kFIRParameterValue parameter, you must\n/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @\"view_cart\";\n\n/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event\n/// to a funnel with the @c kFIREventAddToCart and @c kFIREventPurchase to gauge your conversion\n/// process. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCreativeName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCreativeSlot (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) =\n    @\"view_promotion\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIRParameterNames.h",
    "content": "/// @file FIRParameterNames.h\n///\n/// Predefined event parameter names.\n///\n/// Params supply information that contextualize Events. You can associate up to 25 unique Params\n/// with each Event type. Some Params are suggested below for certain common Events, but you are\n/// not limited to these. You may supply extra Params for suggested Events or custom Params for\n/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric\n/// characters and underscores (\"_\"), and must start with an alphabetic character. Param values can\n/// be up to 100 characters long. The \"firebase_\", \"google_\", and \"ga_\" prefixes are reserved and\n/// should not be used.\n\n#import <Foundation/Foundation.h>\n\n/// Game achievement ID (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAchievementID : @\"10_matches_won\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) =\n    @\"achievement_id\";\n\n/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream).\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdFormat : @\"Banner\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) =\n    @\"ad_format\";\n\n/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdNetworkClickID : @\"1234567\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdNetworkClickID\n    NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @\"aclid\";\n\n/// The ad platform (e.g. MoPub, IronSource) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdPlatform : @\"MoPub\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) =\n    @\"ad_platform\";\n\n/// The ad source (e.g. AdColony) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdSource : @\"AdColony\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) =\n    @\"ad_source\";\n\n/// The ad unit name (e.g. Banner_03) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdUnitName : @\"Banner_03\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) =\n    @\"ad_unit_name\";\n\n/// A product affiliation to designate a supplying company or brick and mortar store location\n/// (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAffiliation : @\"Google Store\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) =\n    @\"affiliation\";\n\n/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to\n/// capture campaign information, otherwise can be populated by developer. Highly Recommended\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCampaign : @\"winter_promotion\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) =\n    @\"campaign\";\n\n/// Character used in game (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCharacter : @\"beat_boss\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) =\n    @\"character\";\n\n/// The checkout step (1..N) (unsigned 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCheckoutStep : @\"1\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIRParameterCheckoutStep NS_SWIFT_NAME(AnalyticsParameterCheckoutStep) =\n    @\"checkout_step\";\n\n/// Some option on a step in an ecommerce flow (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCheckoutOption : @\"Visa\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIRParameterCheckoutOption\n    NS_SWIFT_NAME(AnalyticsParameterCheckoutOption) = @\"checkout_option\";\n\n/// Campaign content (NSString).\nstatic NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @\"content\";\n\n/// Type of content selected (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterContentType : @\"news article\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) =\n    @\"content_type\";\n\n/// Coupon code used for a purchase (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCoupon : @\"SUMMER_FUN\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @\"coupon\";\n\n/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign.\n/// Use varies by network.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCP1 : @\"custom_data\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @\"cp1\";\n\n/// The name of a creative used in a promotional spot (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCreativeName : @\"Summer Sale\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) =\n    @\"creative_name\";\n\n/// The name of a creative slot (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCreativeSlot : @\"summer_banner2\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) =\n    @\"creative_slot\";\n\n/// Currency of the purchase or items associated with the event, in 3-letter\n/// <a href=\"http://en.wikipedia.org/wiki/ISO_4217#Active_codes\"> ISO_4217</a> format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCurrency : @\"USD\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) =\n    @\"currency\";\n\n/// Flight or Travel destination (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterDestination : @\"Mountain View, CA\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) =\n    @\"destination\";\n\n/// The arrival date, check-out date or rental end date for the item. This should be in\n/// YYYY-MM-DD format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterEndDate : @\"2015-09-14\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @\"end_date\";\n\n/// Flight number for travel events (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterFlightNumber : @\"ZZ800\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) =\n    @\"flight_number\";\n\n/// Group/clan/guild ID (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterGroupID : @\"g1\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @\"group_id\";\n\n/// The index of the item in a list (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterIndex : @(5),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @\"index\";\n\n/// Item brand (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemBrand : @\"Google\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) =\n    @\"item_brand\";\n\n/// Item category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) =\n    @\"item_category\";\n\n/// Item ID (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemID : @\"SKU_12345\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @\"item_id\";\n\n/// The Google <a href=\"https://developers.google.com/places/place-id\">Place ID</a> (NSString) that\n/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemLocationID : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated. Use @c kFIRParameterLocationID constant instead.</b>\nstatic NSString *const kFIRParameterItemLocationID\n    NS_SWIFT_NAME(AnalyticsParameterItemLocationID) = @\"item_location_id\";\n\n/// Item Name (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemName : @\"jeggings\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) =\n    @\"item_name\";\n\n/// The list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemList : @\"Search Results\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated. Use @c kFIRParameterItemListName constant instead.</b>\nstatic NSString *const kFIRParameterItemList NS_SWIFT_NAME(AnalyticsParameterItemList) =\n    @\"item_list\";\n\n/// Item variant (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemVariant : @\"Black\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) =\n    @\"item_variant\";\n\n/// Level in game (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLevel : @(42),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @\"level\";\n\n/// Location (NSString). The Google <a href=\"https://developers.google.com/places/place-id\">Place ID\n/// </a> that corresponds to the associated event. Alternatively, you can supply your own custom\n/// Location ID.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLocation : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) =\n    @\"location\";\n\n/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterMedium : @\"email\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @\"medium\";\n\n/// Number of nights staying at hotel (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfNights : @(3),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfNights\n    NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @\"number_of_nights\";\n\n/// Number of passengers traveling (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfPassengers : @(11),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfPassengers\n    NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @\"number_of_passengers\";\n\n/// Number of rooms for travel events (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfRooms : @(2),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) =\n    @\"number_of_rooms\";\n\n/// Flight or Travel origin (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterOrigin : @\"Mountain View, CA\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @\"origin\";\n\n/// Purchase price (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPrice : @(1.0),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $1.00 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @\"price\";\n\n/// Purchase quantity (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterQuantity : @(1),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) =\n    @\"quantity\";\n\n/// Score in game (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScore : @(4200),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @\"score\";\n\n/// Current screen class, such as the class name of the UIViewController, logged with screen_view\n/// event and added to every event (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScreenClass : @\"LoginViewController\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) =\n    @\"screen_class\";\n\n/// Current screen name, such as the name of the UIViewController, logged with screen_view event and\n/// added to every event (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScreenName : @\"LoginView\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) =\n    @\"screen_name\";\n\n/// The search string/keywords used (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSearchTerm : @\"periodic table\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) =\n    @\"search_term\";\n\n/// Shipping cost associated with a transaction (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterShipping : @(5.99),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $5.99 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) =\n    @\"shipping\";\n\n/// Sign up method (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSignUpMethod : @\"google\",\n///       // ...\n///     };\n/// </pre>\n///\n/// <b>This constant has been deprecated. Use Method constant instead.</b>\nstatic NSString *const kFIRParameterSignUpMethod NS_SWIFT_NAME(AnalyticsParameterSignUpMethod) =\n    @\"sign_up_method\";\n\n/// A particular approach used in an operation; for example, \"facebook\" or \"email\" in the context\n/// of a sign_up or login event.  (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterMethod : @\"google\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @\"method\";\n\n/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban\n/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your\n/// property. Highly recommended (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSource : @\"InMobi\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @\"source\";\n\n/// The departure date, check-in date or rental start date for the item. This should be in\n/// YYYY-MM-DD format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterStartDate : @\"2015-09-14\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) =\n    @\"start_date\";\n\n/// Tax cost associated with a transaction (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTax : @(2.43),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $2.43 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @\"tax\";\n\n/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTerm : @\"game\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @\"term\";\n\n/// The unique identifier of a transaction (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTransactionID : @\"T12345\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) =\n    @\"transaction_id\";\n\n/// Travel class (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTravelClass : @\"business\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) =\n    @\"travel_class\";\n\n/// A context-specific numeric value which is accumulated automatically for each event type. This is\n/// a general purpose parameter that is useful for accumulating a key metric that pertains to an\n/// event. Examples include revenue, distance, time and points. Value should be specified as signed\n/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events\n/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be\n/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is\n/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the\n/// corresponding @c kFIRParameterCurrency parameter, or supplying an invalid\n/// <a href=\"https://goo.gl/qqX3J2\">currency code</a> for conversion events will cause that\n/// conversion to be omitted from reporting.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterValue : @(3.99),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $3.99 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @\"value\";\n\n/// Name of virtual currency type (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterVirtualCurrencyName : @\"virtual_currency_name\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterVirtualCurrencyName\n    NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @\"virtual_currency_name\";\n\n/// The name of a level in a game (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLevelName : @\"room_1\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) =\n    @\"level_name\";\n\n/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (unsigned\n/// integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSuccess : @(1),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @\"success\";\n\n/// Indicates that the associated event should either extend the current session\n/// or start a new session if no session was active when the event was logged.\n/// Specify YES to extend the current session or to start a new session; any\n/// other value will not extend or start a session.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterExtendSession : @YES,\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) =\n    @\"extend_session\";\n\n/// Monetary value of discount associated with a purchase (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterDiscount : @(2.0),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $2.00 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) =\n    @\"discount\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory2 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) =\n    @\"item_category2\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory3 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) =\n    @\"item_category3\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory4 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) =\n    @\"item_category4\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory5 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) =\n    @\"item_category5\";\n\n/// The ID of the list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemListID : @\"ABC123\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) =\n    @\"item_list_id\";\n\n/// The name of the list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemListName : @\"Related products\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) =\n    @\"item_list_name\";\n\n/// The list of items involved in the transaction. (NSArray).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItems : @[\n///         @{kFIRParameterItemName : @\"jeggings\", kFIRParameterItemCategory : @\"pants\"},\n///         @{kFIRParameterItemName : @\"boots\", kFIRParameterItemCategory : @\"shoes\"},\n///       ],\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @\"items\";\n\n/// The location associated with the event. Preferred to be the Google\n/// <a href=\"https://developers.google.com/places/place-id\">Place ID</a> that corresponds to the\n/// associated item but could be overridden to a custom location ID string.(NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLocationID : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) =\n    @\"location_id\";\n\n/// The chosen method of payment (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPaymentType : @\"Visa\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) =\n    @\"payment_type\";\n\n/// The ID of a product promotion (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPromotionID : @\"ABC123\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) =\n    @\"promotion_id\";\n\n/// The name of a product promotion (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPromotionName : @\"Summer Sale\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) =\n    @\"promotion_name\";\n\n/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterShippingTier : @\"Ground\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) =\n    @\"shipping_tier\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h",
    "content": "/// @file FIRUserPropertyNames.h\n///\n/// Predefined user property names.\n///\n/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can\n/// later analyze different behaviors of various segments of your userbase. You may supply up to 25\n/// unique UserProperties per app, and you can use the name and value of your choosing for each one.\n/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and\n/// underscores (\"_\"), and must start with an alphabetic character. UserProperty values can be up to\n/// 36 characters long. The \"firebase_\", \"google_\", and \"ga_\" prefixes are reserved and should not\n/// be used.\n\n#import <Foundation/Foundation.h>\n\n/// The method used to sign in. For example, \"google\", \"facebook\" or \"twitter\".\nstatic NSString *const kFIRUserPropertySignUpMethod\n    NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @\"sign_up_method\";\n\n/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user.\n/// Set to \"YES\" to enable, or \"NO\" to disable. Default is enabled. See the\n/// <a href=\"https://firebase.google.com/support/guides/disable-analytics\">documentation</a> for\n/// more details and information about related settings.\n///\n/// <pre>\n///     [FIRAnalytics setUserPropertyString:@\"NO\"\n///                                 forName:kFIRUserPropertyAllowAdPersonalizationSignals];\n/// </pre>\nstatic NSString *const kFIRUserPropertyAllowAdPersonalizationSignals\n    NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @\"allow_personalized_ads\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h",
    "content": "#import \"FIRAnalytics+AppDelegate.h\"\n#import \"FIRAnalytics+Consent.h\"\n#import \"FIRAnalytics.h\"\n#import \"FIREventNames.h\"\n#import \"FIRParameterNames.h\"\n#import \"FIRUserPropertyNames.h\"\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Info.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>CFBundleExecutable</key>\n\t<string>FirebaseAnalytics</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.firebase.Firebase-FirebaseAnalytics</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>FirebaseAnalytics</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleVersion</key>\n\t<string>8.3.0</string>\n\t<key>DTSDKName</key>\n\t<string>iphonesimulator11.2</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_armv7/FirebaseAnalytics.framework/Modules/module.modulemap",
    "content": "framework module FirebaseAnalytics {\numbrella header \"FirebaseAnalytics.h\"\nexport *\nmodule * { export * }\n  link framework \"CoreTelephony\"\n  link framework \"Foundation\"\n  link framework \"Security\"\n  link framework \"SystemConfiguration\"\n  link framework \"UIKit\"\n  link \"c++\"\n  link \"sqlite3\"\n  link \"z\"\n}\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIRAnalytics.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * Provides App Delegate handlers to be used in your App Delegate.\n *\n * To save time integrating Firebase Analytics in an application, Firebase Analytics does not\n * require delegation implementation from the AppDelegate. Instead this is automatically done by\n * Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App\n * Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting\n * it to NO, and adding the methods in this category to corresponding delegation handlers.\n *\n * To handle Universal Links, you must return YES in\n * [UIApplicationDelegate application:didFinishLaunchingWithOptions:].\n */\n@interface FIRAnalytics (AppDelegate)\n\n/**\n * Handles events related to a URL session that are waiting to be processed.\n *\n * For optimal use of Firebase Analytics, call this method from the\n * [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler]\n * method of the app delegate in your app.\n *\n * @param identifier The identifier of the URL session requiring attention.\n * @param completionHandler The completion handler to call when you finish processing the events.\n *     Calling this completion handler lets the system know that your app's user interface is\n *     updated and a new snapshot can be taken.\n */\n+ (void)handleEventsForBackgroundURLSession:(NSString *)identifier\n                          completionHandler:(nullable void (^)(void))completionHandler;\n\n/**\n * Handles the event when the app is launched by a URL.\n *\n * Call this method from [UIApplicationDelegate application:openURL:options:] &#40;on iOS 9.0 and\n * above&#41;, or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] &#40;on\n * iOS 8.x and below&#41; in your app.\n *\n * @param url The URL resource to open. This resource can be a network resource or a file.\n */\n+ (void)handleOpenURL:(NSURL *)url;\n\n/**\n * Handles the event when the app receives data associated with user activity that includes a\n * Universal Link (on iOS 9.0 and above).\n *\n * Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app\n * delegate (on iOS 9.0 and above).\n *\n * @param userActivity The activity object containing the data associated with the task the user\n *     was performing.\n */\n+ (void)handleUserActivity:(id)userActivity;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIRAnalytics.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The type of consent to set. Supported consent types are `ConsentType.adStorage` and\n/// `ConsentType.analyticsStorage`. Omitting a type retains its previous status.\ntypedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType);\nextern FIRConsentType const FIRConsentTypeAdStorage;\nextern FIRConsentType const FIRConsentTypeAnalyticsStorage;\n\n/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and\n/// `ConsentStatus.denied`.\ntypedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus);\nextern FIRConsentStatus const FIRConsentStatusDenied;\nextern FIRConsentStatus const FIRConsentStatusGranted;\n\n/// Sets the applicable end user consent state.\n@interface FIRAnalytics (Consent)\n\n/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this\n/// device. Use the consent settings to specify individual consent type values. Settings are\n/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`.\n///\n/// @param consentSettings An NSDictionary of consent types. Supported consent type keys are\n///   `ConsentType.adStorage` and `ConsentType.analyticsStorage`. Valid values are\n///   `ConsentStatus.granted` and `ConsentStatus.denied`.\n+ (void)setConsent:(NSDictionary<FIRConsentType, FIRConsentStatus> *)consentSettings;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h",
    "content": "#import <Foundation/Foundation.h>\n\n#import \"FIREventNames.h\"\n#import \"FIRParameterNames.h\"\n#import \"FIRUserPropertyNames.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The top level Firebase Analytics singleton that provides methods for logging events and setting\n/// user properties. See <a href=\"http://goo.gl/gz8SLz\">the developer guides</a> for general\n/// information on using Firebase Analytics in your apps.\n///\n/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling\n///     certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in\n///     unexpected crashes at runtime.\nNS_SWIFT_NAME(Analytics)\n@interface FIRAnalytics : NSObject\n\n/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have\n/// the same parameters. Up to 500 event names are supported. Using predefined events and/or\n/// parameters is recommended for optimal reporting.\n///\n/// The following event names are reserved and cannot be used:\n/// <ul>\n///     <li>ad_activeview</li>\n///     <li>ad_click</li>\n///     <li>ad_exposure</li>\n///     <li>ad_query</li>\n///     <li>ad_reward</li>\n///     <li>adunit_exposure</li>\n///     <li>app_background</li>\n///     <li>app_clear_data</li>\n///     <li>app_exception</li>\n///     <li>app_remove</li>\n///     <li>app_store_refund</li>\n///     <li>app_store_subscription_cancel</li>\n///     <li>app_store_subscription_convert</li>\n///     <li>app_store_subscription_renew</li>\n///     <li>app_update</li>\n///     <li>app_upgrade</li>\n///     <li>dynamic_link_app_open</li>\n///     <li>dynamic_link_app_update</li>\n///     <li>dynamic_link_first_open</li>\n///     <li>error</li>\n///     <li>firebase_campaign</li>\n///     <li>first_open</li>\n///     <li>first_visit</li>\n///     <li>in_app_purchase</li>\n///     <li>notification_dismiss</li>\n///     <li>notification_foreground</li>\n///     <li>notification_open</li>\n///     <li>notification_receive</li>\n///     <li>os_update</li>\n///     <li>session_start</li>\n///     <li>session_start_with_rollout</li>\n///     <li>user_engagement</li>\n/// </ul>\n///\n/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or\n///     underscores. The name must start with an alphabetic character. Some event names are\n///     reserved. See FIREventNames.h for the list of reserved event names. The \"firebase_\",\n///     \"google_\", and \"ga_\" prefixes are reserved and should not be used. Note that event names are\n///     case-sensitive and that logging two events whose names differ only in case will result in\n///     two distinct events. To manually log screen view events, use the `screen_view` event name.\n/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has\n///     no parameters. Parameter names can be up to 40 characters long and must start with an\n///     alphabetic character and contain only alphanumeric characters and underscores. Only NSString\n///     and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are\n///     supported. NSString parameter values can be up to 100 characters long. The \"firebase_\",\n///     \"google_\", and \"ga_\" prefixes are reserved and should not be used for parameter names.\n+ (void)logEventWithName:(NSString *)name\n              parameters:(nullable NSDictionary<NSString *, id> *)parameters\n    NS_SWIFT_NAME(logEvent(_:parameters:));\n\n/// Sets a user property to a given value. Up to 25 user property names are supported. Once set,\n/// user property values persist throughout the app lifecycle and across sessions.\n///\n/// The following user property names are reserved and cannot be used:\n/// <ul>\n///     <li>first_open_time</li>\n///     <li>last_deep_link_referrer</li>\n///     <li>user_id</li>\n/// </ul>\n///\n/// @param value The value of the user property. Values can be up to 36 characters long. Setting the\n///     value to nil removes the user property.\n/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters\n///     or underscores and must start with an alphabetic character. The \"firebase_\", \"google_\", and\n///     \"ga_\" prefixes are reserved and should not be used for user property names.\n+ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name\n    NS_SWIFT_NAME(setUserProperty(_:forName:));\n\n/// Sets the user ID property. This feature must be used in accordance with\n/// <a href=\"https://www.google.com/policies/privacy\">Google's Privacy Policy</a>\n///\n/// @param userID The user ID to ascribe to the user of this app on this device, which must be\n///     non-empty and no more than 256 characters long. Setting userID to nil removes the user ID.\n+ (void)setUserID:(nullable NSString *)userID;\n\n/// Sets whether analytics collection is enabled for this app on this device. This setting is\n/// persisted across app sessions. By default it is enabled.\n///\n/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection.\n+ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;\n\n/// Sets the interval of inactivity in seconds that terminates the current session. The default\n/// value is 1800 seconds (30 minutes).\n///\n/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current\n///     session terminates.\n+ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval;\n\n/// Returns the unique ID for this instance of the application or nil if\n/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`.\n///\n/// @see `FIRAnalytics+Consent.h`\n+ (nullable NSString *)appInstanceID;\n\n/// Clears all analytics data for this instance from the device and resets the app instance ID.\n/// FIRAnalyticsConfiguration values will be reset to the default values.\n+ (void)resetAnalyticsData;\n\n/// Adds parameters that will be set on every event logged from the SDK, including automatic ones.\n/// The values passed in the parameters dictionary will be added to the dictionary of default event\n/// parameters. These parameters persist across app runs. They are of lower precedence than event\n/// parameters, so if an event parameter and a parameter set using this API have the same name, the\n/// value of the event parameter will be used. The same limitations on event parameters apply to\n/// default event parameters.\n///\n/// @param parameters Parameters to be added to the dictionary of parameters added to every event.\n///     They will be added to the dictionary of default event parameters, replacing any existing\n///     parameter with the same name. Valid parameters are NSString and NSNumber (signed 64-bit\n///     integer and 64-bit floating-point number). Setting a key's value to [NSNull null] will clear\n///     that parameter. Passing in a nil dictionary will clear all parameters.\n+ (void)setDefaultEventParameters:(nullable NSDictionary<NSString *, id> *)parameters;\n\n/// Unavailable.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h",
    "content": "/// @file FIREventNames.h\n///\n/// Predefined event names.\n///\n/// An Event is an important occurrence in your app that you want to measure. You can report up to\n/// 500 different types of Events per app and you can associate up to 25 unique parameters with each\n/// Event type. Some common events are suggested below, but you may also choose to specify custom\n/// Event types that are associated with your specific app. Each event type is identified by a\n/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric\n/// characters and underscores (\"_\"), and must start with an alphabetic character. The \"firebase_\",\n/// \"google_\", and \"ga_\" prefixes are reserved and should not be used.\n\n#import <Foundation/Foundation.h>\n\n/// Add Payment Info event. This event signifies that a user has submitted their payment\n/// information. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterPaymentType (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) =\n    @\"add_payment_info\";\n\n/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for\n/// purchase. Add this event to a funnel with @c kFIREventPurchase to gauge the effectiveness of\n/// your checkout process. Note: If you supply the @c kFIRParameterValue parameter, you must also\n/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @\"add_to_cart\";\n\n/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use\n/// this event to identify popular gift items. Note: If you supply the @c kFIRParameterValue\n/// parameter, you must also supply the @c kFIRParameterCurrency parameter so that revenue metrics\n/// can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) =\n    @\"add_to_wishlist\";\n\n/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply\n/// the @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency parameter\n/// so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAdPlatform (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdFormat (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdSource (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdUnitName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) =\n    @\"ad_impression\";\n\n/// App Open event. By logging this event when an App becomes active, developers can understand how\n/// often users leave and return during the course of a Session. Although Sessions are automatically\n/// reported, this event can provide further clarification around the continuous engagement of\n/// app-users.\nstatic NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @\"app_open\";\n\n/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of\n/// checking out. Add this event to a funnel with your @c kFIREventPurchase event to gauge the\n/// effectiveness of your checkout process. Note: If you supply the @c kFIRParameterValue parameter,\n/// you must also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be\n/// computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) =\n    @\"begin_checkout\";\n\n/// Campaign Detail event. Log this event to supply the referral details of a re-engagement\n/// campaign. Note: you must supply at least one of the required parameters kFIRParameterSource,\n/// kFIRParameterMedium or kFIRParameterCampaign. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSource (NSString)</li>\n///     <li>@c kFIRParameterMedium (NSString)</li>\n///     <li>@c kFIRParameterCampaign (NSString)</li>\n///     <li>@c kFIRParameterTerm (NSString) (optional)</li>\n///     <li>@c kFIRParameterContent (NSString) (optional)</li>\n///     <li>@c kFIRParameterAdNetworkClickID (NSString) (optional)</li>\n///     <li>@c kFIRParameterCP1 (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) =\n    @\"campaign_details\";\n\n/// Checkout progress. Params:\n///\n/// <ul>\n///    <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li>\n///    <li>@c kFIRParameterCheckoutOption (NSString) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIREventCheckoutProgress NS_SWIFT_NAME(AnalyticsEventCheckoutProgress) =\n    @\"checkout_progress\";\n\n/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log\n/// this along with @c kFIREventSpendVirtualCurrency to better understand your virtual economy.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>\n///     <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>\n/// </ul>\nstatic NSString *const kFIREventEarnVirtualCurrency\n    NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @\"earn_virtual_currency\";\n\n/// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note:\n/// This is different from the in-app purchase event, which is reported automatically for App\n/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also\n/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterLocation (NSString) (optional)</li>\n///     <li>@c kFIRParameterStartDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterEndDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)\n///         for travel bookings</li>\n///     <li>@c kFIRParameterOrigin (NSString) (optional)</li>\n///     <li>@c kFIRParameterDestination (NSString) (optional)</li>\n///     <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventPurchase constant instead.</b>\nstatic NSString *const kFIREventEcommercePurchase NS_SWIFT_NAME(AnalyticsEventEcommercePurchase) =\n    @\"ecommerce_purchase\";\n\n/// Generate Lead event. Log this event when a lead has been generated in the app to understand the\n/// efficacy of your install and re-engagement campaigns. Note: If you supply the\n/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency\n/// parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) =\n    @\"generate_lead\";\n\n/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use\n/// this event to analyze how popular certain groups or social features are in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterGroupID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @\"join_group\";\n\n/// Level End event. Log this event when the user finishes a level. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevelName (NSString)</li>\n///     <li>@c kFIRParameterSuccess (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @\"level_end\";\n\n/// Level Start event. Log this event when the user starts a new level. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevelName (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @\"level_start\";\n\n/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can\n/// help you gauge the level distribution of your userbase and help you identify certain levels that\n/// are difficult to pass. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterCharacter (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @\"level_up\";\n\n/// Login event. Apps with a login feature can report this event to signify that a user has logged\n/// in.\nstatic NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @\"login\";\n\n/// Post Score event. Log this event when the user posts a score in your gaming app. This event can\n/// help you understand how users are actually performing in your game and it can help you correlate\n/// high scores with certain audiences or behaviors. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterScore (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCharacter (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @\"post_score\";\n\n/// Present Offer event. This event signifies that the app has presented a purchase offer to a user.\n/// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge\n/// your conversion process. Note: If you supply the @c kFIRParameterValue parameter, you must\n/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n///     <li>@c kFIRParameterItemName (NSString)</li>\n///     <li>@c kFIRParameterItemCategory (NSString)</li>\n///     <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventViewPromotion constant instead.</b>\nstatic NSString *const kFIREventPresentOffer NS_SWIFT_NAME(AnalyticsEventPresentOffer) =\n    @\"present_offer\";\n\n/// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded.\n/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n/// </ul>\n/// <b>This constant has been deprecated. Use @c kFIREventRefund constant instead.</b>\nstatic NSString *const kFIREventPurchaseRefund NS_SWIFT_NAME(AnalyticsEventPurchaseRefund) =\n    @\"purchase_refund\";\n\n/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart.\n/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the @c\n/// kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) =\n    @\"remove_from_cart\";\n\n/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs.\n/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterScreenClass (NSString) (optional)</li>\n///     <li>@c kFIRParameterScreenName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @\"screen_view\";\n\n/// Search event. Apps that support search features can use this event to contextualize search\n/// operations by supplying the appropriate, corresponding parameters. This event can help you\n/// identify the most popular content in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSearchTerm (NSString)</li>\n///     <li>@c kFIRParameterStartDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterEndDate (NSString) (optional)</li>\n///     <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for\n///         hotel bookings</li>\n///     <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)\n///         for travel bookings</li>\n///     <li>@c kFIRParameterOrigin (NSString) (optional)</li>\n///     <li>@c kFIRParameterDestination (NSString) (optional)</li>\n///     <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>\n/// </ul>\nstatic NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @\"search\";\n\n/// Select Content event. This general purpose event signifies that a user has selected some content\n/// of a certain type in an app. The content can be any object in your app. This event can help you\n/// identify popular content and categories of content in your app. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterContentType (NSString)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) =\n    @\"select_content\";\n\n/// Set checkout option. Params:\n///\n/// <ul>\n///    <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li>\n///    <li>@c kFIRParameterCheckoutOption (NSString)</li>\n/// </ul>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIREventSetCheckoutOption NS_SWIFT_NAME(AnalyticsEventSetCheckoutOption) =\n    @\"set_checkout_option\";\n\n/// Share event. Apps with social features can log the Share event to identify the most viral\n/// content. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterContentType (NSString)</li>\n///     <li>@c kFIRParameterItemID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @\"share\";\n\n/// Sign Up event. This event indicates that a user has signed up for an account in your app. The\n/// parameter signifies the method by which the user signed up. Use this event to understand the\n/// different behaviors between logged in and logged out users. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSignUpMethod (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @\"sign_up\";\n\n/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can\n/// help you identify which virtual goods are the most popular objects of purchase. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItemName (NSString)</li>\n///     <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>\n///     <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>\n/// </ul>\nstatic NSString *const kFIREventSpendVirtualCurrency\n    NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @\"spend_virtual_currency\";\n\n/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use\n/// this in a funnel with kFIREventTutorialComplete to understand how many users complete this\n/// process and move on to the full app experience.\nstatic NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) =\n    @\"tutorial_begin\";\n\n/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding\n/// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your\n/// on-boarding process.\nstatic NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) =\n    @\"tutorial_complete\";\n\n/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your\n/// game. Since achievements generally represent the breadth of a gaming experience, this event can\n/// help you understand how many users are experiencing all that your game has to offer. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAchievementID (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) =\n    @\"unlock_achievement\";\n\n/// View Item event. This event signifies that a user has viewed an item. Use the appropriate\n/// parameters to contextualize the event. Use this event to discover the most popular items viewed\n/// in your app. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @\"view_item\";\n\n/// View Item List event. Log this event when a user sees a list of items or offerings. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterItemListID (NSString) (optional)</li>\n///     <li>@c kFIRParameterItemListName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) =\n    @\"view_item_list\";\n\n/// View Search Results event. Log this event when the user has been presented with the results of a\n/// search. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterSearchTerm (NSString)</li>\n/// </ul>\nstatic NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) =\n    @\"view_search_results\";\n\n/// Add Shipping Info event. This event signifies that a user has submitted their shipping\n/// information. Note: If you supply the @c kFIRParameterValue parameter, you must also supply the\n/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShippingTier (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) =\n    @\"add_shipping_info\";\n\n/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note:\n/// This is different from the in-app purchase event, which is reported automatically for App\n/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also supply\n/// the @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.\n/// Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAffiliation (NSString) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @\"purchase\";\n\n/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the\n/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency parameter so\n/// that revenue metrics can be computed accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterAffiliation (NSString) (optional)</li>\n///     <li>@c kFIRParameterCoupon (NSString) (optional)</li>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>\n///     <li>@c kFIRParameterTransactionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @\"refund\";\n\n/// Select Item event. This event signifies that an item was selected by a user from a list. Use the\n/// appropriate parameters to contextualize the event. Use this event to discover the most popular\n/// items selected. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterItemListID (NSString) (optional)</li>\n///     <li>@c kFIRParameterItemListName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @\"select_item\";\n\n/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the\n/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion\n/// applies. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCreativeName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCreativeSlot (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) =\n    @\"select_promotion\";\n\n/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to\n/// analyze your purchase funnel. Note: If you supply the @c kFIRParameterValue parameter, you must\n/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed\n/// accurately. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCurrency (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @\"view_cart\";\n\n/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event\n/// to a funnel with the @c kFIREventAddToCart and @c kFIREventPurchase to gauge your conversion\n/// process. Params:\n///\n/// <ul>\n///     <li>@c kFIRParameterCreativeName (NSString) (optional)</li>\n///     <li>@c kFIRParameterCreativeSlot (NSString) (optional)</li>\n///     <li>@c kFIRParameterItems (NSArray) (optional)</li>\n///     <li>@c kFIRParameterLocationID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionID (NSString) (optional)</li>\n///     <li>@c kFIRParameterPromotionName (NSString) (optional)</li>\n/// </ul>\nstatic NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) =\n    @\"view_promotion\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h",
    "content": "/// @file FIRParameterNames.h\n///\n/// Predefined event parameter names.\n///\n/// Params supply information that contextualize Events. You can associate up to 25 unique Params\n/// with each Event type. Some Params are suggested below for certain common Events, but you are\n/// not limited to these. You may supply extra Params for suggested Events or custom Params for\n/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric\n/// characters and underscores (\"_\"), and must start with an alphabetic character. Param values can\n/// be up to 100 characters long. The \"firebase_\", \"google_\", and \"ga_\" prefixes are reserved and\n/// should not be used.\n\n#import <Foundation/Foundation.h>\n\n/// Game achievement ID (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAchievementID : @\"10_matches_won\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) =\n    @\"achievement_id\";\n\n/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream).\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdFormat : @\"Banner\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) =\n    @\"ad_format\";\n\n/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdNetworkClickID : @\"1234567\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdNetworkClickID\n    NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @\"aclid\";\n\n/// The ad platform (e.g. MoPub, IronSource) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdPlatform : @\"MoPub\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) =\n    @\"ad_platform\";\n\n/// The ad source (e.g. AdColony) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdSource : @\"AdColony\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) =\n    @\"ad_source\";\n\n/// The ad unit name (e.g. Banner_03) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAdUnitName : @\"Banner_03\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) =\n    @\"ad_unit_name\";\n\n/// A product affiliation to designate a supplying company or brick and mortar store location\n/// (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterAffiliation : @\"Google Store\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) =\n    @\"affiliation\";\n\n/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to\n/// capture campaign information, otherwise can be populated by developer. Highly Recommended\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCampaign : @\"winter_promotion\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) =\n    @\"campaign\";\n\n/// Character used in game (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCharacter : @\"beat_boss\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) =\n    @\"character\";\n\n/// The checkout step (1..N) (unsigned 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCheckoutStep : @\"1\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIRParameterCheckoutStep NS_SWIFT_NAME(AnalyticsParameterCheckoutStep) =\n    @\"checkout_step\";\n\n/// Some option on a step in an ecommerce flow (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCheckoutOption : @\"Visa\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated.</b>\nstatic NSString *const kFIRParameterCheckoutOption\n    NS_SWIFT_NAME(AnalyticsParameterCheckoutOption) = @\"checkout_option\";\n\n/// Campaign content (NSString).\nstatic NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @\"content\";\n\n/// Type of content selected (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterContentType : @\"news article\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) =\n    @\"content_type\";\n\n/// Coupon code used for a purchase (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCoupon : @\"SUMMER_FUN\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @\"coupon\";\n\n/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign.\n/// Use varies by network.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCP1 : @\"custom_data\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @\"cp1\";\n\n/// The name of a creative used in a promotional spot (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCreativeName : @\"Summer Sale\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) =\n    @\"creative_name\";\n\n/// The name of a creative slot (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCreativeSlot : @\"summer_banner2\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) =\n    @\"creative_slot\";\n\n/// Currency of the purchase or items associated with the event, in 3-letter\n/// <a href=\"http://en.wikipedia.org/wiki/ISO_4217#Active_codes\"> ISO_4217</a> format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterCurrency : @\"USD\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) =\n    @\"currency\";\n\n/// Flight or Travel destination (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterDestination : @\"Mountain View, CA\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) =\n    @\"destination\";\n\n/// The arrival date, check-out date or rental end date for the item. This should be in\n/// YYYY-MM-DD format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterEndDate : @\"2015-09-14\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @\"end_date\";\n\n/// Flight number for travel events (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterFlightNumber : @\"ZZ800\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) =\n    @\"flight_number\";\n\n/// Group/clan/guild ID (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterGroupID : @\"g1\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @\"group_id\";\n\n/// The index of the item in a list (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterIndex : @(5),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @\"index\";\n\n/// Item brand (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemBrand : @\"Google\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) =\n    @\"item_brand\";\n\n/// Item category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) =\n    @\"item_category\";\n\n/// Item ID (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemID : @\"SKU_12345\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @\"item_id\";\n\n/// The Google <a href=\"https://developers.google.com/places/place-id\">Place ID</a> (NSString) that\n/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemLocationID : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated. Use @c kFIRParameterLocationID constant instead.</b>\nstatic NSString *const kFIRParameterItemLocationID\n    NS_SWIFT_NAME(AnalyticsParameterItemLocationID) = @\"item_location_id\";\n\n/// Item Name (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemName : @\"jeggings\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) =\n    @\"item_name\";\n\n/// The list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemList : @\"Search Results\",\n///       // ...\n///     };\n/// </pre>\n/// <b>This constant has been deprecated. Use @c kFIRParameterItemListName constant instead.</b>\nstatic NSString *const kFIRParameterItemList NS_SWIFT_NAME(AnalyticsParameterItemList) =\n    @\"item_list\";\n\n/// Item variant (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemVariant : @\"Black\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) =\n    @\"item_variant\";\n\n/// Level in game (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLevel : @(42),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @\"level\";\n\n/// Location (NSString). The Google <a href=\"https://developers.google.com/places/place-id\">Place ID\n/// </a> that corresponds to the associated event. Alternatively, you can supply your own custom\n/// Location ID.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLocation : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) =\n    @\"location\";\n\n/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterMedium : @\"email\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @\"medium\";\n\n/// Number of nights staying at hotel (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfNights : @(3),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfNights\n    NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @\"number_of_nights\";\n\n/// Number of passengers traveling (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfPassengers : @(11),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfPassengers\n    NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @\"number_of_passengers\";\n\n/// Number of rooms for travel events (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterNumberOfRooms : @(2),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) =\n    @\"number_of_rooms\";\n\n/// Flight or Travel origin (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterOrigin : @\"Mountain View, CA\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @\"origin\";\n\n/// Purchase price (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPrice : @(1.0),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $1.00 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @\"price\";\n\n/// Purchase quantity (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterQuantity : @(1),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) =\n    @\"quantity\";\n\n/// Score in game (signed 64-bit integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScore : @(4200),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @\"score\";\n\n/// Current screen class, such as the class name of the UIViewController, logged with screen_view\n/// event and added to every event (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScreenClass : @\"LoginViewController\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) =\n    @\"screen_class\";\n\n/// Current screen name, such as the name of the UIViewController, logged with screen_view event and\n/// added to every event (NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterScreenName : @\"LoginView\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) =\n    @\"screen_name\";\n\n/// The search string/keywords used (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSearchTerm : @\"periodic table\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) =\n    @\"search_term\";\n\n/// Shipping cost associated with a transaction (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterShipping : @(5.99),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $5.99 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) =\n    @\"shipping\";\n\n/// Sign up method (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSignUpMethod : @\"google\",\n///       // ...\n///     };\n/// </pre>\n///\n/// <b>This constant has been deprecated. Use Method constant instead.</b>\nstatic NSString *const kFIRParameterSignUpMethod NS_SWIFT_NAME(AnalyticsParameterSignUpMethod) =\n    @\"sign_up_method\";\n\n/// A particular approach used in an operation; for example, \"facebook\" or \"email\" in the context\n/// of a sign_up or login event.  (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterMethod : @\"google\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @\"method\";\n\n/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban\n/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your\n/// property. Highly recommended (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSource : @\"InMobi\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @\"source\";\n\n/// The departure date, check-in date or rental start date for the item. This should be in\n/// YYYY-MM-DD format (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterStartDate : @\"2015-09-14\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) =\n    @\"start_date\";\n\n/// Tax cost associated with a transaction (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTax : @(2.43),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $2.43 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @\"tax\";\n\n/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTerm : @\"game\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @\"term\";\n\n/// The unique identifier of a transaction (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTransactionID : @\"T12345\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) =\n    @\"transaction_id\";\n\n/// Travel class (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterTravelClass : @\"business\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) =\n    @\"travel_class\";\n\n/// A context-specific numeric value which is accumulated automatically for each event type. This is\n/// a general purpose parameter that is useful for accumulating a key metric that pertains to an\n/// event. Examples include revenue, distance, time and points. Value should be specified as signed\n/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events\n/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be\n/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is\n/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the\n/// corresponding @c kFIRParameterCurrency parameter, or supplying an invalid\n/// <a href=\"https://goo.gl/qqX3J2\">currency code</a> for conversion events will cause that\n/// conversion to be omitted from reporting.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterValue : @(3.99),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $3.99 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @\"value\";\n\n/// Name of virtual currency type (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterVirtualCurrencyName : @\"virtual_currency_name\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterVirtualCurrencyName\n    NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @\"virtual_currency_name\";\n\n/// The name of a level in a game (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLevelName : @\"room_1\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) =\n    @\"level_name\";\n\n/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (unsigned\n/// integer as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterSuccess : @(1),\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @\"success\";\n\n/// Indicates that the associated event should either extend the current session\n/// or start a new session if no session was active when the event was logged.\n/// Specify YES to extend the current session or to start a new session; any\n/// other value will not extend or start a session.\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterExtendSession : @YES,\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) =\n    @\"extend_session\";\n\n/// Monetary value of discount associated with a purchase (double as NSNumber).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterDiscount : @(2.0),\n///       kFIRParameterCurrency : @\"USD\",  // e.g. $2.00 USD\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) =\n    @\"discount\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory2 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) =\n    @\"item_category2\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory3 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) =\n    @\"item_category3\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory4 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) =\n    @\"item_category4\";\n\n/// Item Category (context-specific) (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemCategory5 : @\"pants\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) =\n    @\"item_category5\";\n\n/// The ID of the list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemListID : @\"ABC123\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) =\n    @\"item_list_id\";\n\n/// The name of the list in which the item was presented to the user (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItemListName : @\"Related products\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) =\n    @\"item_list_name\";\n\n/// The list of items involved in the transaction. (NSArray).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterItems : @[\n///         @{kFIRParameterItemName : @\"jeggings\", kFIRParameterItemCategory : @\"pants\"},\n///         @{kFIRParameterItemName : @\"boots\", kFIRParameterItemCategory : @\"shoes\"},\n///       ],\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @\"items\";\n\n/// The location associated with the event. Preferred to be the Google\n/// <a href=\"https://developers.google.com/places/place-id\">Place ID</a> that corresponds to the\n/// associated item but could be overridden to a custom location ID string.(NSString). <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterLocationID : @\"ChIJiyj437sx3YAR9kUWC8QkLzQ\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) =\n    @\"location_id\";\n\n/// The chosen method of payment (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPaymentType : @\"Visa\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) =\n    @\"payment_type\";\n\n/// The ID of a product promotion (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPromotionID : @\"ABC123\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) =\n    @\"promotion_id\";\n\n/// The name of a product promotion (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterPromotionName : @\"Summer Sale\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) =\n    @\"promotion_name\";\n\n/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item\n/// (NSString).\n/// <pre>\n///     NSDictionary *params = @{\n///       kFIRParameterShippingTier : @\"Ground\",\n///       // ...\n///     };\n/// </pre>\nstatic NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) =\n    @\"shipping_tier\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h",
    "content": "/// @file FIRUserPropertyNames.h\n///\n/// Predefined user property names.\n///\n/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can\n/// later analyze different behaviors of various segments of your userbase. You may supply up to 25\n/// unique UserProperties per app, and you can use the name and value of your choosing for each one.\n/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and\n/// underscores (\"_\"), and must start with an alphabetic character. UserProperty values can be up to\n/// 36 characters long. The \"firebase_\", \"google_\", and \"ga_\" prefixes are reserved and should not\n/// be used.\n\n#import <Foundation/Foundation.h>\n\n/// The method used to sign in. For example, \"google\", \"facebook\" or \"twitter\".\nstatic NSString *const kFIRUserPropertySignUpMethod\n    NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @\"sign_up_method\";\n\n/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user.\n/// Set to \"YES\" to enable, or \"NO\" to disable. Default is enabled. See the\n/// <a href=\"https://firebase.google.com/support/guides/disable-analytics\">documentation</a> for\n/// more details and information about related settings.\n///\n/// <pre>\n///     [FIRAnalytics setUserPropertyString:@\"NO\"\n///                                 forName:kFIRUserPropertyAllowAdPersonalizationSignals];\n/// </pre>\nstatic NSString *const kFIRUserPropertyAllowAdPersonalizationSignals\n    NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @\"allow_personalized_ads\";\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h",
    "content": "#import \"FIRAnalytics+AppDelegate.h\"\n#import \"FIRAnalytics+Consent.h\"\n#import \"FIRAnalytics.h\"\n#import \"FIREventNames.h\"\n#import \"FIRParameterNames.h\"\n#import \"FIRUserPropertyNames.h\"\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Info.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>CFBundleExecutable</key>\n\t<string>FirebaseAnalytics</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.firebase.Firebase-FirebaseAnalytics</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>FirebaseAnalytics</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleVersion</key>\n\t<string>8.3.0</string>\n\t<key>DTSDKName</key>\n\t<string>iphonesimulator11.2</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap",
    "content": "framework module FirebaseAnalytics {\numbrella header \"FirebaseAnalytics.h\"\nexport *\nmodule * { export * }\n  link framework \"CoreTelephony\"\n  link framework \"Foundation\"\n  link framework \"Security\"\n  link framework \"SystemConfiguration\"\n  link framework \"UIKit\"\n  link \"c++\"\n  link \"sqlite3\"\n  link \"z\"\n}\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/// Values stored in analyticsEnabledState. Never alter these constants since they must match with\n/// values persisted to disk.\ntypedef NS_ENUM(int64_t, FIRAnalyticsEnabledState) {\n  // 0 is the default value for keys not found stored in persisted config, so it cannot represent\n  // kFIRAnalyticsEnabledStateSetNo. It must represent kFIRAnalyticsEnabledStateNotSet.\n  kFIRAnalyticsEnabledStateNotSet = 0,\n  kFIRAnalyticsEnabledStateSetYes = 1,\n  kFIRAnalyticsEnabledStateSetNo = 2,\n};\n\n/// The user defaults key for the persisted measurementEnabledState value. FIRAPersistedConfig reads\n/// measurementEnabledState using this same key.\nstatic NSString *const kFIRAPersistedConfigMeasurementEnabledStateKey =\n    @\"/google/measurement/measurement_enabled_state\";\n\nstatic NSString *const kFIRAnalyticsConfigurationSetEnabledNotification =\n    @\"FIRAnalyticsConfigurationSetEnabledNotification\";\nstatic NSString *const kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification =\n    @\"FIRAnalyticsConfigurationSetMinimumSessionIntervalNotification\";\nstatic NSString *const kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification =\n    @\"FIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification\";\n\n@interface FIRAnalyticsConfiguration : NSObject\n\n/// Returns the shared instance of FIRAnalyticsConfiguration.\n+ (FIRAnalyticsConfiguration *)sharedInstance;\n\n// Sets whether analytics collection is enabled for this app on this device. This setting is\n// persisted across app sessions. By default it is enabled.\n- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;\n\n/// Sets whether analytics collection is enabled for this app on this device, and a flag to persist\n/// the value or not. The setting should not be persisted if being set by the global data collection\n/// flag.\n- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled\n                       persistSetting:(BOOL)shouldPersist;\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseCore/Sources/FIRAnalyticsConfiguration.h\"\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n@implementation FIRAnalyticsConfiguration\n#pragma clang diagnostic pop\n\n+ (FIRAnalyticsConfiguration *)sharedInstance {\n  static FIRAnalyticsConfiguration *sharedInstance = nil;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[FIRAnalyticsConfiguration alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (void)postNotificationName:(NSString *)name value:(id)value {\n  if (!name.length || !value) {\n    return;\n  }\n  [[NSNotificationCenter defaultCenter] postNotificationName:name\n                                                      object:self\n                                                    userInfo:@{name : value}];\n}\n\n- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled {\n  [self setAnalyticsCollectionEnabled:analyticsCollectionEnabled persistSetting:YES];\n}\n\n- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled\n                       persistSetting:(BOOL)shouldPersist {\n  // Persist the measurementEnabledState. Use FIRAnalyticsEnabledState values instead of YES/NO.\n  FIRAnalyticsEnabledState analyticsEnabledState =\n      analyticsCollectionEnabled ? kFIRAnalyticsEnabledStateSetYes : kFIRAnalyticsEnabledStateSetNo;\n  if (shouldPersist) {\n    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];\n    [userDefaults setObject:@(analyticsEnabledState)\n                     forKey:kFIRAPersistedConfigMeasurementEnabledStateKey];\n    [userDefaults synchronize];\n  }\n\n  [self postNotificationName:kFIRAnalyticsConfigurationSetEnabledNotification\n                       value:@(analyticsCollectionEnabled)];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <sys/utsname.h>\n\n#if __has_include(<UIKit/UIKit.h>)\n#import <UIKit/UIKit.h>\n#endif\n\n#if __has_include(<AppKit/AppKit.h>)\n#import <AppKit/AppKit.h>\n#endif\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h\"\n\n#import \"FirebaseCore/Sources/FIRAnalyticsConfiguration.h\"\n#import \"FirebaseCore/Sources/FIRBundleUtil.h\"\n#import \"FirebaseCore/Sources/FIRComponentContainerInternal.h\"\n#import \"FirebaseCore/Sources/FIRConfigurationInternal.h\"\n#import \"FirebaseCore/Sources/FIRFirebaseUserAgent.h\"\n\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h\"\n#import \"FirebaseCore/Sources/Private/FIRLibrary.h\"\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h\"\n\n#import <GoogleUtilities/GULAppEnvironmentUtil.h>\n\n#import <objc/runtime.h>\n\n// The kFIRService strings are only here while transitioning CoreDiagnostics from the Analytics\n// pod to a Core dependency. These symbols are not used and should be deleted after the transition.\nNSString *const kFIRServiceAdMob;\nNSString *const kFIRServiceAuth;\nNSString *const kFIRServiceAuthUI;\nNSString *const kFIRServiceCrash;\nNSString *const kFIRServiceDatabase;\nNSString *const kFIRServiceDynamicLinks;\nNSString *const kFIRServiceFirestore;\nNSString *const kFIRServiceFunctions;\nNSString *const kFIRServiceInstanceID;\nNSString *const kFIRServiceInvites;\nNSString *const kFIRServiceMessaging;\nNSString *const kFIRServiceMeasurement;\nNSString *const kFIRServicePerformance;\nNSString *const kFIRServiceRemoteConfig;\nNSString *const kFIRServiceStorage;\nNSString *const kGGLServiceAnalytics;\nNSString *const kGGLServiceSignIn;\n\nNSString *const kFIRDefaultAppName = @\"__FIRAPP_DEFAULT\";\nNSString *const kFIRAppReadyToConfigureSDKNotification = @\"FIRAppReadyToConfigureSDKNotification\";\nNSString *const kFIRAppDeleteNotification = @\"FIRAppDeleteNotification\";\nNSString *const kFIRAppIsDefaultAppKey = @\"FIRAppIsDefaultAppKey\";\nNSString *const kFIRAppNameKey = @\"FIRAppNameKey\";\nNSString *const kFIRGoogleAppIDKey = @\"FIRGoogleAppIDKey\";\n\nNSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat =\n    @\"/google/firebase/global_data_collection_enabled:%@\";\nNSString *const kFIRGlobalAppDataCollectionEnabledPlistKey =\n    @\"FirebaseDataCollectionDefaultEnabled\";\n\nNSString *const kFIRAppDiagnosticsConfigurationTypeKey = @\"ConfigType\";\nNSString *const kFIRAppDiagnosticsErrorKey = @\"Error\";\nNSString *const kFIRAppDiagnosticsFIRAppKey = @\"FIRApp\";\nNSString *const kFIRAppDiagnosticsSDKNameKey = @\"SDKName\";\nNSString *const kFIRAppDiagnosticsSDKVersionKey = @\"SDKVersion\";\nNSString *const kFIRAppDiagnosticsApplePlatformPrefix = @\"apple-platform\";\n\n// Auth internal notification notification and key.\nNSString *const FIRAuthStateDidChangeInternalNotification =\n    @\"FIRAuthStateDidChangeInternalNotification\";\nNSString *const FIRAuthStateDidChangeInternalNotificationAppKey =\n    @\"FIRAuthStateDidChangeInternalNotificationAppKey\";\nNSString *const FIRAuthStateDidChangeInternalNotificationTokenKey =\n    @\"FIRAuthStateDidChangeInternalNotificationTokenKey\";\nNSString *const FIRAuthStateDidChangeInternalNotificationUIDKey =\n    @\"FIRAuthStateDidChangeInternalNotificationUIDKey\";\n\n/**\n * Error domain for exceptions and NSError construction.\n */\nNSString *const kFirebaseCoreErrorDomain = @\"com.firebase.core\";\n\n/** The NSUserDefaults suite name for FirebaseCore, for those storage locations that use it. */\nNSString *const kFirebaseCoreDefaultsSuiteName = @\"com.firebase.core\";\n\n/**\n * The URL to download plist files.\n */\nstatic NSString *const kPlistURL = @\"https://console.firebase.google.com/\";\n\n/**\n * An array of all classes that registered as `FIRCoreConfigurable` in order to receive lifecycle\n * events from Core.\n */\nstatic NSMutableArray<Class<FIRLibrary>> *sRegisteredAsConfigurable;\n\n@interface FIRApp ()\n\n#ifdef DEBUG\n@property(nonatomic) BOOL alreadyOutputDataCollectionFlag;\n#endif  // DEBUG\n\n@end\n\n@implementation FIRApp\n\n// This is necessary since our custom getter prevents `_options` from being created.\n@synthesize options = _options;\n\nstatic NSMutableDictionary *sAllApps;\nstatic FIRApp *sDefaultApp;\n\n+ (void)configure {\n  FIROptions *options = [FIROptions defaultOptions];\n  if (!options) {\n    [NSException raise:kFirebaseCoreErrorDomain\n                format:@\"`FirebaseApp.configure()` could not find \"\n                       @\"a valid GoogleService-Info.plist in your project. Please download one \"\n                       @\"from %@.\",\n                       kPlistURL];\n  }\n  [FIRApp configureWithOptions:options];\n#if TARGET_OS_OSX || TARGET_OS_TV\n  FIRLogNotice(kFIRLoggerCore, @\"I-COR000028\",\n               @\"tvOS and macOS SDK support is not part of the official Firebase product. \"\n               @\"Instead they are community supported. Details at \"\n               @\"https://github.com/firebase/firebase-ios-sdk/blob/master/README.md.\");\n#endif\n}\n\n+ (void)configureWithOptions:(FIROptions *)options {\n  if (!options) {\n    [NSException raise:kFirebaseCoreErrorDomain\n                format:@\"Options is nil. Please pass a valid options.\"];\n  }\n  [FIRApp configureWithName:kFIRDefaultAppName options:options];\n}\n\n+ (NSCharacterSet *)applicationNameAllowedCharacters {\n  static NSCharacterSet *applicationNameAllowedCharacters;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    NSMutableCharacterSet *allowedNameCharacters = [NSMutableCharacterSet alphanumericCharacterSet];\n    [allowedNameCharacters addCharactersInString:@\"-_\"];\n    applicationNameAllowedCharacters = [allowedNameCharacters copy];\n  });\n  return applicationNameAllowedCharacters;\n}\n\n+ (void)configureWithName:(NSString *)name options:(FIROptions *)options {\n  if (!name || !options) {\n    [NSException raise:kFirebaseCoreErrorDomain format:@\"Neither name nor options can be nil.\"];\n  }\n  if (name.length == 0) {\n    [NSException raise:kFirebaseCoreErrorDomain format:@\"Name cannot be empty.\"];\n  }\n\n  if ([name isEqualToString:kFIRDefaultAppName]) {\n    if (sDefaultApp) {\n      // The default app already exists. Handle duplicate `configure` calls and return.\n      [self appWasConfiguredTwice:sDefaultApp usingOptions:options];\n      return;\n    }\n\n    FIRLogDebug(kFIRLoggerCore, @\"I-COR000001\", @\"Configuring the default app.\");\n  } else {\n    // Validate the app name and ensure it hasn't been configured already.\n    NSCharacterSet *nameCharacters = [NSCharacterSet characterSetWithCharactersInString:name];\n\n    if (![[self applicationNameAllowedCharacters] isSupersetOfSet:nameCharacters]) {\n      [NSException raise:kFirebaseCoreErrorDomain\n                  format:@\"App name can only contain alphanumeric, \"\n                         @\"hyphen (-), and underscore (_) characters\"];\n    }\n\n    @synchronized(self) {\n      if (sAllApps && sAllApps[name]) {\n        // The app already exists. Handle a duplicate `configure` call and return.\n        [self appWasConfiguredTwice:sAllApps[name] usingOptions:options];\n        return;\n      }\n    }\n\n    FIRLogDebug(kFIRLoggerCore, @\"I-COR000002\", @\"Configuring app named %@\", name);\n  }\n\n  @synchronized(self) {\n    FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];\n    if (app.isDefaultApp) {\n      sDefaultApp = app;\n    }\n\n    [FIRApp addAppToAppDictionary:app];\n\n    // The FIRApp instance is ready to go, `sDefaultApp` is assigned, other SDKs are now ready to be\n    // instantiated.\n    [app.container instantiateEagerComponents];\n    [FIRApp sendNotificationsToSDKs:app];\n  }\n}\n\n/// Called when `configure` has been called multiple times for the same app. This can either throw\n/// an exception (most cases) or ignore the duplicate configuration in situations where it's allowed\n/// like an extension.\n+ (void)appWasConfiguredTwice:(FIRApp *)app usingOptions:(FIROptions *)options {\n  // Only extensions should potentially be able to call `configure` more than once.\n  if (![GULAppEnvironmentUtil isAppExtension]) {\n    // Throw an exception since this is now an invalid state.\n    if (app.isDefaultApp) {\n      [NSException raise:kFirebaseCoreErrorDomain\n                  format:@\"Default app has already been configured.\"];\n    } else {\n      [NSException raise:kFirebaseCoreErrorDomain\n                  format:@\"App named %@ has already been configured.\", app.name];\n    }\n  }\n\n  // In an extension, the entry point could be called multiple times. As long as the options are\n  // identical we should allow multiple `configure` calls.\n  if ([options isEqual:app.options]) {\n    // Everything is identical but the extension's lifecycle triggered `configure` twice.\n    // Ignore duplicate calls and return since everything should still be in a valid state.\n    FIRLogDebug(kFIRLoggerCore, @\"I-COR000035\",\n                @\"Ignoring second `configure` call in an extension.\");\n    return;\n  } else {\n    [NSException raise:kFirebaseCoreErrorDomain\n                format:@\"App named %@ has already been configured.\", app.name];\n  }\n}\n\n+ (FIRApp *)defaultApp {\n  if (sDefaultApp) {\n    return sDefaultApp;\n  }\n  FIRLogError(kFIRLoggerCore, @\"I-COR000003\",\n              @\"The default Firebase app has not yet been \"\n              @\"configured. Add `FirebaseApp.configure()` to your \"\n              @\"application initialization. This can be done in \"\n              @\"in the App Delegate's application(_:didFinishLaunchingWithOptions:)` \"\n              @\"(or the `@main` struct's initializer in SwiftUI). \"\n              @\"Read more: https://goo.gl/ctyzm8.\");\n  return nil;\n}\n\n+ (FIRApp *)appNamed:(NSString *)name {\n  @synchronized(self) {\n    if (sAllApps) {\n      FIRApp *app = sAllApps[name];\n      if (app) {\n        return app;\n      }\n    }\n    FIRLogError(kFIRLoggerCore, @\"I-COR000004\", @\"App with name %@ does not exist.\", name);\n    return nil;\n  }\n}\n\n+ (NSDictionary *)allApps {\n  @synchronized(self) {\n    if (!sAllApps) {\n      FIRLogError(kFIRLoggerCore, @\"I-COR000005\", @\"No app has been configured yet.\");\n    }\n    return [sAllApps copy];\n  }\n}\n\n// Public only for tests\n+ (void)resetApps {\n  @synchronized(self) {\n    sDefaultApp = nil;\n    [sAllApps removeAllObjects];\n    sAllApps = nil;\n    [[self userAgent] reset];\n  }\n}\n\n- (void)deleteApp:(FIRAppVoidBoolCallback)completion {\n  @synchronized([self class]) {\n    if (sAllApps && sAllApps[self.name]) {\n      FIRLogDebug(kFIRLoggerCore, @\"I-COR000006\", @\"Deleting app named %@\", self.name);\n\n      // Remove all registered libraries from the container to avoid creating new instances.\n      [self.container removeAllComponents];\n      // Remove all cached instances from the container before deleting the app.\n      [self.container removeAllCachedInstances];\n\n      [sAllApps removeObjectForKey:self.name];\n      [self clearDataCollectionSwitchFromUserDefaults];\n      if ([self.name isEqualToString:kFIRDefaultAppName]) {\n        sDefaultApp = nil;\n      }\n      NSDictionary *appInfoDict = @{kFIRAppNameKey : self.name};\n      [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDeleteNotification\n                                                          object:[self class]\n                                                        userInfo:appInfoDict];\n      completion(YES);\n    } else {\n      FIRLogError(kFIRLoggerCore, @\"I-COR000007\", @\"App does not exist.\");\n      completion(NO);\n    }\n  }\n}\n\n+ (void)addAppToAppDictionary:(FIRApp *)app {\n  if (!sAllApps) {\n    sAllApps = [NSMutableDictionary dictionary];\n  }\n  if ([app configureCore]) {\n    sAllApps[app.name] = app;\n  } else {\n    [NSException raise:kFirebaseCoreErrorDomain\n                format:@\"Configuration fails. It may be caused by an invalid GOOGLE_APP_ID in \"\n                       @\"GoogleService-Info.plist or set in the customized options.\"];\n  }\n}\n\n- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options {\n  self = [super init];\n  if (self) {\n    _name = [name copy];\n    _options = [options copy];\n    _options.editingLocked = YES;\n    _isDefaultApp = [name isEqualToString:kFIRDefaultAppName];\n    _container = [[FIRComponentContainer alloc] initWithApp:self];\n  }\n  return self;\n}\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (BOOL)configureCore {\n  [self checkExpectedBundleID];\n  if (![self isAppIDValid]) {\n    return NO;\n  }\n\n  // Initialize the Analytics once there is a valid options under default app. Analytics should\n  // always initialize first by itself before the other SDKs.\n  if ([self.name isEqualToString:kFIRDefaultAppName]) {\n    Class firAnalyticsClass = NSClassFromString(@\"FIRAnalytics\");\n    if (firAnalyticsClass) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wundeclared-selector\"\n      SEL startWithConfigurationSelector = @selector(startWithConfiguration:options:);\n#pragma clang diagnostic pop\n      if ([firAnalyticsClass respondsToSelector:startWithConfigurationSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n        [firAnalyticsClass performSelector:startWithConfigurationSelector\n                                withObject:[FIRConfiguration sharedInstance].analyticsConfiguration\n                                withObject:_options];\n#pragma clang diagnostic pop\n      }\n    }\n  }\n\n  [self subscribeForAppDidBecomeActiveNotifications];\n\n  return YES;\n}\n\n- (FIROptions *)options {\n  return [_options copy];\n}\n\n- (void)setDataCollectionDefaultEnabled:(BOOL)dataCollectionDefaultEnabled {\n#ifdef DEBUG\n  FIRLogDebug(kFIRLoggerCore, @\"I-COR000034\", @\"Explicitly %@ data collection flag.\",\n              dataCollectionDefaultEnabled ? @\"enabled\" : @\"disabled\");\n  self.alreadyOutputDataCollectionFlag = YES;\n#endif  // DEBUG\n\n  NSString *key =\n      [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name];\n  [[NSUserDefaults standardUserDefaults] setBool:dataCollectionDefaultEnabled forKey:key];\n\n  // Core also controls the FirebaseAnalytics flag, so check if the Analytics flags are set\n  // within FIROptions and change the Analytics value if necessary. Analytics only works with the\n  // default app, so return if this isn't the default app.\n  if (!self.isDefaultApp) {\n    return;\n  }\n\n  // Check if the Analytics flag is explicitly set. If so, no further actions are necessary.\n  if ([self.options isAnalyticsCollectionExplicitlySet]) {\n    return;\n  }\n\n  // The Analytics flag has not been explicitly set, so update with the value being set.\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n  [[FIRAnalyticsConfiguration sharedInstance]\n    setAnalyticsCollectionEnabled:dataCollectionDefaultEnabled\n                   persistSetting:NO];\n#pragma clang diagnostic pop\n}\n\n- (BOOL)isDataCollectionDefaultEnabled {\n  // Check if it's been manually set before in code, and use that as the higher priority value.\n  NSNumber *defaultsObject = [[self class] readDataCollectionSwitchFromUserDefaultsForApp:self];\n  if (defaultsObject != nil) {\n#ifdef DEBUG\n    if (!self.alreadyOutputDataCollectionFlag) {\n      FIRLogDebug(kFIRLoggerCore, @\"I-COR000031\", @\"Data Collection flag is %@ in user defaults.\",\n                  [defaultsObject boolValue] ? @\"enabled\" : @\"disabled\");\n      self.alreadyOutputDataCollectionFlag = YES;\n    }\n#endif  // DEBUG\n    return [defaultsObject boolValue];\n  }\n\n  // Read the Info.plist to see if the flag is set. If it's not set, it should default to `YES`.\n  // As per the implementation of `readDataCollectionSwitchFromPlist`, it's a cached value and has\n  // no performance impact calling multiple times.\n  NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist];\n  if (collectionEnabledPlistValue != nil) {\n#ifdef DEBUG\n    if (!self.alreadyOutputDataCollectionFlag) {\n      FIRLogDebug(kFIRLoggerCore, @\"I-COR000032\", @\"Data Collection flag is %@ in plist.\",\n                  [collectionEnabledPlistValue boolValue] ? @\"enabled\" : @\"disabled\");\n      self.alreadyOutputDataCollectionFlag = YES;\n    }\n#endif  // DEBUG\n    return [collectionEnabledPlistValue boolValue];\n  }\n\n#ifdef DEBUG\n  if (!self.alreadyOutputDataCollectionFlag) {\n    FIRLogDebug(kFIRLoggerCore, @\"I-COR000033\", @\"Data Collection flag is not set.\");\n    self.alreadyOutputDataCollectionFlag = YES;\n  }\n#endif  // DEBUG\n  return YES;\n}\n\n#pragma mark - private\n\n+ (void)sendNotificationsToSDKs:(FIRApp *)app {\n  // TODO: Remove this notification once all SDKs are registered with `FIRCoreConfigurable`.\n  NSNumber *isDefaultApp = [NSNumber numberWithBool:app.isDefaultApp];\n  NSDictionary *appInfoDict = @{\n    kFIRAppNameKey : app.name,\n    kFIRAppIsDefaultAppKey : isDefaultApp,\n    kFIRGoogleAppIDKey : app.options.googleAppID\n  };\n  [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppReadyToConfigureSDKNotification\n                                                      object:self\n                                                    userInfo:appInfoDict];\n\n  // This is the new way of sending information to SDKs.\n  // TODO: Do we want this on a background thread, maybe?\n  @synchronized(self) {\n    for (Class<FIRLibrary> library in sRegisteredAsConfigurable) {\n      [library configureWithApp:app];\n    }\n  }\n}\n\n+ (NSError *)errorForMissingOptions {\n  NSDictionary *errorDict = @{\n    NSLocalizedDescriptionKey :\n        @\"Unable to parse GoogleService-Info.plist in order to configure services.\",\n    NSLocalizedRecoverySuggestionErrorKey :\n        @\"Check formatting and location of GoogleService-Info.plist.\"\n  };\n  return [NSError errorWithDomain:kFirebaseCoreErrorDomain code:-100 userInfo:errorDict];\n}\n\n+ (NSError *)errorForInvalidAppID {\n  NSDictionary *errorDict = @{\n    NSLocalizedDescriptionKey : @\"Unable to validate Google App ID\",\n    NSLocalizedRecoverySuggestionErrorKey :\n        @\"Check formatting and location of GoogleService-Info.plist or GoogleAppID set in the \"\n        @\"customized options.\"\n  };\n  return [NSError errorWithDomain:kFirebaseCoreErrorDomain code:-101 userInfo:errorDict];\n}\n\n+ (BOOL)isDefaultAppConfigured {\n  return (sDefaultApp != nil);\n}\n\n+ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version {\n  // Create the set of characters which aren't allowed, only if this feature is used.\n  NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet alphanumericCharacterSet];\n  [allowedSet addCharactersInString:@\"-_.\"];\n  NSCharacterSet *disallowedSet = [allowedSet invertedSet];\n  // Make sure the library name and version strings do not contain unexpected characters, and\n  // add the name/version pair to the dictionary.\n  if ([name rangeOfCharacterFromSet:disallowedSet].location == NSNotFound &&\n      [version rangeOfCharacterFromSet:disallowedSet].location == NSNotFound) {\n    [[self userAgent] setValue:version forComponent:name];\n  } else {\n    FIRLogError(kFIRLoggerCore, @\"I-COR000027\",\n                @\"The library name (%@) or version number (%@) contain invalid characters. \"\n                @\"Only alphanumeric, dash, underscore and period characters are allowed.\",\n                name, version);\n  }\n}\n\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name {\n  [self registerInternalLibrary:library withName:name withVersion:FIRFirebaseVersion()];\n}\n\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name\n                    withVersion:(nonnull NSString *)version {\n  // This is called at +load time, keep the work to a minimum.\n\n  // Ensure the class given conforms to the proper protocol.\n  if (![(Class)library conformsToProtocol:@protocol(FIRLibrary)] ||\n      ![(Class)library respondsToSelector:@selector(componentsToRegister)]) {\n    [NSException raise:NSInvalidArgumentException\n                format:@\"Class %@ attempted to register components, but it does not conform to \"\n                       @\"`FIRLibrary or provide a `componentsToRegister:` method.\",\n                       library];\n  }\n\n  [FIRComponentContainer registerAsComponentRegistrant:library];\n  if ([(Class)library respondsToSelector:@selector(configureWithApp:)]) {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n      sRegisteredAsConfigurable = [[NSMutableArray alloc] init];\n    });\n    @synchronized(self) {\n      [sRegisteredAsConfigurable addObject:library];\n    }\n  }\n  [self registerLibrary:name withVersion:version];\n}\n\n+ (FIRFirebaseUserAgent *)userAgent {\n  static dispatch_once_t onceToken;\n  static FIRFirebaseUserAgent *_userAgent;\n  dispatch_once(&onceToken, ^{\n    _userAgent = [[FIRFirebaseUserAgent alloc] init];\n    [_userAgent setValue:FIRFirebaseVersion() forComponent:@\"fire-ios\"];\n  });\n  return _userAgent;\n}\n\n+ (NSString *)firebaseUserAgent {\n  return [[self userAgent] firebaseUserAgent];\n}\n\n- (void)checkExpectedBundleID {\n  NSArray *bundles = [FIRBundleUtil relevantBundles];\n  NSString *expectedBundleID = [self expectedBundleID];\n  // The checking is only done when the bundle ID is provided in the serviceInfo dictionary for\n  // backward compatibility.\n  if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifierPrefix:expectedBundleID\n                                                                 inBundles:bundles]) {\n    FIRLogError(kFIRLoggerCore, @\"I-COR000008\",\n                @\"The project's Bundle ID is inconsistent with \"\n                @\"either the Bundle ID in '%@.%@', or the Bundle ID in the options if you are \"\n                @\"using a customized options. To ensure that everything can be configured \"\n                @\"correctly, you may need to make the Bundle IDs consistent. To continue with this \"\n                @\"plist file, you may change your app's bundle identifier to '%@'. Or you can \"\n                @\"download a new configuration file that matches your bundle identifier from %@ \"\n                @\"and replace the current one.\",\n                kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL);\n  }\n}\n\n#pragma mark - private - App ID Validation\n\n/**\n * Validates the format and fingerprint of the app ID contained in GOOGLE_APP_ID in the plist file.\n * This is the main method for validating app ID.\n *\n * @return YES if the app ID fulfills the expected format and fingerprint, NO otherwise.\n */\n- (BOOL)isAppIDValid {\n  NSString *appID = _options.googleAppID;\n  BOOL isValid = [FIRApp validateAppID:appID];\n  if (!isValid) {\n    NSString *expectedBundleID = [self expectedBundleID];\n    FIRLogError(kFIRLoggerCore, @\"I-COR000009\",\n                @\"The GOOGLE_APP_ID either in the plist file \"\n                @\"'%@.%@' or the one set in the customized options is invalid. If you are using \"\n                @\"the plist file, use the iOS version of bundle identifier to download the file, \"\n                @\"and do not manually edit the GOOGLE_APP_ID. You may change your app's bundle \"\n                @\"identifier to '%@'. Or you can download a new configuration file that matches \"\n                @\"your bundle identifier from %@ and replace the current one.\",\n                kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL);\n  };\n  return isValid;\n}\n\n+ (BOOL)validateAppID:(NSString *)appID {\n  // Failing validation only occurs when we are sure we are looking at a V2 app ID and it does not\n  // have a valid fingerprint, otherwise we just warn about the potential issue.\n  if (!appID.length) {\n    return NO;\n  }\n\n  NSScanner *stringScanner = [NSScanner scannerWithString:appID];\n  stringScanner.charactersToBeSkipped = nil;\n\n  NSString *appIDVersion;\n  if (![stringScanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet]\n                                 intoString:&appIDVersion]) {\n    return NO;\n  }\n\n  if (![stringScanner scanString:@\":\" intoString:NULL]) {\n    // appIDVersion must be separated by \":\"\n    return NO;\n  }\n\n  NSArray *knownVersions = @[ @\"1\" ];\n  if (![knownVersions containsObject:appIDVersion]) {\n    // Permit unknown yet properly formatted app ID versions.\n    FIRLogInfo(kFIRLoggerCore, @\"I-COR000010\", @\"Unknown GOOGLE_APP_ID version: %@\", appIDVersion);\n    return YES;\n  }\n\n  if (![self validateAppIDFormat:appID withVersion:appIDVersion]) {\n    return NO;\n  }\n\n  if (![self validateAppIDFingerprint:appID withVersion:appIDVersion]) {\n    return NO;\n  }\n\n  return YES;\n}\n\n+ (NSString *)actualBundleID {\n  return [[NSBundle mainBundle] bundleIdentifier];\n}\n\n/**\n * Validates that the format of the app ID string is what is expected based on the supplied version.\n * The version must end in \":\".\n *\n * For v1 app ids the format is expected to be\n * '<version #>:<project number>:ios:<fingerprint of bundle id>'.\n *\n * This method does not verify that the contents of the app id are correct, just that they fulfill\n * the expected format.\n *\n * @param appID Contents of GOOGLE_APP_ID from the plist file.\n * @param version Indicates what version of the app id format this string should be.\n * @return YES if provided string fufills the expected format, NO otherwise.\n */\n+ (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version {\n  if (!appID.length || !version.length) {\n    return NO;\n  }\n\n  NSScanner *stringScanner = [NSScanner scannerWithString:appID];\n  stringScanner.charactersToBeSkipped = nil;\n\n  // Skip version part\n  // '*<version #>*:<project number>:ios:<fingerprint of bundle id>'\n  if (![stringScanner scanString:version intoString:NULL]) {\n    // The version part is missing or mismatched\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>*:*<project number>:ios:<fingerprint of bundle id>'\n  if (![stringScanner scanString:@\":\" intoString:NULL]) {\n    // appIDVersion must be separated by \":\"\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>:*<project number>*:ios:<fingerprint of bundle id>'.\n  NSInteger projectNumber = NSNotFound;\n  if (![stringScanner scanInteger:&projectNumber]) {\n    // NO project number found.\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>:<project number>*:*ios:<fingerprint of bundle id>'.\n  if (![stringScanner scanString:@\":\" intoString:NULL]) {\n    // The project number must be separated by \":\"\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>:<project number>:*ios*:<fingerprint of bundle id>'.\n  NSString *platform;\n  if (![stringScanner scanUpToString:@\":\" intoString:&platform]) {\n    return NO;\n  }\n\n  if (![platform isEqualToString:@\"ios\"]) {\n    // The platform must be @\"ios\"\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>:<project number>:ios*:*<fingerprint of bundle id>'.\n  if (![stringScanner scanString:@\":\" intoString:NULL]) {\n    // The platform must be separated by \":\"\n    return NO;\n  }\n\n  // Validate version part (see part between '*' symbols below)\n  // '<version #>:<project number>:ios:*<fingerprint of bundle id>*'.\n  unsigned long long fingerprint = NSNotFound;\n  if (![stringScanner scanHexLongLong:&fingerprint]) {\n    // Fingerprint part is missing\n    return NO;\n  }\n\n  if (!stringScanner.isAtEnd) {\n    // There are not allowed characters in the fingerprint part\n    return NO;\n  }\n\n  return YES;\n}\n\n/**\n * Validates that the fingerprint of the app ID string is what is expected based on the supplied\n * version.\n *\n * Note that the v1 hash algorithm is not permitted on the client and cannot be fully validated.\n *\n * @param appID Contents of GOOGLE_APP_ID from the plist file.\n * @param version Indicates what version of the app id format this string should be.\n * @return YES if provided string fufills the expected fingerprint and the version is known, NO\n *         otherwise.\n */\n+ (BOOL)validateAppIDFingerprint:(NSString *)appID withVersion:(NSString *)version {\n  // Extract the supplied fingerprint from the supplied app ID.\n  // This assumes the app ID format is the same for all known versions below. If the app ID format\n  // changes in future versions, the tokenizing of the app ID format will need to take into account\n  // the version of the app ID.\n  NSArray *components = [appID componentsSeparatedByString:@\":\"];\n  if (components.count != 4) {\n    return NO;\n  }\n\n  NSString *suppliedFingerprintString = components[3];\n  if (!suppliedFingerprintString.length) {\n    return NO;\n  }\n\n  uint64_t suppliedFingerprint;\n  NSScanner *scanner = [NSScanner scannerWithString:suppliedFingerprintString];\n  if (![scanner scanHexLongLong:&suppliedFingerprint]) {\n    return NO;\n  }\n\n  if ([version isEqual:@\"1\"]) {\n    // The v1 hash algorithm is not permitted on the client so the actual hash cannot be validated.\n    return YES;\n  }\n\n  // Unknown version.\n  return NO;\n}\n\n- (NSString *)expectedBundleID {\n  return _options.bundleID;\n}\n\n// end App ID validation\n\n#pragma mark - Reading From Plist & User Defaults\n\n/**\n * Clears the data collection switch from the standard NSUserDefaults for easier testing and\n * readability.\n */\n- (void)clearDataCollectionSwitchFromUserDefaults {\n  NSString *key =\n      [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name];\n  [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];\n}\n\n/**\n * Reads the data collection switch from the standard NSUserDefaults for easier testing and\n * readability.\n */\n+ (nullable NSNumber *)readDataCollectionSwitchFromUserDefaultsForApp:(FIRApp *)app {\n  // Read the object in user defaults, and only return if it's an NSNumber.\n  NSString *key =\n      [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, app.name];\n  id collectionEnabledDefaultsObject = [[NSUserDefaults standardUserDefaults] objectForKey:key];\n  if ([collectionEnabledDefaultsObject isKindOfClass:[NSNumber class]]) {\n    return collectionEnabledDefaultsObject;\n  }\n\n  return nil;\n}\n\n/**\n * Reads the data collection switch from the Info.plist for easier testing and readability. Will\n * only read once from the plist and return the cached value.\n */\n+ (nullable NSNumber *)readDataCollectionSwitchFromPlist {\n  static NSNumber *collectionEnabledPlistObject;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    // Read the data from the `Info.plist`, only assign it if it's there and an NSNumber.\n    id plistValue = [[NSBundle mainBundle]\n        objectForInfoDictionaryKey:kFIRGlobalAppDataCollectionEnabledPlistKey];\n    if (plistValue && [plistValue isKindOfClass:[NSNumber class]]) {\n      collectionEnabledPlistObject = (NSNumber *)plistValue;\n    }\n  });\n\n  return collectionEnabledPlistObject;\n}\n\n#pragma mark - App Life Cycle\n\n- (void)subscribeForAppDidBecomeActiveNotifications {\n#if TARGET_OS_IOS || TARGET_OS_TV\n  NSNotificationName notificationName = UIApplicationDidBecomeActiveNotification;\n#elif TARGET_OS_OSX\n  NSNotificationName notificationName = NSApplicationDidBecomeActiveNotification;\n#endif\n\n#if !TARGET_OS_WATCH\n  [[NSNotificationCenter defaultCenter] addObserver:self\n                                           selector:@selector(appDidBecomeActive:)\n                                               name:notificationName\n                                             object:nil];\n#endif\n}\n\n- (void)appDidBecomeActive:(NSNotification *)notification {\n  [self logCoreTelemetryIfEnabled];\n}\n\n- (void)logCoreTelemetryIfEnabled {\n  if ([self isDataCollectionDefaultEnabled]) {\n    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{\n      [FIRCoreDiagnosticsConnector logCoreTelemetryWithOptions:[self options]];\n    });\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRAppAssociationRegistration.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n//  TODO: Remove this once Auth moves over to Core's instance registration system.\n/** @class FIRAppAssociationRegistration\n    @brief Manages object associations as a singleton-dependent: At most one object is\n        registered for any given host/key pair, and the object shall be created on-the-fly when\n        asked for.\n */\n@interface FIRAppAssociationRegistration<ObjectType> : NSObject\n\n/** @fn registeredObjectWithHost:key:creationBlock:\n    @brief Retrieves the registered object with a particular host and key.\n    @param host The host object.\n    @param key The key to specify the registered object on the host.\n    @param creationBlock The block to return the object to be registered if not already.\n        The block is executed immediately before this method returns if it is executed at all.\n        It can also be executed multiple times across different method invocations if previous\n        execution of the block returns @c nil.\n    @return The registered object for the host/key pair, or @c nil if no object is registered\n        and @c creationBlock returns @c nil.\n    @remarks The method is thread-safe but non-reentrant in the sense that attempting to call this\n        method again within the @c creationBlock with the same host/key pair raises an exception.\n        The registered object is retained by the host.\n */\n+ (nullable ObjectType)registeredObjectWithHost:(id)host\n                                            key:(NSString *)key\n                                  creationBlock:(ObjectType _Nullable (^)(void))creationBlock;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRAppAssociationRegistration.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/FIRAppAssociationRegistration.h\"\n\n#import <objc/runtime.h>\n\n@implementation FIRAppAssociationRegistration\n\n+ (nullable id)registeredObjectWithHost:(id)host\n                                    key:(NSString *)key\n                          creationBlock:(id _Nullable (^)(void))creationBlock {\n  @synchronized(self) {\n    SEL dictKey = @selector(registeredObjectWithHost:key:creationBlock:);\n    NSMutableDictionary<NSString *, id> *objectsByKey = objc_getAssociatedObject(host, dictKey);\n    if (!objectsByKey) {\n      objectsByKey = [[NSMutableDictionary alloc] init];\n      objc_setAssociatedObject(host, dictKey, objectsByKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n    }\n    id obj = objectsByKey[key];\n    NSValue *creationBlockBeingCalled = [NSValue valueWithPointer:dictKey];\n    if (obj) {\n      if ([creationBlockBeingCalled isEqual:obj]) {\n        [NSException raise:@\"Reentering registeredObjectWithHost:key:creationBlock: not allowed\"\n                    format:@\"host: %@ key: %@\", host, key];\n      }\n      return obj;\n    }\n    objectsByKey[key] = creationBlockBeingCalled;\n    obj = creationBlock();\n    objectsByKey[key] = obj;\n    return obj;\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * This class provides utilities for accessing resources in bundles.\n */\n@interface FIRBundleUtil : NSObject\n\n/**\n * Finds all relevant bundles, starting with [NSBundle mainBundle].\n */\n+ (NSArray *)relevantBundles;\n\n/**\n * Reads the options dictionary from one of the provided bundles.\n *\n * @param resourceName The resource name, e.g. @\"GoogleService-Info\".\n * @param fileType The file type (extension), e.g. @\"plist\".\n * @param bundles The bundles to expect, in priority order. See also\n * +[FIRBundleUtil relevantBundles].\n */\n+ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName\n                                        andFileType:(NSString *)fileType\n                                          inBundles:(NSArray *)bundles;\n\n/**\n * Finds URL schemes defined in all relevant bundles, starting with those from\n * [NSBundle mainBundle].\n */\n+ (NSArray *)relevantURLSchemes;\n\n/**\n * Checks if any of the given bundles have a matching bundle identifier prefix (removing extension\n * suffixes).\n */\n+ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles;\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/FIRBundleUtil.h\"\n\n#import <GoogleUtilities/GULAppEnvironmentUtil.h>\n\n@implementation FIRBundleUtil\n\n+ (NSArray *)relevantBundles {\n  return @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ];\n}\n\n+ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName\n                                        andFileType:(NSString *)fileType\n                                          inBundles:(NSArray *)bundles {\n  // Loop through all bundles to find the config dict.\n  for (NSBundle *bundle in bundles) {\n    NSString *path = [bundle pathForResource:resourceName ofType:fileType];\n    // Use the first one we find.\n    if (path) {\n      return path;\n    }\n  }\n  return nil;\n}\n\n+ (NSArray *)relevantURLSchemes {\n  NSMutableArray *result = [[NSMutableArray alloc] init];\n  for (NSBundle *bundle in [[self class] relevantBundles]) {\n    NSArray *urlTypes = [bundle objectForInfoDictionaryKey:@\"CFBundleURLTypes\"];\n    for (NSDictionary *urlType in urlTypes) {\n      [result addObjectsFromArray:urlType[@\"CFBundleURLSchemes\"]];\n    }\n  }\n  return result;\n}\n\n+ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles {\n  for (NSBundle *bundle in bundles) {\n    if ([bundle.bundleIdentifier isEqualToString:bundleIdentifier]) {\n      return YES;\n    }\n\n    if ([GULAppEnvironmentUtil isAppExtension]) {\n      // A developer could be using the same `FIROptions` for both their app and extension. Since\n      // extensions have a suffix added to the bundleID, we consider a matching prefix as valid.\n      NSString *appBundleIDFromExtension =\n          [self bundleIdentifierByRemovingLastPartFrom:bundle.bundleIdentifier];\n      if ([appBundleIDFromExtension isEqualToString:bundleIdentifier]) {\n        return YES;\n      }\n    }\n  }\n  return NO;\n}\n\n+ (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier {\n  NSString *bundleIDComponentsSeparator = @\".\";\n\n  NSMutableArray<NSString *> *bundleIDComponents =\n      [[bundleIdentifier componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy];\n  [bundleIDComponents removeLastObject];\n\n  return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Private/FIRComponent.h\"\n\n#import \"FirebaseCore/Sources/Private/FIRComponentContainer.h\"\n#import \"FirebaseCore/Sources/Private/FIRDependency.h\"\n\n@interface FIRComponent ()\n\n- (instancetype)initWithProtocol:(Protocol *)protocol\n             instantiationTiming:(FIRInstantiationTiming)instantiationTiming\n                    dependencies:(NSArray<FIRDependency *> *)dependencies\n                   creationBlock:(FIRComponentCreationBlock)creationBlock;\n\n@end\n\n@implementation FIRComponent\n\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                        creationBlock:(FIRComponentCreationBlock)creationBlock {\n  return [[FIRComponent alloc] initWithProtocol:protocol\n                            instantiationTiming:FIRInstantiationTimingLazy\n                                   dependencies:@[]\n                                  creationBlock:creationBlock];\n}\n\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                  instantiationTiming:(FIRInstantiationTiming)instantiationTiming\n                         dependencies:(NSArray<FIRDependency *> *)dependencies\n                        creationBlock:(FIRComponentCreationBlock)creationBlock {\n  return [[FIRComponent alloc] initWithProtocol:protocol\n                            instantiationTiming:instantiationTiming\n                                   dependencies:dependencies\n                                  creationBlock:creationBlock];\n}\n\n- (instancetype)initWithProtocol:(Protocol *)protocol\n             instantiationTiming:(FIRInstantiationTiming)instantiationTiming\n                    dependencies:(NSArray<FIRDependency *> *)dependencies\n                   creationBlock:(FIRComponentCreationBlock)creationBlock {\n  self = [super init];\n  if (self) {\n    _protocol = protocol;\n    _instantiationTiming = instantiationTiming;\n    _dependencies = [dependencies copy];\n    _creationBlock = creationBlock;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Private/FIRComponentContainer.h\"\n\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponent.h\"\n#import \"FirebaseCore/Sources/Private/FIRLibrary.h\"\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRComponentContainer ()\n\n/// The dictionary of components that are registered for a particular app. The key is an `NSString`\n/// of the protocol.\n@property(nonatomic, strong) NSMutableDictionary<NSString *, FIRComponentCreationBlock> *components;\n\n/// Cached instances of components that requested to be cached.\n@property(nonatomic, strong) NSMutableDictionary<NSString *, id> *cachedInstances;\n\n/// Protocols of components that have requested to be eagerly instantiated.\n@property(nonatomic, strong, nullable) NSMutableArray<Protocol *> *eagerProtocolsToInstantiate;\n\n@end\n\n@implementation FIRComponentContainer\n\n// Collection of all classes that register to provide components.\nstatic NSMutableSet<Class> *sFIRComponentRegistrants;\n\n#pragma mark - Public Registration\n\n+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass {\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sFIRComponentRegistrants = [[NSMutableSet<Class> alloc] init];\n  });\n\n  [self registerAsComponentRegistrant:klass inSet:sFIRComponentRegistrants];\n}\n\n+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass\n                                inSet:(NSMutableSet<Class> *)allRegistrants {\n  [allRegistrants addObject:klass];\n}\n\n#pragma mark - Internal Initialization\n\n- (instancetype)initWithApp:(FIRApp *)app {\n  return [self initWithApp:app registrants:sFIRComponentRegistrants];\n}\n\n- (instancetype)initWithApp:(FIRApp *)app registrants:(NSMutableSet<Class> *)allRegistrants {\n  self = [super init];\n  if (self) {\n    _app = app;\n    _cachedInstances = [NSMutableDictionary<NSString *, id> dictionary];\n    _components = [NSMutableDictionary<NSString *, FIRComponentCreationBlock> dictionary];\n\n    [self populateComponentsFromRegisteredClasses:allRegistrants forApp:app];\n  }\n  return self;\n}\n\n- (void)populateComponentsFromRegisteredClasses:(NSSet<Class> *)classes forApp:(FIRApp *)app {\n  // Keep track of any components that need to eagerly instantiate after all components are added.\n  self.eagerProtocolsToInstantiate = [[NSMutableArray alloc] init];\n\n  // Loop through the verified component registrants and populate the components array.\n  for (Class<FIRLibrary> klass in classes) {\n    // Loop through all the components being registered and store them as appropriate.\n    // Classes which do not provide functionality should use a dummy FIRComponentRegistrant\n    // protocol.\n    for (FIRComponent *component in [klass componentsToRegister]) {\n      // Check if the component has been registered before, and error out if so.\n      NSString *protocolName = NSStringFromProtocol(component.protocol);\n      if (self.components[protocolName]) {\n        FIRLogError(kFIRLoggerCore, @\"I-COR000029\",\n                    @\"Attempted to register protocol %@, but it already has an implementation.\",\n                    protocolName);\n        continue;\n      }\n\n      // Store the creation block for later usage.\n      self.components[protocolName] = component.creationBlock;\n\n      // Queue any protocols that should be eagerly instantiated. Don't instantiate them yet\n      // because they could depend on other components that haven't been added to the components\n      // array yet.\n      BOOL shouldInstantiateEager =\n          (component.instantiationTiming == FIRInstantiationTimingAlwaysEager);\n      BOOL shouldInstantiateDefaultEager =\n          (component.instantiationTiming == FIRInstantiationTimingEagerInDefaultApp &&\n           [app isDefaultApp]);\n      if (shouldInstantiateEager || shouldInstantiateDefaultEager) {\n        [self.eagerProtocolsToInstantiate addObject:component.protocol];\n      }\n    }\n  }\n}\n\n#pragma mark - Instance Creation\n\n- (void)instantiateEagerComponents {\n  // After all components are registered, instantiate the ones that are requesting eager\n  // instantiation.\n  @synchronized(self) {\n    for (Protocol *protocol in self.eagerProtocolsToInstantiate) {\n      // Get an instance for the protocol, which will instantiate it since it couldn't have been\n      // cached yet. Ignore the instance coming back since we don't need it.\n      __unused id unusedInstance = [self instanceForProtocol:protocol];\n    }\n\n    // All eager instantiation is complete, clear the stored property now.\n    self.eagerProtocolsToInstantiate = nil;\n  }\n}\n\n/// Instantiate an instance of a class that conforms to the specified protocol.\n/// This will:\n///   - Call the block to create an instance if possible,\n///   - Validate that the instance returned conforms to the protocol it claims to,\n///   - Cache the instance if the block requests it\n///\n/// Note that this method assumes the caller already has @sychronized on self.\n- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol\n                                    withBlock:(FIRComponentCreationBlock)creationBlock {\n  if (!creationBlock) {\n    return nil;\n  }\n\n  // Create an instance using the creation block.\n  BOOL shouldCache = NO;\n  id instance = creationBlock(self, &shouldCache);\n  if (!instance) {\n    return nil;\n  }\n\n  // An instance was created, validate that it conforms to the protocol it claims to.\n  NSString *protocolName = NSStringFromProtocol(protocol);\n  if (![instance conformsToProtocol:protocol]) {\n    FIRLogError(kFIRLoggerCore, @\"I-COR000030\",\n                @\"An instance conforming to %@ was requested, but the instance provided does not \"\n                @\"conform to the protocol\",\n                protocolName);\n  }\n\n  // The instance is ready to be returned, but check if it should be cached first before returning.\n  if (shouldCache) {\n    self.cachedInstances[protocolName] = instance;\n  }\n\n  return instance;\n}\n\n#pragma mark - Internal Retrieval\n\n- (nullable id)instanceForProtocol:(Protocol *)protocol {\n  // Check if there is a cached instance, and return it if so.\n  NSString *protocolName = NSStringFromProtocol(protocol);\n\n  id cachedInstance;\n  @synchronized(self) {\n    cachedInstance = self.cachedInstances[protocolName];\n    if (!cachedInstance) {\n      // Use the creation block to instantiate an instance and return it.\n      FIRComponentCreationBlock creationBlock = self.components[protocolName];\n      cachedInstance = [self instantiateInstanceForProtocol:protocol withBlock:creationBlock];\n    }\n  }\n  return cachedInstance;\n}\n\n#pragma mark - Lifecycle\n\n- (void)removeAllCachedInstances {\n  @synchronized(self) {\n    // Loop through the cache and notify each instance that is a maintainer to clean up after\n    // itself.\n    for (id instance in self.cachedInstances.allValues) {\n      if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] &&\n          [instance respondsToSelector:@selector(appWillBeDeleted:)]) {\n        [instance appWillBeDeleted:self.app];\n      }\n    }\n\n    // Empty the cache.\n    [self.cachedInstances removeAllObjects];\n  }\n}\n\n- (void)removeAllComponents {\n  @synchronized(self) {\n    [self.components removeAllObjects];\n  }\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainerInternal.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseCore/Sources/Private/FIRComponentContainer.h\"\n#import \"FirebaseCore/Sources/Private/FIRLibrary.h\"\n\n@class FIRApp;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRComponentContainer (Private)\n\n/// Initializes a container for a given app. This should only be called by the app itself.\n- (instancetype)initWithApp:(FIRApp *)app;\n\n/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the\n/// protocol wasn't registered, or if the instance couldn't be instantiated for the provided app.\n- (nullable id)instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:));\n\n/// Instantiates all the components that have registered as \"eager\" after initialization.\n- (void)instantiateEagerComponents;\n\n/// Remove all of the cached instances stored and allow them to clean up after themselves.\n- (void)removeAllCachedInstances;\n\n/// Removes all the components. After calling this method no new instances will be created.\n- (void)removeAllComponents;\n\n/// Register a class to provide components for the interoperability system. The class should conform\n/// to `FIRComponentRegistrant` and provide an array of `FIRComponent` objects.\n+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Private/FIRComponentType.h\"\n\n#import \"FirebaseCore/Sources/FIRComponentContainerInternal.h\"\n\n@implementation FIRComponentType\n\n+ (id)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container {\n  // Forward the call to the container.\n  return [container instanceForProtocol:protocol];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/FIRConfigurationInternal.h\"\n\n#import \"FirebaseCore/Sources/FIRAnalyticsConfiguration.h\"\n\nextern void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);\n\n@implementation FIRConfiguration\n\n+ (instancetype)sharedInstance {\n  static FIRConfiguration *sharedInstance = nil;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[FIRConfiguration alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _analyticsConfiguration = [FIRAnalyticsConfiguration sharedInstance];\n  }\n  return self;\n}\n\n- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel {\n  NSAssert(loggerLevel <= FIRLoggerLevelMax && loggerLevel >= FIRLoggerLevelMin,\n           @\"Invalid logger level, %ld\", (long)loggerLevel);\n  FIRSetLoggerLevel(loggerLevel);\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRConfigurationInternal.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h\"\n\n@class FIRAnalyticsConfiguration;\n\n@interface FIRConfiguration ()\n\n/**\n * The configuration class for Firebase Analytics. This should be removed once the logic for\n * enabling and disabling Analytics is moved to Analytics.\n */\n@property(nonatomic, readwrite) FIRAnalyticsConfiguration *analyticsConfiguration;\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRCoreDiagnosticsConnector.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h\"\n\n#import \"Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h\"\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h\"\n\n#import \"FirebaseCore/Sources/FIRDiagnosticsData.h\"\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n\n// Define the interop class symbol declared as an extern in FIRCoreDiagnosticsInterop.\nClass<FIRCoreDiagnosticsInterop> FIRCoreDiagnosticsImplementation;\n\n@implementation FIRCoreDiagnosticsConnector\n\n+ (void)initialize {\n  if (!FIRCoreDiagnosticsImplementation) {\n    FIRCoreDiagnosticsImplementation = NSClassFromString(@\"FIRCoreDiagnostics\");\n    if (FIRCoreDiagnosticsImplementation) {\n      NSAssert([FIRCoreDiagnosticsImplementation\n                   conformsToProtocol:@protocol(FIRCoreDiagnosticsInterop)],\n               @\"If FIRCoreDiagnostics is implemented, it must conform to the interop protocol.\");\n      NSAssert(\n          [FIRCoreDiagnosticsImplementation respondsToSelector:@selector(sendDiagnosticsData:)],\n          @\"If FIRCoreDiagnostics is implemented, it must implement +sendDiagnosticsData.\");\n    }\n  }\n}\n\n+ (void)logCoreTelemetryWithOptions:(FIROptions *)options {\n  if (FIRCoreDiagnosticsImplementation) {\n    FIRDiagnosticsData *diagnosticsData = [[FIRDiagnosticsData alloc] init];\n    [diagnosticsData insertValue:@(YES) forKey:kFIRCDIsDataCollectionDefaultEnabledKey];\n    [diagnosticsData insertValue:[FIRApp firebaseUserAgent] forKey:kFIRCDFirebaseUserAgentKey];\n    [diagnosticsData insertValue:@(FIRConfigTypeCore) forKey:kFIRCDConfigurationTypeKey];\n    [diagnosticsData insertValue:options.googleAppID forKey:kFIRCDGoogleAppIDKey];\n    [diagnosticsData insertValue:options.bundleID forKey:kFIRCDBundleIDKey];\n    [diagnosticsData insertValue:@(options.usingOptionsFromDefaultPlist)\n                          forKey:kFIRCDUsingOptionsFromDefaultPlistKey];\n    [diagnosticsData insertValue:options.libraryVersionID forKey:kFIRCDLibraryVersionIDKey];\n    [FIRCoreDiagnosticsImplementation sendDiagnosticsData:diagnosticsData];\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Private/FIRDependency.h\"\n\n@interface FIRDependency ()\n\n- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required;\n\n@end\n\n@implementation FIRDependency\n\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol {\n  return [[self alloc] initWithProtocol:protocol isRequired:YES];\n}\n\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required {\n  return [[self alloc] initWithProtocol:protocol isRequired:required];\n}\n\n- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required {\n  self = [super init];\n  if (self) {\n    _protocol = protocol;\n    _isRequired = required;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRDiagnosticsData.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Implements the FIRCoreDiagnosticsData protocol to log diagnostics data. */\n@interface FIRDiagnosticsData : NSObject <FIRCoreDiagnosticsData>\n\n/** Inserts values into the diagnosticObjects dictionary if the value isn't nil.\n *\n * @param value The value to insert if it's not nil.\n * @param key The key to associate it with.\n */\n- (void)insertValue:(nullable id)value forKey:(NSString *)key;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRDiagnosticsData.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/FIRDiagnosticsData.h\"\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h\"\n\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n\n@implementation FIRDiagnosticsData {\n  /** Backing ivar for the diagnosticObjects property. */\n  NSMutableDictionary<NSString *, id> *_diagnosticObjects;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _diagnosticObjects = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n- (void)insertValue:(nullable id)value forKey:(NSString *)key {\n  if (key) {\n    _diagnosticObjects[key] = value;\n  }\n}\n\n#pragma mark - FIRCoreDiagnosticsData\n\n- (NSDictionary<NSString *, id> *)diagnosticObjects {\n  if (!_diagnosticObjects[kFIRCDllAppsCountKey]) {\n    _diagnosticObjects[kFIRCDllAppsCountKey] = @([FIRApp allApps].count);\n  }\n  if (!_diagnosticObjects[kFIRCDIsDataCollectionDefaultEnabledKey]) {\n    _diagnosticObjects[kFIRCDIsDataCollectionDefaultEnabledKey] =\n        @([[FIRApp defaultApp] isDataCollectionDefaultEnabled]);\n  }\n  if (!_diagnosticObjects[kFIRCDFirebaseUserAgentKey]) {\n    _diagnosticObjects[kFIRCDFirebaseUserAgentKey] = [FIRApp firebaseUserAgent];\n  }\n  return _diagnosticObjects;\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunused-parameter\"\n- (void)setDiagnosticObjects:(NSDictionary<NSString *, id> *)diagnosticObjects {\n  NSAssert(NO, @\"Please use -insertValue:forKey:\");\n}\n#pragma clang diagnostic pop\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRFirebaseUserAgent : NSObject\n\n/** Returns the firebase user agent which consists of environment part and the components added via\n * `setValue:forComponent` method. */\n- (NSString *)firebaseUserAgent;\n\n/** Sets value associated with the specified component. If value is `nil` then the component is\n * removed. */\n- (void)setValue:(nullable NSString *)value forComponent:(NSString *)componentName;\n\n/** Resets manually added components. */\n- (void)reset;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/FIRFirebaseUserAgent.h\"\n\n#import <GoogleUtilities/GULAppEnvironmentUtil.h>\n\n@interface FIRFirebaseUserAgent ()\n\n@property(nonatomic, readonly) NSMutableDictionary<NSString *, NSString *> *valuesByComponent;\n@property(nonatomic, readonly) NSDictionary<NSString *, NSString *> *environmentComponents;\n@property(nonatomic, readonly) NSString *firebaseUserAgent;\n\n@end\n\n@implementation FIRFirebaseUserAgent\n\n@synthesize firebaseUserAgent = _firebaseUserAgent;\n@synthesize environmentComponents = _environmentComponents;\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _valuesByComponent = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n- (NSString *)firebaseUserAgent {\n  @synchronized(self) {\n    if (_firebaseUserAgent == nil) {\n      NSMutableDictionary<NSString *, NSString *> *allComponents =\n          [self.valuesByComponent mutableCopy];\n      [allComponents setValuesForKeysWithDictionary:self.environmentComponents];\n\n      __block NSMutableArray<NSString *> *components =\n          [[NSMutableArray<NSString *> alloc] initWithCapacity:self.valuesByComponent.count];\n      [allComponents enumerateKeysAndObjectsUsingBlock:^(\n                         NSString *_Nonnull name, NSString *_Nonnull value, BOOL *_Nonnull stop) {\n        [components addObject:[NSString stringWithFormat:@\"%@/%@\", name, value]];\n      }];\n      [components sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];\n      _firebaseUserAgent = [components componentsJoinedByString:@\" \"];\n    }\n    return _firebaseUserAgent;\n  }\n}\n\n- (void)setValue:(nullable NSString *)value forComponent:(NSString *)componentName {\n  @synchronized(self) {\n    self.valuesByComponent[componentName] = value;\n    // Reset cached user agent string.\n    _firebaseUserAgent = nil;\n  }\n}\n\n- (void)reset {\n  @synchronized(self) {\n    // Reset components.\n    _valuesByComponent = [[[self class] environmentComponents] mutableCopy];\n    // Reset cached user agent string.\n    _firebaseUserAgent = nil;\n  }\n}\n\n#pragma mark - Environment components\n\n- (NSDictionary<NSString *, NSString *> *)environmentComponents {\n  if (_environmentComponents == nil) {\n    _environmentComponents = [[self class] environmentComponents];\n  }\n  return _environmentComponents;\n}\n\n+ (NSDictionary<NSString *, NSString *> *)environmentComponents {\n  NSMutableDictionary<NSString *, NSString *> *components = [NSMutableDictionary dictionary];\n\n  NSDictionary<NSString *, id> *info = [[NSBundle mainBundle] infoDictionary];\n  NSString *xcodeVersion = info[@\"DTXcodeBuild\"];\n  NSString *appleSdkVersion = info[@\"DTSDKBuild\"];\n  NSString *isFromAppstoreFlagValue = [GULAppEnvironmentUtil isFromAppStore] ? @\"true\" : @\"false\";\n\n  components[@\"apple-platform\"] = [GULAppEnvironmentUtil applePlatform];\n  components[@\"apple-sdk\"] = appleSdkVersion;\n  components[@\"appstore\"] = isFromAppstoreFlagValue;\n  components[@\"deploy\"] = [GULAppEnvironmentUtil deploymentType];\n  components[@\"device\"] = [GULAppEnvironmentUtil deviceModel];\n  components[@\"os-version\"] = [GULAppEnvironmentUtil systemVersion];\n  components[@\"xcode\"] = xcodeVersion;\n\n  return [components copy];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatInfo.m",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/Private/FIRHeartbeatInfo.h\"\n#import <GoogleUtilities/GULHeartbeatDateStorable.h>\n#import <GoogleUtilities/GULHeartbeatDateStorage.h>\n#import <GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h>\n#import <GoogleUtilities/GULLogger.h>\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n\nconst static long secondsInDay = 86400;\n@implementation FIRHeartbeatInfo : NSObject\n\n/** Updates the storage with the heartbeat information corresponding to this tag.\n * @param heartbeatTag Tag which could either be sdk specific tag or the global tag.\n * @return Boolean representing whether the heartbeat needs to be sent for this tag or not.\n */\n+ (BOOL)updateIfNeededHeartbeatDateForTag:(NSString *)heartbeatTag {\n  @synchronized(self) {\n    NSString *const kHeartbeatStorageName = @\"HEARTBEAT_INFO_STORAGE\";\n    id<GULHeartbeatDateStorable> dataStorage;\n#if TARGET_OS_TV\n    NSUserDefaults *defaults =\n        [[NSUserDefaults alloc] initWithSuiteName:kFirebaseCoreDefaultsSuiteName];\n    dataStorage =\n        [[GULHeartbeatDateStorageUserDefaults alloc] initWithDefaults:defaults\n                                                                  key:kHeartbeatStorageName];\n#else\n    dataStorage = [[GULHeartbeatDateStorage alloc] initWithFileName:kHeartbeatStorageName];\n#endif\n    NSDate *heartbeatTime = [dataStorage heartbeatDateForTag:heartbeatTag];\n    NSDate *currentDate = [NSDate date];\n    if (heartbeatTime != nil) {\n      NSTimeInterval secondsBetween = [currentDate timeIntervalSinceDate:heartbeatTime];\n      if (secondsBetween < secondsInDay) {\n        return false;\n      }\n    }\n    return [dataStorage setHearbeatDate:currentDate forTag:heartbeatTag];\n  }\n}\n\n+ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag {\n  NSString *globalTag = @\"GLOBAL\";\n  BOOL isSdkHeartbeatNeeded = [FIRHeartbeatInfo updateIfNeededHeartbeatDateForTag:heartbeatTag];\n  BOOL isGlobalHeartbeatNeeded = [FIRHeartbeatInfo updateIfNeededHeartbeatDateForTag:globalTag];\n  if (!isSdkHeartbeatNeeded && !isGlobalHeartbeatNeeded) {\n    // Both sdk and global heartbeat not needed.\n    return FIRHeartbeatInfoCodeNone;\n  } else if (isSdkHeartbeatNeeded && !isGlobalHeartbeatNeeded) {\n    // Only SDK heartbeat needed.\n    return FIRHeartbeatInfoCodeSDK;\n  } else if (!isSdkHeartbeatNeeded && isGlobalHeartbeatNeeded) {\n    // Only global heartbeat needed.\n    return FIRHeartbeatInfoCodeGlobal;\n  } else {\n    // Both sdk and global heartbeat are needed.\n    return FIRHeartbeatInfoCodeCombined;\n  }\n}\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n\n#import <GoogleUtilities/GULAppEnvironmentUtil.h>\n#import <GoogleUtilities/GULLogger.h>\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h\"\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h\"\n\nFIRLoggerService kFIRLoggerCore = @\"[Firebase/Core]\";\n\n// All the FIRLoggerService definitions should be migrated to clients. Do not add new ones!\nFIRLoggerService kFIRLoggerAnalytics = @\"[Firebase/Analytics]\";\nFIRLoggerService kFIRLoggerCrash = @\"[Firebase/Crash]\";\nFIRLoggerService kFIRLoggerRemoteConfig = @\"[Firebase/RemoteConfig]\";\n\n/// Arguments passed on launch.\nNSString *const kFIRDisableDebugModeApplicationArgument = @\"-FIRDebugDisabled\";\nNSString *const kFIREnableDebugModeApplicationArgument = @\"-FIRDebugEnabled\";\nNSString *const kFIRLoggerForceSDTERRApplicationArgument = @\"-FIRLoggerForceSTDERR\";\n\n/// Key for the debug mode bit in NSUserDefaults.\nNSString *const kFIRPersistedDebugModeKey = @\"/google/firebase/debug_mode\";\n\n/// NSUserDefaults that should be used to store and read variables. If nil, `standardUserDefaults`\n/// will be used.\nstatic NSUserDefaults *sFIRLoggerUserDefaults;\n\nstatic dispatch_once_t sFIRLoggerOnceToken;\n\n// The sFIRAnalyticsDebugMode flag is here to support the -FIRDebugEnabled/-FIRDebugDisabled\n// flags used by Analytics. Users who use those flags expect Analytics to log verbosely,\n// while the rest of Firebase logs at the default level. This flag is introduced to support\n// that behavior.\nstatic BOOL sFIRAnalyticsDebugMode;\n\n#ifdef DEBUG\n/// The regex pattern for the message code.\nstatic NSString *const kMessageCodePattern = @\"^I-[A-Z]{3}[0-9]{6}$\";\nstatic NSRegularExpression *sMessageCodeRegex;\n#endif\n\nvoid FIRLoggerInitializeASL(void) {\n  dispatch_once(&sFIRLoggerOnceToken, ^{\n    // Register Firebase Version with GULLogger.\n    GULLoggerRegisterVersion(FIRFirebaseVersion());\n\n    // Override the aslOptions to ASL_OPT_STDERR if the override argument is passed in.\n    NSArray *arguments = [NSProcessInfo processInfo].arguments;\n    BOOL overrideSTDERR = [arguments containsObject:kFIRLoggerForceSDTERRApplicationArgument];\n\n    // Use the standard NSUserDefaults if it hasn't been explicitly set.\n    if (sFIRLoggerUserDefaults == nil) {\n      sFIRLoggerUserDefaults = [NSUserDefaults standardUserDefaults];\n    }\n\n    BOOL forceDebugMode = NO;\n    BOOL debugMode = [sFIRLoggerUserDefaults boolForKey:kFIRPersistedDebugModeKey];\n    if ([arguments containsObject:kFIRDisableDebugModeApplicationArgument]) {  // Default mode\n      [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey];\n    } else if ([arguments containsObject:kFIREnableDebugModeApplicationArgument] ||\n               debugMode) {  // Debug mode\n      [sFIRLoggerUserDefaults setBool:YES forKey:kFIRPersistedDebugModeKey];\n      forceDebugMode = YES;\n    }\n    GULLoggerInitializeASL();\n    if (overrideSTDERR) {\n      GULLoggerEnableSTDERR();\n    }\n    if (forceDebugMode) {\n      GULLoggerForceDebug();\n    }\n  });\n}\n\n__attribute__((no_sanitize(\"thread\"))) void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode) {\n  sFIRAnalyticsDebugMode = analyticsDebugMode;\n}\n\nvoid FIRSetLoggerLevel(FIRLoggerLevel loggerLevel) {\n  FIRLoggerInitializeASL();\n  GULSetLoggerLevel((GULLoggerLevel)loggerLevel);\n}\n\n#ifdef DEBUG\nvoid FIRResetLogger(void) {\n  extern void GULResetLogger(void);\n  sFIRLoggerOnceToken = 0;\n  [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey];\n  sFIRLoggerUserDefaults = nil;\n  GULResetLogger();\n}\n\nvoid FIRSetLoggerUserDefaults(NSUserDefaults *defaults) {\n  sFIRLoggerUserDefaults = defaults;\n}\n#endif\n\n/**\n * Check if the level is high enough to be loggable.\n *\n * Analytics can override the log level with an intentional race condition.\n * Add the attribute to get a clean thread sanitizer run.\n */\n__attribute__((no_sanitize(\"thread\"))) BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel,\n                                                               BOOL analyticsComponent) {\n  FIRLoggerInitializeASL();\n  if (sFIRAnalyticsDebugMode && analyticsComponent) {\n    return YES;\n  }\n  return GULIsLoggableLevel((GULLoggerLevel)loggerLevel);\n}\n\nvoid FIRLogBasic(FIRLoggerLevel level,\n                 FIRLoggerService service,\n                 NSString *messageCode,\n                 NSString *message,\n                 va_list args_ptr) {\n  FIRLoggerInitializeASL();\n  GULLogBasic((GULLoggerLevel)level, service,\n              sFIRAnalyticsDebugMode && [kFIRLoggerAnalytics isEqualToString:service], messageCode,\n              message, args_ptr);\n}\n\n/**\n * Generates the logging functions using macros.\n *\n * Calling FIRLogError(kFIRLoggerCore, @\"I-COR000001\", @\"Configure %@ failed.\", @\"blah\") shows:\n * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Error> [Firebase/Core][I-COR000001] Configure blah failed.\n * Calling FIRLogDebug(kFIRLoggerCore, @\"I-COR000001\", @\"Configure succeed.\") shows:\n * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [Firebase/Core][I-COR000001] Configure succeed.\n */\n#define FIR_LOGGING_FUNCTION(level)                                                             \\\n  void FIRLog##level(FIRLoggerService service, NSString *messageCode, NSString *message, ...) { \\\n    va_list args_ptr;                                                                           \\\n    va_start(args_ptr, message);                                                                \\\n    FIRLogBasic(FIRLoggerLevel##level, service, messageCode, message, args_ptr);                \\\n    va_end(args_ptr);                                                                           \\\n  }\n\nFIR_LOGGING_FUNCTION(Error)\nFIR_LOGGING_FUNCTION(Warning)\nFIR_LOGGING_FUNCTION(Notice)\nFIR_LOGGING_FUNCTION(Info)\nFIR_LOGGING_FUNCTION(Debug)\n\n#undef FIR_MAKE_LOGGER\n\n#pragma mark - FIRLoggerWrapper\n\n@implementation FIRLoggerWrapper\n\n+ (void)logWithLevel:(FIRLoggerLevel)level\n         withService:(FIRLoggerService)service\n            withCode:(NSString *)messageCode\n         withMessage:(NSString *)message\n            withArgs:(va_list)args {\n  FIRLogBasic(level, service, messageCode, message, args);\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"FirebaseCore/Sources/FIRBundleUtil.h\"\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h\"\n\n// Keys for the strings in the plist file.\nNSString *const kFIRAPIKey = @\"API_KEY\";\nNSString *const kFIRTrackingID = @\"TRACKING_ID\";\nNSString *const kFIRGoogleAppID = @\"GOOGLE_APP_ID\";\nNSString *const kFIRClientID = @\"CLIENT_ID\";\nNSString *const kFIRGCMSenderID = @\"GCM_SENDER_ID\";\nNSString *const kFIRAndroidClientID = @\"ANDROID_CLIENT_ID\";\nNSString *const kFIRDatabaseURL = @\"DATABASE_URL\";\nNSString *const kFIRStorageBucket = @\"STORAGE_BUCKET\";\n// The key to locate the expected bundle identifier in the plist file.\nNSString *const kFIRBundleID = @\"BUNDLE_ID\";\n// The key to locate the project identifier in the plist file.\nNSString *const kFIRProjectID = @\"PROJECT_ID\";\n\nNSString *const kFIRIsMeasurementEnabled = @\"IS_MEASUREMENT_ENABLED\";\nNSString *const kFIRIsAnalyticsCollectionEnabled = @\"FIREBASE_ANALYTICS_COLLECTION_ENABLED\";\nNSString *const kFIRIsAnalyticsCollectionDeactivated = @\"FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED\";\n\nNSString *const kFIRIsAnalyticsEnabled = @\"IS_ANALYTICS_ENABLED\";\nNSString *const kFIRIsSignInEnabled = @\"IS_SIGNIN_ENABLED\";\n\n// Library version ID formatted like:\n// @\"5\"     // Major version (one or more digits)\n// @\"04\"    // Minor version (exactly 2 digits)\n// @\"01\"    // Build number (exactly 2 digits)\n// @\"000\";  // Fixed \"000\"\nNSString *kFIRLibraryVersionID;\n\n// Plist file name.\nNSString *const kServiceInfoFileName = @\"GoogleService-Info\";\n// Plist file type.\nNSString *const kServiceInfoFileType = @\"plist\";\n\n// Exception raised from attempting to modify a FIROptions after it's been copied to a FIRApp.\nNSString *const kFIRExceptionBadModification =\n    @\"Attempted to modify options after it's set on FIRApp. Please modify all properties before \"\n    @\"initializing FIRApp.\";\n\n@interface FIROptions ()\n\n/**\n * This property maintains the actual configuration key-value pairs.\n */\n@property(nonatomic, readwrite) NSMutableDictionary *optionsDictionary;\n\n/**\n * Calls `analyticsOptionsDictionaryWithInfoDictionary:` using [NSBundle mainBundle].infoDictionary.\n * It combines analytics options from both the infoDictionary and the GoogleService-Info.plist.\n * Values which are present in the main plist override values from the GoogleService-Info.plist.\n */\n@property(nonatomic, readonly) NSDictionary *analyticsOptionsDictionary;\n\n/**\n * Combination of analytics options from both the infoDictionary and the GoogleService-Info.plist.\n * Values which are present in the infoDictionary override values from the GoogleService-Info.plist.\n */\n- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary;\n\n/**\n * Throw exception if editing is locked when attempting to modify an option.\n */\n- (void)checkEditingLocked;\n\n@end\n\n@implementation FIROptions {\n  /// Backing variable for self.analyticsOptionsDictionary.\n  NSDictionary *_analyticsOptionsDictionary;\n}\n\nstatic FIROptions *sDefaultOptions = nil;\nstatic NSDictionary *sDefaultOptionsDictionary = nil;\nstatic dispatch_once_t sDefaultOptionsOnceToken;\nstatic dispatch_once_t sDefaultOptionsDictionaryOnceToken;\n\n#pragma mark - Public only for internal class methods\n\n+ (FIROptions *)defaultOptions {\n  dispatch_once(&sDefaultOptionsOnceToken, ^{\n    NSDictionary *defaultOptionsDictionary = [self defaultOptionsDictionary];\n    if (defaultOptionsDictionary != nil) {\n      sDefaultOptions =\n          [[FIROptions alloc] initInternalWithOptionsDictionary:defaultOptionsDictionary];\n    }\n  });\n\n  return sDefaultOptions;\n}\n\n#pragma mark - Private class methods\n\n+ (NSDictionary *)defaultOptionsDictionary {\n  dispatch_once(&sDefaultOptionsDictionaryOnceToken, ^{\n    NSString *plistFilePath = [FIROptions plistFilePathWithName:kServiceInfoFileName];\n    if (plistFilePath == nil) {\n      return;\n    }\n    sDefaultOptionsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFilePath];\n    if (sDefaultOptionsDictionary == nil) {\n      FIRLogError(kFIRLoggerCore, @\"I-COR000011\",\n                  @\"The configuration file is not a dictionary: \"\n                  @\"'%@.%@'.\",\n                  kServiceInfoFileName, kServiceInfoFileType);\n    }\n  });\n\n  return sDefaultOptionsDictionary;\n}\n\n// Returns the path of the plist file with a given file name.\n+ (NSString *)plistFilePathWithName:(NSString *)fileName {\n  NSArray *bundles = [FIRBundleUtil relevantBundles];\n  NSString *plistFilePath =\n      [FIRBundleUtil optionsDictionaryPathWithResourceName:fileName\n                                               andFileType:kServiceInfoFileType\n                                                 inBundles:bundles];\n  if (plistFilePath == nil) {\n    FIRLogError(kFIRLoggerCore, @\"I-COR000012\", @\"Could not locate configuration file: '%@.%@'.\",\n                fileName, kServiceInfoFileType);\n  }\n  return plistFilePath;\n}\n\n+ (void)resetDefaultOptions {\n  sDefaultOptions = nil;\n  sDefaultOptionsDictionary = nil;\n  sDefaultOptionsOnceToken = 0;\n  sDefaultOptionsDictionaryOnceToken = 0;\n}\n\n#pragma mark - Private instance methods\n\n- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)optionsDictionary {\n  self = [super init];\n  if (self) {\n    _optionsDictionary = [optionsDictionary mutableCopy];\n    _usingOptionsFromDefaultPlist = YES;\n  }\n  return self;\n}\n\n- (id)copyWithZone:(NSZone *)zone {\n  FIROptions *newOptions = [(FIROptions *)[[self class] allocWithZone:zone]\n      initInternalWithOptionsDictionary:self.optionsDictionary];\n  if (newOptions) {\n    newOptions.deepLinkURLScheme = self.deepLinkURLScheme;\n    newOptions.appGroupID = self.appGroupID;\n    newOptions.editingLocked = self.isEditingLocked;\n    newOptions.usingOptionsFromDefaultPlist = self.usingOptionsFromDefaultPlist;\n  }\n  return newOptions;\n}\n\n#pragma mark - Public instance methods\n\n- (instancetype)init {\n  // Unavailable.\n  [self doesNotRecognizeSelector:_cmd];\n  return nil;\n}\n\n- (instancetype)initWithContentsOfFile:(NSString *)plistPath {\n  self = [super init];\n  if (self) {\n    if (plistPath == nil) {\n      FIRLogError(kFIRLoggerCore, @\"I-COR000013\", @\"The plist file path is nil.\");\n      return nil;\n    }\n    _optionsDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] mutableCopy];\n    if (_optionsDictionary == nil) {\n      FIRLogError(kFIRLoggerCore, @\"I-COR000014\",\n                  @\"The configuration file at %@ does not exist or \"\n                  @\"is not a well-formed plist file.\",\n                  plistPath);\n      return nil;\n    }\n    // TODO: Do we want to validate the dictionary here? It says we do that already in\n    // the public header.\n  }\n  return self;\n}\n\n- (instancetype)initWithGoogleAppID:(NSString *)googleAppID GCMSenderID:(NSString *)GCMSenderID {\n  self = [super init];\n  if (self) {\n    NSMutableDictionary *mutableOptionsDict = [NSMutableDictionary dictionary];\n    [mutableOptionsDict setValue:googleAppID forKey:kFIRGoogleAppID];\n    [mutableOptionsDict setValue:GCMSenderID forKey:kFIRGCMSenderID];\n    [mutableOptionsDict setValue:[[NSBundle mainBundle] bundleIdentifier] forKey:kFIRBundleID];\n    self.optionsDictionary = mutableOptionsDict;\n  }\n  return self;\n}\n\n- (NSString *)APIKey {\n  return self.optionsDictionary[kFIRAPIKey];\n}\n\n- (void)checkEditingLocked {\n  if (self.isEditingLocked) {\n    [NSException raise:kFirebaseCoreErrorDomain format:kFIRExceptionBadModification];\n  }\n}\n\n- (void)setAPIKey:(NSString *)APIKey {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRAPIKey] = [APIKey copy];\n}\n\n- (NSString *)clientID {\n  return self.optionsDictionary[kFIRClientID];\n}\n\n- (void)setClientID:(NSString *)clientID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRClientID] = [clientID copy];\n}\n\n- (NSString *)trackingID {\n  return self.optionsDictionary[kFIRTrackingID];\n}\n\n- (void)setTrackingID:(NSString *)trackingID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRTrackingID] = [trackingID copy];\n}\n\n- (NSString *)GCMSenderID {\n  return self.optionsDictionary[kFIRGCMSenderID];\n}\n\n- (void)setGCMSenderID:(NSString *)GCMSenderID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRGCMSenderID] = [GCMSenderID copy];\n}\n\n- (NSString *)projectID {\n  return self.optionsDictionary[kFIRProjectID];\n}\n\n- (void)setProjectID:(NSString *)projectID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRProjectID] = [projectID copy];\n}\n\n- (NSString *)androidClientID {\n  return self.optionsDictionary[kFIRAndroidClientID];\n}\n\n- (void)setAndroidClientID:(NSString *)androidClientID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRAndroidClientID] = [androidClientID copy];\n}\n\n- (NSString *)googleAppID {\n  return self.optionsDictionary[kFIRGoogleAppID];\n}\n\n- (void)setGoogleAppID:(NSString *)googleAppID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRGoogleAppID] = [googleAppID copy];\n}\n\n- (NSString *)libraryVersionID {\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    // The unit tests are set up to catch anything that does not properly convert.\n    NSString *version = FIRFirebaseVersion();\n    NSArray *components = [version componentsSeparatedByString:@\".\"];\n    NSString *major = [components objectAtIndex:0];\n    NSString *minor = [NSString stringWithFormat:@\"%02d\", [[components objectAtIndex:1] intValue]];\n    NSString *patch = [NSString stringWithFormat:@\"%02d\", [[components objectAtIndex:2] intValue]];\n    kFIRLibraryVersionID = [NSString stringWithFormat:@\"%@%@%@000\", major, minor, patch];\n  });\n  return kFIRLibraryVersionID;\n}\n\n- (void)setLibraryVersionID:(NSString *)libraryVersionID {\n  _optionsDictionary[kFIRLibraryVersionID] = [libraryVersionID copy];\n}\n\n- (NSString *)databaseURL {\n  return self.optionsDictionary[kFIRDatabaseURL];\n}\n\n- (void)setDatabaseURL:(NSString *)databaseURL {\n  [self checkEditingLocked];\n\n  _optionsDictionary[kFIRDatabaseURL] = [databaseURL copy];\n}\n\n- (NSString *)storageBucket {\n  return self.optionsDictionary[kFIRStorageBucket];\n}\n\n- (void)setStorageBucket:(NSString *)storageBucket {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRStorageBucket] = [storageBucket copy];\n}\n\n- (void)setDeepLinkURLScheme:(NSString *)deepLinkURLScheme {\n  [self checkEditingLocked];\n  _deepLinkURLScheme = [deepLinkURLScheme copy];\n}\n\n- (NSString *)bundleID {\n  return self.optionsDictionary[kFIRBundleID];\n}\n\n- (void)setBundleID:(NSString *)bundleID {\n  [self checkEditingLocked];\n  _optionsDictionary[kFIRBundleID] = [bundleID copy];\n}\n\n- (void)setAppGroupID:(NSString *)appGroupID {\n  [self checkEditingLocked];\n  _appGroupID = [appGroupID copy];\n}\n\n#pragma mark - Equality\n\n- (BOOL)isEqual:(id)object {\n  if (!object || ![object isKindOfClass:[FIROptions class]]) {\n    return NO;\n  }\n\n  return [self isEqualToOptions:(FIROptions *)object];\n}\n\n- (BOOL)isEqualToOptions:(FIROptions *)options {\n  // Skip any non-FIROptions classes.\n  if (![options isKindOfClass:[FIROptions class]]) {\n    return NO;\n  }\n\n  // Check the internal dictionary and custom properties for differences.\n  if (![options.optionsDictionary isEqualToDictionary:self.optionsDictionary]) {\n    return NO;\n  }\n\n  // Validate extra properties not contained in the dictionary. Only validate it if one of the\n  // objects has the property set.\n  if ((options.deepLinkURLScheme != nil || self.deepLinkURLScheme != nil) &&\n      ![options.deepLinkURLScheme isEqualToString:self.deepLinkURLScheme]) {\n    return NO;\n  }\n\n  if ((options.appGroupID != nil || self.appGroupID != nil) &&\n      ![options.appGroupID isEqualToString:self.appGroupID]) {\n    return NO;\n  }\n\n  // Validate the Analytics options haven't changed with the Info.plist.\n  if (![options.analyticsOptionsDictionary isEqualToDictionary:self.analyticsOptionsDictionary]) {\n    return NO;\n  }\n\n  // We don't care about the `editingLocked` or `usingOptionsFromDefaultPlist` properties since\n  // those relate to lifecycle and construction, we only care if the contents of the options\n  // themselves are equal.\n  return YES;\n}\n\n- (NSUInteger)hash {\n  // This is strongly recommended for any object that implements a custom `isEqual:` method to\n  // ensure that dictionary and set behavior matches other `isEqual:` checks.\n  // Note: `self.analyticsOptionsDictionary` was left out here since it solely relies on the\n  // contents of the main bundle's `Info.plist`. We should avoid reading that file and the contents\n  // should be identical.\n  return self.optionsDictionary.hash ^ self.deepLinkURLScheme.hash ^ self.appGroupID.hash;\n}\n\n#pragma mark - Internal instance methods\n\n- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary {\n  if (_analyticsOptionsDictionary == nil) {\n    NSMutableDictionary *tempAnalyticsOptions = [[NSMutableDictionary alloc] init];\n    NSArray *measurementKeys = @[\n      kFIRIsMeasurementEnabled, kFIRIsAnalyticsCollectionEnabled,\n      kFIRIsAnalyticsCollectionDeactivated\n    ];\n    for (NSString *key in measurementKeys) {\n      id value = infoDictionary[key] ?: self.optionsDictionary[key] ?: nil;\n      if (!value) {\n        continue;\n      }\n      tempAnalyticsOptions[key] = value;\n    }\n    _analyticsOptionsDictionary = tempAnalyticsOptions;\n  }\n  return _analyticsOptionsDictionary;\n}\n\n- (NSDictionary *)analyticsOptionsDictionary {\n  return [self analyticsOptionsDictionaryWithInfoDictionary:[NSBundle mainBundle].infoDictionary];\n}\n\n/**\n * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in\n * GoogleService-Info.plist. This uses the old plist flag IS_MEASUREMENT_ENABLED, which should still\n * be supported.\n */\n- (BOOL)isMeasurementEnabled {\n  if (self.isAnalyticsCollectionDeactivated) {\n    return NO;\n  }\n  NSNumber *value = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled];\n  if (value == nil) {\n    // TODO: This could probably be cleaned up since FIROptions shouldn't know about FIRApp or have\n    //       to check if it's the default app. The FIROptions instance can't be modified after\n    //       `+configure` is called, so it's not a good place to copy it either in case the flag is\n    //       changed at runtime.\n\n    // If no values are set for Analytics, fall back to the global collection switch in FIRApp.\n    // Analytics only supports the default FIRApp, so check that first.\n    if (![FIRApp isDefaultAppConfigured]) {\n      return NO;\n    }\n\n    // Fall back to the default app's collection switch when the key is not in the dictionary.\n    return [FIRApp defaultApp].isDataCollectionDefaultEnabled;\n  }\n  return [value boolValue];\n}\n\n- (BOOL)isAnalyticsCollectionExplicitlySet {\n  // If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication\n  // that the developer wants FirebaseAnalytics enabled so continue checking.\n  if (self.isAnalyticsCollectionDeactivated) {\n    return YES;\n  }\n\n  // Check if the current Analytics flag is set.\n  id collectionEnabledObject = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled];\n  if (collectionEnabledObject && [collectionEnabledObject isKindOfClass:[NSNumber class]]) {\n    // It doesn't matter what the value is, it's explicitly set.\n    return YES;\n  }\n\n  // Check if the old measurement flag is set.\n  id measurementEnabledObject = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled];\n  if (measurementEnabledObject && [measurementEnabledObject isKindOfClass:[NSNumber class]]) {\n    // It doesn't matter what the value is, it's explicitly set.\n    return YES;\n  }\n\n  // No flags are set to explicitly enable or disable FirebaseAnalytics.\n  return NO;\n}\n\n- (BOOL)isAnalyticsCollectionEnabled {\n  if (self.isAnalyticsCollectionDeactivated) {\n    return NO;\n  }\n  NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled];\n  if (value == nil) {\n    return self.isMeasurementEnabled;  // Fall back to older plist flag.\n  }\n  return [value boolValue];\n}\n\n- (BOOL)isAnalyticsCollectionDeactivated {\n  NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionDeactivated];\n  if (value == nil) {\n    return NO;  // Analytics Collection is not deactivated when the key is not in the dictionary.\n  }\n  return [value boolValue];\n}\n\n- (BOOL)isAnalyticsEnabled {\n  return [self.optionsDictionary[kFIRIsAnalyticsEnabled] boolValue];\n}\n\n- (BOOL)isSignInEnabled {\n  return [self.optionsDictionary[kFIRIsSignInEnabled] boolValue];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h\"\n\n#ifndef Firebase_VERSION\n#error \"Firebase_VERSION is not defined: add -DFirebase_VERSION=... to the build invocation\"\n#endif\n\n// The following two macros supply the incantation so that the C\n// preprocessor does not try to parse the version as a floating\n// point number. See\n// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/\n#define STR(x) STR_EXPAND(x)\n#define STR_EXPAND(x) #x\n\nNSString* FIRFirebaseVersion(void) {\n  return @STR(Firebase_VERSION);\n}\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAppInternal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <FirebaseCore/FIRApp.h>\n\n@class FIRComponentContainer;\n@protocol FIRLibrary;\n\n/**\n * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive\n * FIRApp notifications, log info about the success or failure of their configuration, and access\n * other internal functionality of FIRApp.\n *\n * TODO(b/28296561): Restructure this header.\n */\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_ENUM(NSInteger, FIRConfigType) {\n  FIRConfigTypeCore = 1,\n  FIRConfigTypeSDK = 2,\n};\n\nextern NSString *const kFIRDefaultAppName;\nextern NSString *const kFIRAppReadyToConfigureSDKNotification;\nextern NSString *const kFIRAppDeleteNotification;\nextern NSString *const kFIRAppIsDefaultAppKey;\nextern NSString *const kFIRAppNameKey;\nextern NSString *const kFIRGoogleAppIDKey;\nextern NSString *const kFirebaseCoreErrorDomain;\n\n/** The NSUserDefaults suite name for FirebaseCore, for those storage locations that use it. */\nextern NSString *const kFirebaseCoreDefaultsSuiteName;\n\n/**\n * The format string for the User Defaults key used for storing the data collection enabled flag.\n * This includes formatting to append the Firebase App's name.\n */\nextern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat;\n\n/**\n * The plist key used for storing the data collection enabled flag.\n */\nextern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey;\n\n/** @var FIRAuthStateDidChangeInternalNotification\n @brief The name of the @c NSNotificationCenter notification which is posted when the auth state\n changes (e.g. a new token has been produced, a user logs in or out). The object parameter of\n the notification is a dictionary possibly containing the key:\n @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not\n contain this key it indicates a sign-out event took place.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotification;\n\n/** @var FIRAuthStateDidChangeInternalNotificationTokenKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the new access token.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey;\n\n/** @var FIRAuthStateDidChangeInternalNotificationAppKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the FIRApp associated with the auth instance.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey;\n\n/** @var FIRAuthStateDidChangeInternalNotificationUIDKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the new user's UID (or nil if there is no longer a user signed in).\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey;\n\n@interface FIRApp ()\n\n/**\n * A flag indicating if this is the default app (has the default app name).\n */\n@property(nonatomic, readonly) BOOL isDefaultApp;\n\n/*\n * The container of interop SDKs for this app.\n */\n@property(nonatomic) FIRComponentContainer *container;\n\n/**\n * Checks if the default app is configured without trying to configure it.\n */\n+ (BOOL)isDefaultAppConfigured;\n\n/**\n * Registers a given third-party library with the given version number to be reported for\n * analytics.\n *\n * @param name Name of the library.\n * @param version Version of the library.\n */\n+ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version;\n\n/**\n * Registers a given internal library to be reported for analytics.\n *\n * @param library Optional parameter for component registration.\n * @param name Name of the library.\n */\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name;\n\n/**\n * Registers a given internal library with the given version number to be reported for\n * analytics. This should only be used for non-Firebase libraries that have their own versioning\n * scheme.\n *\n * @param library Optional parameter for component registration.\n * @param name Name of the library.\n * @param version Version of the library.\n */\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name\n                    withVersion:(nonnull NSString *)version;\n\n/**\n * A concatenated string representing all the third-party libraries and version numbers.\n */\n+ (NSString *)firebaseUserAgent;\n\n/**\n * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe.\n */\n+ (void)resetApps;\n\n/**\n * Can be used by the unit tests in each SDK to set customized options.\n */\n- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponent.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRApp;\n@class FIRComponentContainer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Provides a system to clean up cached instances returned from the component system.\nNS_SWIFT_NAME(ComponentLifecycleMaintainer)\n@protocol FIRComponentLifecycleMaintainer\n/// The associated app will be deleted, clean up any resources as they are about to be deallocated.\n- (void)appWillBeDeleted:(FIRApp *)app;\n@end\n\ntypedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container,\n                                                  BOOL *isCacheable)\n    NS_SWIFT_NAME(ComponentCreationBlock);\n\n@class FIRDependency;\n\n/// Describes the timing of instantiation. Note: new components should default to lazy unless there\n/// is a strong reason to be eager.\ntypedef NS_ENUM(NSInteger, FIRInstantiationTiming) {\n  FIRInstantiationTimingLazy,\n  FIRInstantiationTimingAlwaysEager,\n  FIRInstantiationTimingEagerInDefaultApp\n} NS_SWIFT_NAME(InstantiationTiming);\n\n/// A component that can be used from other Firebase SDKs.\nNS_SWIFT_NAME(Component)\n@interface FIRComponent : NSObject\n\n/// The protocol describing functionality provided from the Component.\n@property(nonatomic, strong, readonly) Protocol *protocol;\n\n/// The timing of instantiation.\n@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming;\n\n/// An array of dependencies for the component.\n@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies;\n\n/// A block to instantiate an instance of the component with the appropriate dependencies.\n@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock;\n\n// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format\n// for the next two methods.\n// clang-format off\n\n/// Creates a component with no dependencies that will be lazily initialized.\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                        creationBlock:(FIRComponentCreationBlock)creationBlock\nNS_SWIFT_NAME(init(_:creationBlock:));\n\n/// Creates a component to be registered with the component container.\n///\n/// @param protocol - The protocol describing functionality provided by the component.\n/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's\n///                              a good reason to be instantiated earlier.\n/// @param dependencies - Any dependencies the `implementingClass` has, optional or required.\n/// @param creationBlock - A block to instantiate the component with a container, and if\n/// @return A component that can be registered with the component container.\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                  instantiationTiming:(FIRInstantiationTiming)instantiationTiming\n                         dependencies:(NSArray<FIRDependency *> *)dependencies\n                        creationBlock:(FIRComponentCreationBlock)creationBlock\nNS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:));\n\n// clang-format on\n\n/// Unavailable.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainer.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A type-safe macro to retrieve a component from a container. This should be used to retrieve\n/// components instead of using the container directly.\n#define FIR_COMPONENT(type, container) \\\n  [FIRComponentType<id<type>> instanceForProtocol:@protocol(type) inContainer:container]\n\n@class FIRApp;\n\n/// A container that holds different components that are registered via the\n/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant`\n/// in order to properly register components for Core.\nNS_SWIFT_NAME(FirebaseComponentContainer)\n@interface FIRComponentContainer : NSObject\n\n/// A weak reference to the app that an instance of the container belongs to.\n@property(nonatomic, weak, readonly) FIRApp *app;\n\n/// Unavailable. Use the `container` property on `FIRApp`.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentType.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRComponentContainer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Do not use directly. A placeholder type in order to provide a macro that will warn users of\n/// mis-matched protocols.\nNS_SWIFT_NAME(ComponentType)\n@interface FIRComponentType<__covariant T> : NSObject\n\n/// Do not use directly. A factory method to retrieve an instance that provides a specific\n/// functionality.\n+ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRDiagnosticsData;\n@class FIROptions;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Connects FIRCore with the CoreDiagnostics library. */\n@interface FIRCoreDiagnosticsConnector : NSObject\n\n/** Logs FirebaseCore  related data.\n *\n * @param options The options object containing data to log.\n */\n+ (void)logCoreTelemetryWithOptions:(FIROptions *)options;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRDependency.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A dependency on a specific protocol's functionality.\nNS_SWIFT_NAME(Dependency)\n@interface FIRDependency : NSObject\n\n/// The protocol describing functionality being depended on.\n@property(nonatomic, strong, readonly) Protocol *protocol;\n\n/// A flag to specify if the dependency is required or not.\n@property(nonatomic, readonly) BOOL isRequired;\n\n/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for\n/// the required parameter.\n/// Creates a required dependency on the specified protocol's functionality.\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol;\n\n/// Creates a dependency on the specified protocol's functionality and specify if it's required for\n/// the class's functionality.\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required;\n\n/// Use `dependencyWithProtocol:isRequired:` instead.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRHeartbeatInfo : NSObject\n\n// Enum representing the different heartbeat codes.\ntypedef NS_ENUM(NSInteger, FIRHeartbeatInfoCode) {\n  FIRHeartbeatInfoCodeNone = 0,\n  FIRHeartbeatInfoCodeSDK = 1,\n  FIRHeartbeatInfoCodeGlobal = 2,\n  FIRHeartbeatInfoCodeCombined = 3,\n};\n\n/**\n * Get heartbeat code required for the sdk.\n * @param heartbeatTag String representing the sdk heartbeat tag.\n * @return Heartbeat code indicating whether or not an sdk/global heartbeat\n * needs to be sent\n */\n+ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLibrary.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef FIRLibrary_h\n#define FIRLibrary_h\n\n#import <Foundation/Foundation.h>\n\n@class FIRApp;\n@class FIRComponent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Provide an interface to register a library for userAgent logging and availability to others.\nNS_SWIFT_NAME(Library)\n@protocol FIRLibrary\n\n/// Returns one or more FIRComponents that will be registered in\n/// FIRApp and participate in dependency resolution and injection.\n+ (NSArray<FIRComponent *> *)componentsToRegister;\n\n@optional\n/// Implement this method if the library needs notifications for lifecycle events. This method is\n/// called when the developer calls `FirebaseApp.configure()`.\n+ (void)configureWithApp:(FIRApp *)app;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\n#endif /* FIRLibrary_h */\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLogger.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import <FirebaseCore/FIRLoggerLevel.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The Firebase services used in Firebase logger.\n */\ntypedef NSString *const FIRLoggerService;\n\nextern FIRLoggerService kFIRLoggerAnalytics;\nextern FIRLoggerService kFIRLoggerCrash;\nextern FIRLoggerService kFIRLoggerCore;\nextern FIRLoggerService kFIRLoggerRemoteConfig;\n\n/**\n * The key used to store the logger's error count.\n */\nextern NSString *const kFIRLoggerErrorCountKey;\n\n/**\n * The key used to store the logger's warning count.\n */\nextern NSString *const kFIRLoggerWarningCountKey;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\n/**\n * Enables or disables Analytics debug mode.\n * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug.\n * Enabling the debug mode has no effect if the app is running from App Store.\n * (required) analytics debug mode flag.\n */\nvoid FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode);\n\n/**\n * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level.\n * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store.\n * (required) log level (one of the FIRLoggerLevel enum values).\n */\nvoid FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);\n\n/**\n * Checks if the specified logger level is loggable given the current settings.\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) whether or not this function is called from the Analytics component.\n */\nBOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent);\n\n/**\n * Logs a message to the Xcode console and the device log. If running from AppStore, will\n * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming.\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) service name of type FIRLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\nextern void FIRLogBasic(FIRLoggerLevel level,\n                        FIRLoggerService service,\n                        NSString *messageCode,\n                        NSString *message,\n// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable\n// See: http://stackoverflow.com/q/29095469\n#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX\n                        va_list args_ptr\n#else\n                        va_list _Nullable args_ptr\n#endif\n);\n\n/**\n * The following functions accept the following parameters in order:\n * (required) service name of type FIRLoggerService.\n * (required) message code starting from \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n *            See go/firebase-log-proposal for details.\n * (required) message string which can be a format string.\n * (optional) the list of arguments to substitute into the format string.\n * Example usage:\n * FIRLogError(kFIRLoggerCore, @\"I-COR000001\", @\"Configuration of %@ failed.\", app.name);\n */\nextern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif  // __cplusplus\n\n@interface FIRLoggerWrapper : NSObject\n\n/**\n * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) service name of type FIRLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\n\n+ (void)logWithLevel:(FIRLoggerLevel)level\n         withService:(FIRLoggerService)service\n            withCode:(NSString *)messageCode\n         withMessage:(NSString *)message\n            withArgs:(va_list)args;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FIROptionsInternal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <FirebaseCore/FIROptions.h>\n\n/**\n * Keys for the strings in the plist file.\n */\nextern NSString *const kFIRAPIKey;\nextern NSString *const kFIRTrackingID;\nextern NSString *const kFIRGoogleAppID;\nextern NSString *const kFIRClientID;\nextern NSString *const kFIRGCMSenderID;\nextern NSString *const kFIRAndroidClientID;\nextern NSString *const kFIRDatabaseURL;\nextern NSString *const kFIRStorageBucket;\nextern NSString *const kFIRBundleID;\nextern NSString *const kFIRProjectID;\n\n/**\n * Keys for the plist file name\n */\nextern NSString *const kServiceInfoFileName;\n\nextern NSString *const kServiceInfoFileType;\n\n/**\n * This header file exposes the initialization of FIROptions to internal use.\n */\n@interface FIROptions ()\n\n/**\n * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests.\n */\n+ (void)resetDefaultOptions;\n\n/**\n * Initializes the options with dictionary. The above strings are the keys of the dictionary.\n * This is the designated initializer.\n */\n- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary\n    NS_DESIGNATED_INITIALIZER;\n\n/**\n * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and\n * other first party services.\n */\n+ (FIROptions *)defaultOptions;\n\n+ (NSDictionary *)defaultOptionsDictionary;\n\n/**\n * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at\n * runtime.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet;\n\n/**\n * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless\n * explicitly disabled in GoogleService-Info.plist.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled;\n\n/**\n * Whether or not Analytics Collection was completely disabled. If YES, then\n * isAnalyticsCollectionEnabled will be NO.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated;\n\n/**\n * The version ID of the client library, e.g. @\"1100000\".\n */\n@property(nonatomic, readonly, copy) NSString *libraryVersionID;\n\n/**\n * The flag indicating whether this object was constructed with the values in the default plist\n * file.\n */\n@property(nonatomic) BOOL usingOptionsFromDefaultPlist;\n\n/**\n * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in\n * GoogleService-Info.plist.\n */\n@property(nonatomic, readonly) BOOL isMeasurementEnabled;\n\n/**\n * Whether or not Analytics was enabled in the developer console.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsEnabled;\n\n/**\n * Whether or not SignIn was enabled in the developer console.\n */\n@property(nonatomic, readonly) BOOL isSignInEnabled;\n\n/**\n * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp.\n */\n@property(nonatomic, getter=isEditingLocked) BOOL editingLocked;\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Private/FirebaseCoreInternal.h",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// An umbrella header, for any other libraries in this repo to access Firebase Public and Private\n// headers. Any package manager complexity should be handled here.\n\n#import <FirebaseCore/FirebaseCore.h>\n\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponent.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponentContainer.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponentType.h\"\n#import \"FirebaseCore/Sources/Private/FIRDependency.h\"\n#import \"FirebaseCore/Sources/Private/FIRHeartbeatInfo.h\"\n#import \"FirebaseCore/Sources/Private/FIRLibrary.h\"\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIROptions;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A block that takes a BOOL and has no return value. */\ntypedef void (^FIRAppVoidBoolCallback)(BOOL success) NS_SWIFT_NAME(FirebaseAppVoidBoolCallback);\n\n/**\n * The entry point of Firebase SDKs.\n *\n * Initialize and configure FIRApp using +[FIRApp configure]\n * or other customized ways as shown below.\n *\n * The logging system has two modes: default mode and debug mode. In default mode, only logs with\n * log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent\n * to device. The log levels that Firebase uses are consistent with the ASL log levels.\n *\n * Enable debug mode by passing the -FIRDebugEnabled argument to the application. You can add this\n * argument in the application's Xcode scheme. When debug mode is enabled via -FIRDebugEnabled,\n * further executions of the application will also be in debug mode. In order to return to default\n * mode, you must explicitly disable the debug mode with the application argument -FIRDebugDisabled.\n *\n * It is also possible to change the default logging level in code by calling setLoggerLevel: on\n * the FIRConfiguration interface.\n */\nNS_SWIFT_NAME(FirebaseApp)\n@interface FIRApp : NSObject\n\n/**\n * Configures a default Firebase app. Raises an exception if any configuration step fails. The\n * default app is named \"__FIRAPP_DEFAULT\". This method should be called after the app is launched\n * and before using Firebase services. This method should be called from the main thread and\n * contains synchronous file I/O (reading GoogleService-Info.plist from disk).\n */\n+ (void)configure;\n\n/**\n * Configures the default Firebase app with the provided options. The default app is named\n * \"__FIRAPP_DEFAULT\". Raises an exception if any configuration step fails. This method should be\n * called from the main thread.\n *\n * @param options The Firebase application options used to configure the service.\n */\n+ (void)configureWithOptions:(FIROptions *)options NS_SWIFT_NAME(configure(options:));\n\n/**\n * Configures a Firebase app with the given name and options. Raises an exception if any\n * configuration step fails. This method should be called from the main thread.\n *\n * @param name The application's name given by the developer. The name should should only contain\n               Letters, Numbers and Underscore.\n * @param options The Firebase application options used to configure the services.\n */\n// clang-format off\n+ (void)configureWithName:(NSString *)name\n                  options:(FIROptions *)options NS_SWIFT_NAME(configure(name:options:));\n// clang-format on\n\n/**\n * Returns the default app, or nil if the default app does not exist.\n */\n+ (nullable FIRApp *)defaultApp NS_SWIFT_NAME(app());\n\n/**\n * Returns a previously created FIRApp instance with the given name, or nil if no such app exists.\n * This method is thread safe.\n */\n+ (nullable FIRApp *)appNamed:(NSString *)name NS_SWIFT_NAME(app(name:));\n\n/**\n * Returns the set of all extant FIRApp instances, or nil if there are no FIRApp instances. This\n * method is thread safe.\n */\n@property(class, readonly, nullable) NSDictionary<NSString *, FIRApp *> *allApps;\n\n/**\n * Cleans up the current FIRApp, freeing associated data and returning its name to the pool for\n * future use. This method is thread safe.\n */\n- (void)deleteApp:(FIRAppVoidBoolCallback)completion;\n\n/**\n * FIRApp instances should not be initialized directly. Call +[FIRApp configure],\n * +[FIRApp configureWithOptions:], or +[FIRApp configureWithNames:options:] directly.\n */\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n * Gets the name of this app.\n */\n@property(nonatomic, copy, readonly) NSString *name;\n\n/**\n * Gets a copy of the options for this app. These are non-modifiable.\n */\n@property(nonatomic, copy, readonly) FIROptions *options;\n\n/**\n * Gets or sets whether automatic data collection is enabled for all products. Defaults to `YES`\n * unless `FirebaseDataCollectionDefaultEnabled` is set to `NO` in your app's Info.plist. This value\n * is persisted across runs of the app so that it can be set once when users have consented to\n * collection.\n */\n@property(nonatomic, readwrite, getter=isDataCollectionDefaultEnabled)\n    BOOL dataCollectionDefaultEnabled;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FIRLoggerLevel.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * This interface provides global level properties that the developer can tweak.\n */\nNS_SWIFT_NAME(FirebaseConfiguration)\n@interface FIRConfiguration : NSObject\n\n/** Returns the shared configuration object. */\n@property(class, nonatomic, readonly) FIRConfiguration *sharedInstance NS_SWIFT_NAME(shared);\n\n/**\n * Sets the logging level for internal Firebase logging. Firebase will only log messages\n * that are logged at or below loggerLevel. The messages are logged both to the Xcode\n * console and to the device's log. Note that if an app is running from AppStore, it will\n * never log above FIRLoggerLevelNotice even if loggerLevel is set to a higher (more verbose)\n * setting.\n *\n * @param loggerLevel The maximum logging level. The default level is set to FIRLoggerLevelNotice.\n */\n- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note that importing GULLoggerLevel.h will lead to a non-modular header\n// import error.\n\n/**\n * The log levels used by internal logging.\n */\ntypedef NS_ENUM(NSInteger, FIRLoggerLevel) {\n  /** Error level, matches ASL_LEVEL_ERR. */\n  FIRLoggerLevelError = 3,\n  /** Warning level, matches ASL_LEVEL_WARNING. */\n  FIRLoggerLevelWarning = 4,\n  /** Notice level, matches ASL_LEVEL_NOTICE. */\n  FIRLoggerLevelNotice = 5,\n  /** Info level, matches ASL_LEVEL_INFO. */\n  FIRLoggerLevelInfo = 6,\n  /** Debug level, matches ASL_LEVEL_DEBUG. */\n  FIRLoggerLevelDebug = 7,\n  /** Minimum log level. */\n  FIRLoggerLevelMin = FIRLoggerLevelError,\n  /** Maximum log level. */\n  FIRLoggerLevelMax = FIRLoggerLevelDebug\n} NS_SWIFT_NAME(FirebaseLoggerLevel);\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * This class provides constant fields of Google APIs.\n */\nNS_SWIFT_NAME(FirebaseOptions)\n@interface FIROptions : NSObject <NSCopying>\n\n/**\n * Returns the default options. The first time this is called it synchronously reads\n * GoogleService-Info.plist from disk.\n */\n+ (nullable FIROptions *)defaultOptions NS_SWIFT_NAME(defaultOptions());\n\n/**\n * An iOS API key used for authenticating requests from your app, e.g.\n * @\"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk\", used to identify your app to Google servers.\n */\n@property(nonatomic, copy, nullable) NSString *APIKey NS_SWIFT_NAME(apiKey);\n\n/**\n * The bundle ID for the application. Defaults to `[[NSBundle mainBundle] bundleID]` when not set\n * manually or in a plist.\n */\n@property(nonatomic, copy) NSString *bundleID;\n\n/**\n * The OAuth2 client ID for iOS application used to authenticate Google users, for example\n * @\"12345.apps.googleusercontent.com\", used for signing in with Google.\n */\n@property(nonatomic, copy, nullable) NSString *clientID;\n\n/**\n * The tracking ID for Google Analytics, e.g. @\"UA-12345678-1\", used to configure Google Analytics.\n */\n@property(nonatomic, copy, nullable) NSString *trackingID;\n\n/**\n * The Project Number from the Google Developer's console, for example @\"012345678901\", used to\n * configure Google Cloud Messaging.\n */\n@property(nonatomic, copy) NSString *GCMSenderID NS_SWIFT_NAME(gcmSenderID);\n\n/**\n * The Project ID from the Firebase console, for example @\"abc-xyz-123\".\n */\n@property(nonatomic, copy, nullable) NSString *projectID;\n\n/**\n * The Android client ID used in Google AppInvite when an iOS app has its Android version, for\n * example @\"12345.apps.googleusercontent.com\".\n */\n@property(nonatomic, copy, nullable) NSString *androidClientID;\n\n/**\n * The Google App ID that is used to uniquely identify an instance of an app.\n */\n@property(nonatomic, copy) NSString *googleAppID;\n\n/**\n * The database root URL, e.g. @\"http://abc-xyz-123.firebaseio.com\".\n */\n@property(nonatomic, copy, nullable) NSString *databaseURL;\n\n/**\n * The URL scheme used to set up Durable Deep Link service.\n */\n@property(nonatomic, copy, nullable) NSString *deepLinkURLScheme;\n\n/**\n * The Google Cloud Storage bucket name, e.g. @\"abc-xyz-123.storage.firebase.com\".\n */\n@property(nonatomic, copy, nullable) NSString *storageBucket;\n\n/**\n * The App Group identifier to share data between the application and the application extensions.\n * The App Group must be configured in the application and on the Apple Developer Portal. Default\n * value `nil`.\n */\n@property(nonatomic, copy, nullable) NSString *appGroupID;\n\n/**\n * Initializes a customized instance of FIROptions from the file at the given plist file path. This\n * will read the file synchronously from disk.\n * For example,\n * NSString *filePath =\n *     [[NSBundle mainBundle] pathForResource:@\"GoogleService-Info\" ofType:@\"plist\"];\n * FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];\n * Returns nil if the plist file does not exist or is invalid.\n */\n- (nullable instancetype)initWithContentsOfFile:(NSString *)plistPath NS_DESIGNATED_INITIALIZER;\n\n/**\n * Initializes a customized instance of FIROptions with required fields. Use the mutable properties\n * to modify fields for configuring specific services.\n */\n// clang-format off\n- (instancetype)initWithGoogleAppID:(NSString *)googleAppID\n                        GCMSenderID:(NSString *)GCMSenderID\n    NS_SWIFT_NAME(init(googleAppID:gcmSenderID:)) NS_DESIGNATED_INITIALIZER;\n// clang-format on\n\n/** Unavailable. Please use `init(contentsOfFile:)` or `init(googleAppID:gcmSenderID:)` instead. */\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Returns the current version of Firebase. */\nNS_SWIFT_NAME(FirebaseVersion())\nNSString* FIRFirebaseVersion(void);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FIRApp.h\"\n#import \"FIRConfiguration.h\"\n#import \"FIRLoggerLevel.h\"\n#import \"FIROptions.h\"\n#import \"FIRVersion.h\"\n"
  },
  {
    "path": "Pods/FirebaseCore/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** If present, is a BOOL wrapped in an NSNumber. */\n#define kFIRCDIsDataCollectionDefaultEnabledKey @\"FIRCDIsDataCollectionDefaultEnabledKey\"\n\n/** If present, is an int32_t wrapped in an NSNumber. */\n#define kFIRCDConfigurationTypeKey @\"FIRCDConfigurationTypeKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDSdkNameKey @\"FIRCDSdkNameKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDSdkVersionKey @\"FIRCDSdkVersionKey\"\n\n/** If present, is an int32_t wrapped in an NSNumber. */\n#define kFIRCDllAppsCountKey @\"FIRCDllAppsCountKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDGoogleAppIDKey @\"FIRCDGoogleAppIDKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDBundleIDKey @\"FIRCDBundleID\"\n\n/** If present, is a BOOL wrapped in an NSNumber. */\n#define kFIRCDUsingOptionsFromDefaultPlistKey @\"FIRCDUsingOptionsFromDefaultPlistKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDLibraryVersionIDKey @\"FIRCDLibraryVersionIDKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDFirebaseUserAgentKey @\"FIRCDFirebaseUserAgentKey\"\n\n/** Defines the interface of a data object needed to log diagnostics data. */\n@protocol FIRCoreDiagnosticsData <NSObject>\n\n@required\n\n/** A dictionary containing data (non-exhaustive) to be logged in diagnostics. */\n@property(nonatomic) NSDictionary<NSString *, id> *diagnosticObjects;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FIRCoreDiagnosticsData.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Allows the interoperation of FirebaseCore and FirebaseCoreDiagnostics. */\n@protocol FIRCoreDiagnosticsInterop <NSObject>\n\n/** Sends the given diagnostics data.\n *\n * @param diagnosticsData The diagnostics data object to send.\n */\n+ (void)sendDiagnosticsData:(id<FIRCoreDiagnosticsData>)diagnosticsData;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCore/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/FirebaseCore/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![License](https://img.shields.io/cocoapods/l/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![Platform](https://img.shields.io/cocoapods/p/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n\n[![Actions Status][gh-abtesting-badge]][gh-actions]\n[![Actions Status][gh-appcheck-badge]][gh-actions]\n[![Actions Status][gh-appdistribution-badge]][gh-actions]\n[![Actions Status][gh-auth-badge]][gh-actions]\n[![Actions Status][gh-cocoapods-integration-badge]][gh-actions]\n[![Actions Status][gh-core-badge]][gh-actions]\n[![Actions Status][gh-core-diagnostics-badge]][gh-actions]\n[![Actions Status][gh-crashlytics-badge]][gh-actions]\n[![Actions Status][gh-database-badge]][gh-actions]\n[![Actions Status][gh-datatransport-badge]][gh-actions]\n[![Actions Status][gh-dynamiclinks-badge]][gh-actions]\n[![Actions Status][gh-firebasepod-badge]][gh-actions]\n[![Actions Status][gh-firestore-badge]][gh-actions]\n[![Actions Status][gh-functions-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-components-badge]][gh-actions]\n[![Actions Status][gh-inappmessaging-badge]][gh-actions]\n[![Actions Status][gh-interop-badge]][gh-actions]\n[![Actions Status][gh-messaging-badge]][gh-actions]\n[![Actions Status][gh-mlmodeldownloader-badge]][gh-actions]\n[![Actions Status][gh-performance-badge]][gh-actions]\n[![Actions Status][gh-remoteconfig-badge]][gh-actions]\n[![Actions Status][gh-storage-badge]][gh-actions]\n[![Actions Status][gh-symbolcollision-badge]][gh-actions]\n[![Actions Status][gh-zip-badge]][gh-actions]\n[![Travis](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)\n\n# Firebase Apple Open Source Development\n\nThis repository contains all Apple platform Firebase SDK source except FirebaseAnalytics\nand FirebaseML.\n\nFirebase is an app development platform with tools to help you build, grow and\nmonetize your app. More information about Firebase can be found on the\n[official Firebase website](https://firebase.google.com).\n\n**Note** _FirebaseCombineSwift_ contains support for Apple's Combine framework. This module is currently under development, and not yet supported for use in production environments. Fore more details, please refer to the [docs](FirebaseCombineSwift/README.md).\n\n## Installation\n\nSee the subsections below for details about the different installation methods.\n1. [Standard pod install](README.md#standard-pod-install)\n1. [Swift Package Manager](SwiftPackageManager.md)\n1. [Installing from the GitHub repo](README.md#installing-from-github)\n1. [Experimental Carthage](README.md#carthage-ios-only)\n\n### Standard pod install\n\nGo to\n[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).\n\n### Swift Package Manager\n\nInstructions for [Swift Package Manager](https://swift.org/package-manager/) support can be\nfound at [SwiftPackageManager.md](SwiftPackageManager.md).\n\n### Installing from GitHub\n\nThese instructions can be used to access the Firebase repo at other branches,\ntags, or commits.\n\n#### Background\n\nSee\n[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)\nfor instructions and options about overriding pod source locations.\n\n#### Accessing Firebase Source Snapshots\n\nAll of the official releases are tagged in this repo and available via CocoaPods. To access a local\nsource snapshot or unreleased branch, use Podfile directives like the following:\n\nTo access FirebaseFirestore via a branch:\n```ruby\npod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\npod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\n```\n\nTo access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:\n\n```ruby\npod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'\npod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'\n```\n\n### Carthage (iOS only)\n\nInstructions for the experimental Carthage distribution are at\n[Carthage](Carthage.md).\n\n### Using Firebase from a Framework or a library\n\n[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md)\n\n## Development\n\nTo develop Firebase software in this repository, ensure that you have at least\nthe following software:\n\n  * Xcode 12.2 (or later)\n\nCocoaPods is still the canonical way to develop, but much of the repo now supports\ndevelopment with Swift Package Manager.\n\n### CocoaPods\n\nInstall\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n```ruby\npod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios\n```\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\nFirestore has a self contained Xcode project. See\n[Firestore/README.md](Firestore/README.md).\n\n#### Development for Catalyst\n* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Swift Package Manager\n* To enable test schemes: `./scripts/setup_spm_tests.sh`\n* `open Package.swift` or double click `Package.swift` in Finder.\n* Xcode will open the project\n  * Choose a scheme for a library to build or test suite to run\n  * Choose a target platform by selecting the run destination along with the scheme\n\n### Adding a New Firebase Pod\n\nSee [AddNewPod.md](AddNewPod.md).\n\n### Managing Headers and Imports\n\nSee [HeadersImports.md](HeadersImports.md).\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n### Running Sample Apps\nIn order to run the sample apps and integration tests, you'll need a valid\n`GoogleService-Info.plist` file. The Firebase Xcode project contains dummy plist\nfiles without real values, but can be replaced with real plist files. To get your own\n`GoogleService-Info.plist` files:\n\n1. Go to the [Firebase Console](https://console.firebase.google.com/)\n2. Create a new Firebase project, if you don't already have one\n3. For each sample app you want to test, create a new Firebase app with the sample app's bundle\nidentifier (e.g. `com.google.Database-Example`)\n4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project.\n\n### Coverage Report Generation\n\nSee [scripts/code_coverage_report/README.md](scripts/code_coverage_report/README.md).\n\n## Specific Component Instructions\nSee the sections below for any special instructions for those components.\n\n### Firebase Auth\n\nIf you're doing specific Firebase Auth development, see\n[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about\nbuilding and running the FirebaseAuth pod along with various samples and tests.\n\n### Firebase Database\n\nThe Firebase Database Integration tests can be run against a locally running Database Emulator\nor against a production instance.\n\nTo run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before\nrunning the integration test.\n\nTo run against a production instance, provide a valid GoogleServices-Info.plist and copy it to\n`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to\n[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are\nrunning.\n\n### Firebase Performance Monitoring\nIf you're doing specific Firebase Performance Monitoring development, see\n[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK\nand [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about\nintegrating Performance with the dev test App.\n\n### Firebase Storage\n\nTo run the Storage Integration tests, follow the instructions in\n[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m).\n\n#### Push Notifications\n\nPush notifications can only be delivered to specially provisioned App IDs in the developer portal.\nIn order to actually test receiving push notifications, you will need to:\n\n1. Change the bundle identifier of the sample app to something you own in your Apple Developer\naccount, and enable that App ID for push notifications.\n2. You'll also need to\n[upload your APNs Provider Authentication Key or certificate to the\nFirebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)\nat **Project Settings > Cloud Messaging > [Your Firebase App]**.\n3. Ensure your iOS device is added to your Apple Developer portal as a test device.\n\n#### iOS Simulator\n\nThe iOS Simulator cannot register for remote notifications, and will not receive push notifications.\nIn order to receive push notifications, you'll have to follow the steps above and run the app on a\nphysical device.\n\n## Building with Firebase on Apple platforms\n\nAt this time, not all of Firebase's products are available across all Apple platforms. However,\nFirebase is constantly evolving and community supported efforts have helped expand Firebase's support.\nTo keep up with the latest info regarding Firebase's support across Apple platforms, refer to\n[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform)\nin Firebase's documentation.\n\n### Community Supported Efforts\n\nWe've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are\nvery grateful!  We'd like to empower as many developers as we can to be able to use Firebase and\nparticipate in the Firebase community.\n\n#### tvOS, macOS, watchOS and Catalyst\nThanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and\nwork on tvOS, macOS, watchOS and Catalyst.\n\nFor tvOS, see the [Sample](Example/tvOSSample).\nFor watchOS, currently only Messaging, Storage and Crashlytics (and their dependencies) have limited\nsupport. See the [Independent Watch App Sample](Example/watchOSSample).\n\nKeep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and\nthis repository is actively developed primarily for iOS. While we can catch basic unit test issues\nwith GitHub Actions, there may be some changes where the SDK no longer works as expected on macOS,\ntvOS or watchOS. If you encounter this, please\n[file an issue](https://github.com/firebase/firebase-ios-sdk/issues).\n\nDuring app setup in the console, you may get to a step that mentions something like \"Checking if the\napp has communicated with our servers\". This relies on Analytics and will not work on\nmacOS/tvOS/watchOS/Catalyst.\n**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.\n\n#### Additional MacOS and Catalyst Notes\n\n* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`\nto Build Settings.\n* For Catalyst, FirebaseFirestore requires signing the\n[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).\n\n#### Additional Crashlytics Notes\n* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are\nnot recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded)\n\n## Roadmap\n\nSee [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source\nplans and directions.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase\niOS SDK.\n\n## License\n\nThe contents of this repository are licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\nYour use of Firebase is governed by the\n[Terms of Service for Firebase Services](https://firebase.google.com/terms/).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg\n[gh-appcheck-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/app_check/badge.svg\n[gh-appdistribution-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/appdistribution/badge.svg\n[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg\n[gh-cocoapods-integration-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/cocoapods-integration/badge.svg\n[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg\n[gh-core-diagnostics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core-diagnostics/badge.svg\n[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg\n[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg\n[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg\n[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg\n[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg\n[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg\n[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg\n[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg\n[gh-google-utilities-components-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities-components/badge.svg\n[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg\n[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg\n[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg\n[gh-mlmodeldownloader-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/mlmodeldownloader/badge.svg\n[gh-performance-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/performance/badge.svg\n[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg\n[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg\n[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg\n[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <objc/runtime.h>\n#include <sys/utsname.h>\n\n#import <GoogleDataTransport/GoogleDataTransport.h>\n\n#import <GoogleUtilities/GULAppEnvironmentUtil.h>\n#import <GoogleUtilities/GULHeartbeatDateStorage.h>\n#import <GoogleUtilities/GULLogger.h>\n\n#import \"Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h\"\n#import \"Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h\"\n\n#import <nanopb/pb.h>\n#import <nanopb/pb_decode.h>\n#import <nanopb/pb_encode.h>\n\n#import \"Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h\"\n\n/** The logger service string to use when printing to the console. */\nstatic GULLoggerService kFIRCoreDiagnostics = @\"[FirebaseCoreDiagnostics/FIRCoreDiagnostics]\";\n\n#ifdef FIREBASE_BUILD_ZIP_FILE\nstatic BOOL kUsingZipFile = YES;\n#else   // FIREBASE_BUILD_ZIP_FILE\nstatic BOOL kUsingZipFile = NO;\n#endif  // FIREBASE_BUILD_ZIP_FILE\n\n#if SWIFT_PACKAGE\n#define kDeploymentType logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_SPM\n#elif FIREBASE_BUILD_CARTHAGE\n#define kDeploymentType logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_CARTHAGE\n#elif FIREBASE_BUILD_ZIP_FILE\n#define kDeploymentType logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_ZIP_FILE\n#else\n#define kDeploymentType logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_COCOAPODS\n#endif\n\nstatic NSString *const kFIRServiceMLModelInterpreter = @\"MLModelInterpreter\";\n\nstatic NSString *const kFIRServiceAdMob = @\"AdMob\";\nstatic NSString *const kFIRServiceAuth = @\"Auth\";\nstatic NSString *const kFIRServiceAuthUI = @\"AuthUI\";\nstatic NSString *const kFIRServiceCrash = @\"Crash\";\nstatic NSString *const kFIRServiceDatabase = @\"Database\";\nstatic NSString *const kFIRServiceDynamicLinks = @\"DynamicLinks\";\nstatic NSString *const kFIRServiceFirestore = @\"Firestore\";\nstatic NSString *const kFIRServiceFunctions = @\"Functions\";\nstatic NSString *const kFIRServiceIAM = @\"InAppMessaging\";\nstatic NSString *const kFIRServiceInstanceID = @\"InstanceID\";\nstatic NSString *const kFIRServiceInvites = @\"Invites\";\nstatic NSString *const kFIRServiceMessaging = @\"Messaging\";\nstatic NSString *const kFIRServiceMeasurement = @\"Measurement\";\nstatic NSString *const kFIRServicePerformance = @\"Performance\";\nstatic NSString *const kFIRServiceRemoteConfig = @\"RemoteConfig\";\nstatic NSString *const kFIRServiceStorage = @\"Storage\";\nstatic NSString *const kGGLServiceAnalytics = @\"Analytics\";\nstatic NSString *const kGGLServiceSignIn = @\"SignIn\";\nstatic NSString *const kFIRAppDiagnosticsConfigurationTypeKey =\n    @\"FIRAppDiagnosticsConfigurationTypeKey\";\nstatic NSString *const kFIRAppDiagnosticsFIRAppKey = @\"FIRAppDiagnosticsFIRAppKey\";\nstatic NSString *const kFIRAppDiagnosticsSDKNameKey = @\"FIRAppDiagnosticsSDKNameKey\";\nstatic NSString *const kFIRAppDiagnosticsSDKVersionKey = @\"FIRAppDiagnosticsSDKVersionKey\";\nstatic NSString *const kFIRCoreDiagnosticsHeartbeatTag = @\"FIRCoreDiagnostics\";\n\n/**\n * The file name to the recent heartbeat date.\n */\nNSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @\"FIREBASE_DIAGNOSTICS_HEARTBEAT_DATE\";\n\n/**\n * @note This should implement the GDTCOREventDataObject protocol, but can't because of\n * weak-linking.\n */\n@interface FIRCoreDiagnosticsLog : NSObject\n\n/** The config that will be converted to proto bytes. */\n@property(nonatomic) logs_proto_mobilesdk_ios_ICoreConfiguration config;\n\n@end\n\n@implementation FIRCoreDiagnosticsLog\n\n- (instancetype)initWithConfig:(logs_proto_mobilesdk_ios_ICoreConfiguration)config {\n  self = [super init];\n  if (self) {\n    _config = config;\n  }\n  return self;\n}\n\n// Provided and required by the GDTCOREventDataObject protocol.\n- (NSData *)transportBytes {\n  pb_ostream_t sizestream = PB_OSTREAM_SIZING;\n\n  // Encode 1 time to determine the size.\n  if (!pb_encode(&sizestream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {\n    GDTCORLogError(GDTCORMCETransportBytesError, @\"Error in nanopb encoding for size: %s\",\n                   PB_GET_ERROR(&sizestream));\n  }\n\n  // Encode a 2nd time to actually get the bytes from it.\n  size_t bufferSize = sizestream.bytes_written;\n  CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);\n  CFDataSetLength(dataRef, bufferSize);\n  pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);\n  if (!pb_encode(&ostream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {\n    GDTCORLogError(GDTCORMCETransportBytesError, @\"Error in nanopb encoding for bytes: %s\",\n                   PB_GET_ERROR(&ostream));\n  }\n  CFDataSetLength(dataRef, ostream.bytes_written);\n\n  return CFBridgingRelease(dataRef);\n}\n\n- (void)dealloc {\n  pb_release(logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config);\n}\n\n@end\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class produces a protobuf containing diagnostics and usage data to be logged. */\n@interface FIRCoreDiagnostics : NSObject <FIRCoreDiagnosticsInterop>\n\n/** The queue on which all diagnostics collection will occur. */\n@property(nonatomic, readonly) dispatch_queue_t diagnosticsQueue;\n\n/** The transport object used to send data. */\n@property(nonatomic, readonly) GDTCORTransport *transport;\n\n/** The storage to store the date of the last sent heartbeat. */\n@property(nonatomic, readonly) GULHeartbeatDateStorage *heartbeatDateStorage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\n@implementation FIRCoreDiagnostics\n\n+ (instancetype)sharedInstance {\n  static FIRCoreDiagnostics *sharedInstance;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[FIRCoreDiagnostics alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (instancetype)init {\n  GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@\"137\"\n                                                             transformers:nil\n                                                                   target:kGDTCORTargetFLL];\n\n  GULHeartbeatDateStorage *dateStorage =\n      [[GULHeartbeatDateStorage alloc] initWithFileName:kFIRCoreDiagnosticsHeartbeatDateFileName];\n\n  return [self initWithTransport:transport heartbeatDateStorage:dateStorage];\n}\n\n/** Initializer for unit tests.\n *\n * @param transport A `GDTCORTransport` instance which that be used to send event.\n * @param heartbeatDateStorage An instanse of date storage to track heartbeat sending.\n * @return Returns the initialized `FIRCoreDiagnostics` instance.\n */\n- (instancetype)initWithTransport:(GDTCORTransport *)transport\n             heartbeatDateStorage:(GULHeartbeatDateStorage *)heartbeatDateStorage {\n  self = [super init];\n  if (self) {\n    _diagnosticsQueue =\n        dispatch_queue_create(\"com.google.FIRCoreDiagnostics\", DISPATCH_QUEUE_SERIAL);\n    _transport = transport;\n    _heartbeatDateStorage = heartbeatDateStorage;\n  }\n  return self;\n}\n\n#pragma mark - nanopb helper functions\n\n/** Callocs a pb_bytes_array and copies the given NSString's bytes into the bytes array.\n *\n * @note Memory needs to be free manually, through pb_free or pb_release.\n * @param string The string to encode as pb_bytes.\n */\npb_bytes_array_t *FIREncodeString(NSString *string) {\n  NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding];\n  return FIREncodeData(stringBytes);\n}\n\n/** Callocs a pb_bytes_array and copies the given NSData bytes into the bytes array.\n *\n * @note Memory needs to be free manually, through pb_free or pb_release.\n * @param data The data to copy into the new bytes array.\n */\npb_bytes_array_t *FIREncodeData(NSData *data) {\n  pb_bytes_array_t *pbBytesArray = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(data.length));\n  if (pbBytesArray != NULL) {\n    [data getBytes:pbBytesArray->bytes length:data.length];\n    pbBytesArray->size = (pb_size_t)data.length;\n  }\n  return pbBytesArray;\n}\n\n/** Maps a service string to the representative nanopb enum.\n *\n * @param serviceString The SDK service string to convert.\n * @return The representative nanopb enum.\n */\nlogs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType FIRMapFromServiceStringToTypeEnum(\n    NSString *serviceString) {\n  static NSDictionary<NSString *, NSNumber *> *serviceStringToTypeEnum;\n  if (serviceStringToTypeEnum == nil) {\n    serviceStringToTypeEnum = @{\n      kFIRServiceAdMob : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ADMOB),\n      kFIRServiceMessaging : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MESSAGING),\n      kFIRServiceMeasurement :\n          @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MEASUREMENT),\n      kFIRServiceRemoteConfig :\n          @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_REMOTE_CONFIG),\n      kFIRServiceDatabase : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_DATABASE),\n      kFIRServiceDynamicLinks :\n          @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_DYNAMIC_LINKS),\n      kFIRServiceAuth : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_AUTH),\n      kFIRServiceAuthUI : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_AUTH_UI),\n      kFIRServiceFirestore : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_FIRESTORE),\n      kFIRServiceFunctions : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_FUNCTIONS),\n      kFIRServicePerformance :\n          @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_PERFORMANCE),\n      kFIRServiceStorage : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_STORAGE),\n      kFIRServiceMLModelInterpreter :\n          @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_MODEL_INTERPRETER),\n      kGGLServiceAnalytics : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ANALYTICS),\n      kGGLServiceSignIn : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_SIGN_IN),\n      kFIRServiceIAM : @(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_IN_APP_MESSAGING),\n    };\n  }\n  if (serviceStringToTypeEnum[serviceString] != nil) {\n    return (int32_t)serviceStringToTypeEnum[serviceString].longLongValue;\n  }\n  return logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_UNKNOWN_SDK_SERVICE;\n}\n\n#pragma mark - Proto population functions\n\n/** Populates the given proto with data related to an SDK logDiagnostics call from the\n * diagnosticObjects dictionary.\n *\n * @param config The proto to populate\n * @param diagnosticObjects The dictionary of diagnostics objects.\n */\nvoid FIRPopulateProtoWithInfoFromUserInfoParams(logs_proto_mobilesdk_ios_ICoreConfiguration *config,\n                                                NSDictionary<NSString *, id> *diagnosticObjects) {\n  NSNumber *configurationType = diagnosticObjects[kFIRCDConfigurationTypeKey];\n  if (configurationType != nil) {\n    switch (configurationType.integerValue) {\n      case logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_CORE:\n        config->configuration_type =\n            logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_CORE;\n        config->has_configuration_type = 1;\n        break;\n      case logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_SDK:\n        config->configuration_type =\n            logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_SDK;\n        config->has_configuration_type = 1;\n        break;\n      default:\n        break;\n    }\n  }\n\n  NSString *sdkName = diagnosticObjects[kFIRCDSdkNameKey];\n  if (sdkName) {\n    config->sdk_name = FIRMapFromServiceStringToTypeEnum(sdkName);\n    config->has_sdk_name = 1;\n  }\n\n  NSString *version = diagnosticObjects[kFIRCDSdkVersionKey];\n  if (version) {\n    config->sdk_version = FIREncodeString(version);\n  }\n}\n\n/** Populates the given proto with data from the calling FIRApp using the given\n * diagnosticObjects dictionary.\n *\n * @param config The proto to populate\n * @param diagnosticObjects The dictionary of diagnostics objects.\n */\nvoid FIRPopulateProtoWithCommonInfoFromApp(logs_proto_mobilesdk_ios_ICoreConfiguration *config,\n                                           NSDictionary<NSString *, id> *diagnosticObjects) {\n  config->pod_name = logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_FIREBASE;\n  config->has_pod_name = 1;\n\n  if (!diagnosticObjects[kFIRCDllAppsCountKey]) {\n    GDTCORLogError(GDTCORMCEGeneralError, @\"%@\",\n                   @\"App count is a required value in the data dict.\");\n  }\n  config->app_count = (int32_t)[diagnosticObjects[kFIRCDllAppsCountKey] integerValue];\n  config->has_app_count = 1;\n\n  NSString *googleAppID = diagnosticObjects[kFIRCDGoogleAppIDKey];\n  if (googleAppID.length) {\n    config->app_id = FIREncodeString(googleAppID);\n  }\n\n  NSString *bundleID = diagnosticObjects[kFIRCDBundleIDKey];\n  if (bundleID.length) {\n    config->bundle_id = FIREncodeString(bundleID);\n  }\n\n  NSString *firebaseUserAgent = diagnosticObjects[kFIRCDFirebaseUserAgentKey];\n  if (firebaseUserAgent.length) {\n    config->platform_info = FIREncodeString(firebaseUserAgent);\n  }\n\n  NSNumber *usingOptionsFromDefaultPlist = diagnosticObjects[kFIRCDUsingOptionsFromDefaultPlistKey];\n  if (usingOptionsFromDefaultPlist != nil) {\n    config->use_default_app = [usingOptionsFromDefaultPlist boolValue];\n    config->has_use_default_app = 1;\n  }\n\n  NSString *libraryVersionID = diagnosticObjects[kFIRCDLibraryVersionIDKey];\n  if (libraryVersionID) {\n    config->icore_version = FIREncodeString(libraryVersionID);\n  }\n\n  NSString *deviceModel = [GULAppEnvironmentUtil deviceModel];\n  if (deviceModel.length) {\n    config->device_model = FIREncodeString(deviceModel);\n  }\n\n  NSString *osVersion = [GULAppEnvironmentUtil systemVersion];\n  if (osVersion.length) {\n    config->os_version = FIREncodeString(osVersion);\n  }\n\n  config->using_zip_file = kUsingZipFile;\n  config->has_using_zip_file = 1;\n  config->deployment_type = kDeploymentType;\n  config->has_deployment_type = 1;\n  config->deployed_in_app_store = [GULAppEnvironmentUtil isFromAppStore];\n  config->has_deployed_in_app_store = 1;\n}\n\n/** Populates the given proto with installed services data.\n *\n * @param config The proto to populate\n */\nvoid FIRPopulateProtoWithInstalledServices(logs_proto_mobilesdk_ios_ICoreConfiguration *config) {\n  NSMutableArray<NSNumber *> *sdkServiceInstalledArray = [NSMutableArray array];\n\n  // AdMob\n  if (NSClassFromString(@\"GADBannerView\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceAdMob))];\n  }\n  // CloudMessaging\n  if (NSClassFromString(@\"FIRMessaging\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceMessaging))];\n  }\n  // RemoteConfig\n  if (NSClassFromString(@\"FIRRemoteConfig\") != nil) {\n    [sdkServiceInstalledArray\n        addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceRemoteConfig))];\n  }\n  // Measurement/Analtyics\n  if (NSClassFromString(@\"FIRAnalytics\") != nil) {\n    [sdkServiceInstalledArray\n        addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceMeasurement))];\n  }\n  // ML Model Interpreter\n  if (NSClassFromString(@\"FIRCustomModelInterpreter\") != nil) {\n    [sdkServiceInstalledArray\n        addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceMLModelInterpreter))];\n  }\n  // Database\n  if (NSClassFromString(@\"FIRDatabase\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceDatabase))];\n  }\n  // DynamicDeepLink\n  if (NSClassFromString(@\"FIRDynamicLinks\") != nil) {\n    [sdkServiceInstalledArray\n        addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceDynamicLinks))];\n  }\n  // Auth\n  if (NSClassFromString(@\"FIRAuth\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceAuth))];\n  }\n  // AuthUI\n  if (NSClassFromString(@\"FUIAuth\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceAuthUI))];\n  }\n  // Firestore\n  if (NSClassFromString(@\"FIRFirestore\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceFirestore))];\n  }\n  // Functions\n  if (NSClassFromString(@\"FIRFunctions\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceFunctions))];\n  }\n  // Performance\n  if (NSClassFromString(@\"FIRPerformance\") != nil) {\n    [sdkServiceInstalledArray\n        addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServicePerformance))];\n  }\n  // Storage\n  if (NSClassFromString(@\"FIRStorage\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceStorage))];\n  }\n  // SignIn via Google pod\n  if (NSClassFromString(@\"GIDSignIn\") != nil && NSClassFromString(@\"GGLContext\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kGGLServiceSignIn))];\n  }\n  // Analytics via Google pod\n  if (NSClassFromString(@\"GAI\") != nil && NSClassFromString(@\"GGLContext\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kGGLServiceAnalytics))];\n  }\n\n  // In-App Messaging\n  if (NSClassFromString(@\"FIRInAppMessaging\") != nil) {\n    [sdkServiceInstalledArray addObject:@(FIRMapFromServiceStringToTypeEnum(kFIRServiceIAM))];\n  }\n\n  logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *servicesInstalled =\n      calloc(sdkServiceInstalledArray.count,\n             sizeof(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType));\n  if (servicesInstalled == NULL) {\n    return;\n  }\n  for (NSUInteger i = 0; i < sdkServiceInstalledArray.count; i++) {\n    NSNumber *typeEnum = sdkServiceInstalledArray[i];\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType serviceType =\n        (int32_t)typeEnum.integerValue;\n    servicesInstalled[i] = serviceType;\n  }\n\n  config->sdk_service_installed = servicesInstalled;\n  config->sdk_service_installed_count = (int32_t)sdkServiceInstalledArray.count;\n}\n\n/** Populates the proto with Info.plist values.\n *\n * @param config The proto to populate.\n */\nvoid FIRPopulateProtoWithInfoPlistValues(logs_proto_mobilesdk_ios_ICoreConfiguration *config) {\n  NSDictionary<NSString *, id> *info = [[NSBundle mainBundle] infoDictionary];\n\n  NSString *xcodeVersion = info[@\"DTXcodeBuild\"] ?: @\"\";\n  NSString *sdkVersion = info[@\"DTSDKBuild\"] ?: @\"\";\n  NSString *combinedVersions = [NSString stringWithFormat:@\"%@-%@\", xcodeVersion, sdkVersion];\n  config->apple_framework_version = FIREncodeString(combinedVersions);\n\n  NSString *minVersion = info[@\"MinimumOSVersion\"];\n  if (minVersion) {\n    config->min_supported_ios_version = FIREncodeString(minVersion);\n  }\n\n  // Apps can turn off swizzling in the Info.plist, check if they've explicitly set the value and\n  // report it. It's enabled by default.\n  NSNumber *appDelegateSwizzledNum = info[@\"FirebaseAppDelegateProxyEnabled\"];\n  BOOL appDelegateSwizzled = YES;\n  if ([appDelegateSwizzledNum isKindOfClass:[NSNumber class]]) {\n    appDelegateSwizzled = [appDelegateSwizzledNum boolValue];\n  }\n  config->swizzling_enabled = appDelegateSwizzled;\n  config->has_swizzling_enabled = 1;\n}\n\n#pragma mark - FIRCoreDiagnosticsInterop\n\n+ (void)sendDiagnosticsData:(nonnull id<FIRCoreDiagnosticsData>)diagnosticsData {\n  FIRCoreDiagnostics *diagnostics = [FIRCoreDiagnostics sharedInstance];\n  [diagnostics sendDiagnosticsData:diagnosticsData];\n}\n\n- (void)sendDiagnosticsData:(nonnull id<FIRCoreDiagnosticsData>)diagnosticsData {\n  dispatch_async(self.diagnosticsQueue, ^{\n    NSDictionary<NSString *, id> *diagnosticObjects = diagnosticsData.diagnosticObjects;\n    NSNumber *isDataCollectionDefaultEnabled =\n        diagnosticObjects[kFIRCDIsDataCollectionDefaultEnabledKey];\n    if (isDataCollectionDefaultEnabled && ![isDataCollectionDefaultEnabled boolValue]) {\n      return;\n    }\n\n    // Create the proto.\n    logs_proto_mobilesdk_ios_ICoreConfiguration icore_config =\n        logs_proto_mobilesdk_ios_ICoreConfiguration_init_default;\n\n    icore_config.using_gdt = 1;\n    icore_config.has_using_gdt = 1;\n\n    // Populate the proto with information.\n    FIRPopulateProtoWithInfoFromUserInfoParams(&icore_config, diagnosticObjects);\n    FIRPopulateProtoWithCommonInfoFromApp(&icore_config, diagnosticObjects);\n    FIRPopulateProtoWithInstalledServices(&icore_config);\n    FIRPopulateProtoWithInfoPlistValues(&icore_config);\n    [self setHeartbeatFlagIfNeededToConfig:&icore_config];\n\n    // This log object is capable of converting the proto to bytes.\n    FIRCoreDiagnosticsLog *log = [[FIRCoreDiagnosticsLog alloc] initWithConfig:icore_config];\n\n    // Send the log as a telemetry event.\n    GDTCOREvent *event = [self.transport eventForTransport];\n    event.dataObject = (id<GDTCOREventDataObject>)log;\n    [self.transport sendTelemetryEvent:event];\n  });\n}\n\n#pragma mark - Heartbeat\n\n- (void)setHeartbeatFlagIfNeededToConfig:(logs_proto_mobilesdk_ios_ICoreConfiguration *)config {\n  // Check if need to send a heartbeat.\n  NSDate *currentDate = [NSDate date];\n  NSDate *lastCheckin =\n      [self.heartbeatDateStorage heartbeatDateForTag:kFIRCoreDiagnosticsHeartbeatTag];\n  if (lastCheckin) {\n    // Ensure the previous checkin was on a different date in the past.\n    if ([self isDate:currentDate inSameDayOrBeforeThan:lastCheckin]) {\n      return;\n    }\n  }\n\n  // Update heartbeat sent date.\n  [self.heartbeatDateStorage setHearbeatDate:currentDate forTag:kFIRCoreDiagnosticsHeartbeatTag];\n  // Set the flag.\n  config->sdk_name = logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ICORE;\n  config->has_sdk_name = 1;\n}\n\n- (BOOL)isDate:(NSDate *)date1 inSameDayOrBeforeThan:(NSDate *)date2 {\n  return [[NSCalendar currentCalendar] isDate:date1 inSameDayAsDate:date2] ||\n         [date1 compare:date2] == NSOrderedAscending;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Automatically generated nanopb constant definitions */\n/* Generated by nanopb-0.3.9.7 */\n\n#include \"firebasecore.nanopb.h\"\n\n/* @@protoc_insertion_point(includes) */\n#if PB_PROTO_HEADER_VERSION != 30\n#error Regenerate this file with the current version of nanopb generator.\n#endif\n\n\n\nconst pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22] = {\n    PB_FIELD(  1, UENUM   , OPTIONAL, STATIC  , FIRST, logs_proto_mobilesdk_ios_ICoreConfiguration, configuration_type, configuration_type, 0),\n    PB_FIELD(  7, UENUM   , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_installed, configuration_type, 0),\n    PB_FIELD(  9, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, device_model, sdk_service_installed, 0),\n    PB_FIELD( 10, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_id, device_model, 0),\n    PB_FIELD( 12, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, bundle_id, app_id, 0),\n    PB_FIELD( 16, UENUM   , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, pod_name, bundle_id, 0),\n    PB_FIELD( 18, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, icore_version, pod_name, 0),\n    PB_FIELD( 19, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_version, icore_version, 0),\n    PB_FIELD( 20, UENUM   , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_name, sdk_version, 0),\n    PB_FIELD( 21, INT32   , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_count, sdk_name, 0),\n    PB_FIELD( 22, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, os_version, app_count, 0),\n    PB_FIELD( 24, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, min_supported_ios_version, os_version, 0),\n    PB_FIELD( 25, BOOL    , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, use_default_app, min_supported_ios_version, 0),\n    PB_FIELD( 26, BOOL    , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployed_in_app_store, use_default_app, 0),\n    PB_FIELD( 27, INT32   , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, dynamic_framework_count, deployed_in_app_store, 0),\n    PB_FIELD( 28, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, apple_framework_version, dynamic_framework_count, 0),\n    PB_FIELD( 29, BOOL    , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_zip_file, apple_framework_version, 0),\n    PB_FIELD( 30, UENUM   , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployment_type, using_zip_file, 0),\n    PB_FIELD( 31, BYTES   , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, platform_info, deployment_type, 0),\n    PB_FIELD( 33, BOOL    , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, swizzling_enabled, platform_info, 0),\n    PB_FIELD( 36, BOOL    , OPTIONAL, STATIC  , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_gdt, swizzling_enabled, 0),\n    PB_LAST_FIELD\n};\n\n\n\n\n\n\n\n/* @@protoc_insertion_point(eof) */\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Automatically generated nanopb header */\n/* Generated by nanopb-0.3.9.7 */\n\n#ifndef PB_LOGS_PROTO_MOBILESDK_IOS_FIREBASECORE_NANOPB_H_INCLUDED\n#define PB_LOGS_PROTO_MOBILESDK_IOS_FIREBASECORE_NANOPB_H_INCLUDED\n#include <nanopb/pb.h>\n\n/* @@protoc_insertion_point(includes) */\n#if PB_PROTO_HEADER_VERSION != 30\n#error Regenerate this file with the current version of nanopb generator.\n#endif\n\n\n/* Enum definitions */\ntypedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType {\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_UNKNOWN_CONFIGURATION_TYPE = 0,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_CORE = 1,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_SDK = 2\n} logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType;\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_UNKNOWN_CONFIGURATION_TYPE\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MAX logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_SDK\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_ARRAYSIZE ((logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType)(logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_SDK+1))\n\ntypedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType {\n    logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_UNKNOWN_BUILD_TYPE = 0,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_INTERNAL = 1,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_EAP = 2,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_PROD = 3\n} logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType;\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MIN logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_UNKNOWN_BUILD_TYPE\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MAX logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_PROD\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_ARRAYSIZE ((logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType)(logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_PROD+1))\n\ntypedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType {\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_UNKNOWN_SDK_SERVICE = 0,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ICORE = 1,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ADMOB = 2,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_APP_INVITE = 3,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_SIGN_IN = 5,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_GCM = 6,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MAPS = 7,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_SCION = 8,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ANALYTICS = 9,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_APP_INDEXING = 10,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_CONFIG = 11,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_DURABLE_DEEP_LINKS = 12,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_CRASH = 13,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_AUTH = 14,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_DATABASE = 15,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_STORAGE = 16,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MESSAGING = 17,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MEASUREMENT = 18,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_REMOTE_CONFIG = 19,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_DYNAMIC_LINKS = 20,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_INVITES = 21,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_AUTH_UI = 22,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_FIRESTORE = 23,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_PERFORMANCE = 24,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_FACE = 26,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_BARCODE = 27,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_TEXT = 28,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_LABEL = 29,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_MODEL_INTERPRETER = 30,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_IN_APP_MESSAGING = 31,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_FUNCTIONS = 32,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_NATURAL_LANGUAGE = 33,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_AUTOML = 34,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_OBJECT_DETECTION = 35\n} logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType;\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_UNKNOWN_SDK_SERVICE\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MAX logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_OBJECT_DETECTION\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ARRAYSIZE ((logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType)(logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ML_VISION_ON_DEVICE_OBJECT_DETECTION+1))\n\ntypedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName {\n    logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_UNKNOWN_POD_NAME = 0,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_GOOGLE = 1,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_FIREBASE = 2\n} logs_proto_mobilesdk_ios_ICoreConfiguration_PodName;\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_UNKNOWN_POD_NAME\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MAX logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_FIREBASE\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_ARRAYSIZE ((logs_proto_mobilesdk_ios_ICoreConfiguration_PodName)(logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_FIREBASE+1))\n\ntypedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType {\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_UNKNOWN = 0,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_COCOAPODS = 1,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_ZIP_FILE = 2,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_CARTHAGE = 3,\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_SPM = 4\n} logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType;\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_UNKNOWN\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MAX logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_SPM\n#define _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_ARRAYSIZE ((logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType)(logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_SPM+1))\n\n/* Struct definitions */\ntypedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {\n    bool has_configuration_type;\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType configuration_type;\n    pb_size_t sdk_service_installed_count;\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *sdk_service_installed;\n    pb_bytes_array_t *device_model;\n    pb_bytes_array_t *app_id;\n    pb_bytes_array_t *bundle_id;\n    bool has_pod_name;\n    logs_proto_mobilesdk_ios_ICoreConfiguration_PodName pod_name;\n    pb_bytes_array_t *icore_version;\n    pb_bytes_array_t *sdk_version;\n    bool has_sdk_name;\n    logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType sdk_name;\n    bool has_app_count;\n    int32_t app_count;\n    pb_bytes_array_t *os_version;\n    pb_bytes_array_t *min_supported_ios_version;\n    bool has_use_default_app;\n    bool use_default_app;\n    bool has_deployed_in_app_store;\n    bool deployed_in_app_store;\n    bool has_dynamic_framework_count;\n    int32_t dynamic_framework_count;\n    pb_bytes_array_t *apple_framework_version;\n    bool has_using_zip_file;\n    bool using_zip_file;\n    bool has_deployment_type;\n    logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType deployment_type;\n    pb_bytes_array_t *platform_info;\n    bool has_swizzling_enabled;\n    bool swizzling_enabled;\n    bool has_using_gdt;\n    bool using_gdt;\n/* @@protoc_insertion_point(struct:logs_proto_mobilesdk_ios_ICoreConfiguration) */\n} logs_proto_mobilesdk_ios_ICoreConfiguration;\n\n/* Default values for struct fields */\n\n/* Initializer values for message structs */\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_default {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_zero {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}\n\n/* Field tags (for use in manual encoding/decoding) */\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_pod_name_tag 16\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_configuration_type_tag 1\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_icore_version_tag 18\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_version_tag 19\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_service_installed_tag 7\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_name_tag 20\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_device_model_tag 9\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_os_version_tag 22\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_id_tag 10\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_bundle_id_tag 12\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_min_supported_ios_version_tag 24\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_use_default_app_tag 25\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_count_tag 21\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployed_in_app_store_tag 26\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_dynamic_framework_count_tag 27\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_apple_framework_version_tag 28\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_zip_file_tag 29\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployment_type_tag 30\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_platform_info_tag 31\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_swizzling_enabled_tag 33\n#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_gdt_tag 36\n\n/* Struct field encoding specification for nanopb */\nextern const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22];\n\n/* Maximum encoded size of messages (where known) */\n/* logs_proto_mobilesdk_ios_ICoreConfiguration_size depends on runtime parameters */\n\n/* Message IDs (where set with \"msgid\" option) */\n#ifdef PB_MSGID\n\n#define FIREBASECORE_MESSAGES \\\n\n\n#endif\n\n/* @@protoc_insertion_point(eof) */\n\n#endif\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Public/FIRCoreDiagnostics.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// There are no actual public headers in the lib. This is a dummy public header to prevent Cocoapods\n// from adding all internal headers as public.\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** If present, is a BOOL wrapped in an NSNumber. */\n#define kFIRCDIsDataCollectionDefaultEnabledKey @\"FIRCDIsDataCollectionDefaultEnabledKey\"\n\n/** If present, is an int32_t wrapped in an NSNumber. */\n#define kFIRCDConfigurationTypeKey @\"FIRCDConfigurationTypeKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDSdkNameKey @\"FIRCDSdkNameKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDSdkVersionKey @\"FIRCDSdkVersionKey\"\n\n/** If present, is an int32_t wrapped in an NSNumber. */\n#define kFIRCDllAppsCountKey @\"FIRCDllAppsCountKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDGoogleAppIDKey @\"FIRCDGoogleAppIDKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDBundleIDKey @\"FIRCDBundleID\"\n\n/** If present, is a BOOL wrapped in an NSNumber. */\n#define kFIRCDUsingOptionsFromDefaultPlistKey @\"FIRCDUsingOptionsFromDefaultPlistKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDLibraryVersionIDKey @\"FIRCDLibraryVersionIDKey\"\n\n/** If present, is an NSString. */\n#define kFIRCDFirebaseUserAgentKey @\"FIRCDFirebaseUserAgentKey\"\n\n/** Defines the interface of a data object needed to log diagnostics data. */\n@protocol FIRCoreDiagnosticsData <NSObject>\n\n@required\n\n/** A dictionary containing data (non-exhaustive) to be logged in diagnostics. */\n@property(nonatomic) NSDictionary<NSString *, id> *diagnosticObjects;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FIRCoreDiagnosticsData.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Allows the interoperation of FirebaseCore and FirebaseCoreDiagnostics. */\n@protocol FIRCoreDiagnosticsInterop <NSObject>\n\n/** Sends the given diagnostics data.\n *\n * @param diagnosticsData The diagnostics data object to send.\n */\n+ (void)sendDiagnosticsData:(id<FIRCoreDiagnosticsData>)diagnosticsData;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/FirebaseCoreDiagnostics/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![License](https://img.shields.io/cocoapods/l/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![Platform](https://img.shields.io/cocoapods/p/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n\n[![Actions Status][gh-abtesting-badge]][gh-actions]\n[![Actions Status][gh-appcheck-badge]][gh-actions]\n[![Actions Status][gh-appdistribution-badge]][gh-actions]\n[![Actions Status][gh-auth-badge]][gh-actions]\n[![Actions Status][gh-cocoapods-integration-badge]][gh-actions]\n[![Actions Status][gh-core-badge]][gh-actions]\n[![Actions Status][gh-core-diagnostics-badge]][gh-actions]\n[![Actions Status][gh-crashlytics-badge]][gh-actions]\n[![Actions Status][gh-database-badge]][gh-actions]\n[![Actions Status][gh-datatransport-badge]][gh-actions]\n[![Actions Status][gh-dynamiclinks-badge]][gh-actions]\n[![Actions Status][gh-firebasepod-badge]][gh-actions]\n[![Actions Status][gh-firestore-badge]][gh-actions]\n[![Actions Status][gh-functions-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-components-badge]][gh-actions]\n[![Actions Status][gh-inappmessaging-badge]][gh-actions]\n[![Actions Status][gh-interop-badge]][gh-actions]\n[![Actions Status][gh-messaging-badge]][gh-actions]\n[![Actions Status][gh-mlmodeldownloader-badge]][gh-actions]\n[![Actions Status][gh-performance-badge]][gh-actions]\n[![Actions Status][gh-remoteconfig-badge]][gh-actions]\n[![Actions Status][gh-storage-badge]][gh-actions]\n[![Actions Status][gh-symbolcollision-badge]][gh-actions]\n[![Actions Status][gh-zip-badge]][gh-actions]\n[![Travis](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)\n\n# Firebase Apple Open Source Development\n\nThis repository contains all Apple platform Firebase SDK source except FirebaseAnalytics\nand FirebaseML.\n\nFirebase is an app development platform with tools to help you build, grow and\nmonetize your app. More information about Firebase can be found on the\n[official Firebase website](https://firebase.google.com).\n\n**Note** _FirebaseCombineSwift_ contains support for Apple's Combine framework. This module is currently under development, and not yet supported for use in production environments. Fore more details, please refer to the [docs](FirebaseCombineSwift/README.md).\n\n## Installation\n\nSee the subsections below for details about the different installation methods.\n1. [Standard pod install](README.md#standard-pod-install)\n1. [Swift Package Manager](SwiftPackageManager.md)\n1. [Installing from the GitHub repo](README.md#installing-from-github)\n1. [Experimental Carthage](README.md#carthage-ios-only)\n\n### Standard pod install\n\nGo to\n[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).\n\n### Swift Package Manager\n\nInstructions for [Swift Package Manager](https://swift.org/package-manager/) support can be\nfound at [SwiftPackageManager.md](SwiftPackageManager.md).\n\n### Installing from GitHub\n\nThese instructions can be used to access the Firebase repo at other branches,\ntags, or commits.\n\n#### Background\n\nSee\n[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)\nfor instructions and options about overriding pod source locations.\n\n#### Accessing Firebase Source Snapshots\n\nAll of the official releases are tagged in this repo and available via CocoaPods. To access a local\nsource snapshot or unreleased branch, use Podfile directives like the following:\n\nTo access FirebaseFirestore via a branch:\n```ruby\npod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\npod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\n```\n\nTo access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:\n\n```ruby\npod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'\npod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'\n```\n\n### Carthage (iOS only)\n\nInstructions for the experimental Carthage distribution are at\n[Carthage](Carthage.md).\n\n### Using Firebase from a Framework or a library\n\n[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md)\n\n## Development\n\nTo develop Firebase software in this repository, ensure that you have at least\nthe following software:\n\n  * Xcode 12.2 (or later)\n\nCocoaPods is still the canonical way to develop, but much of the repo now supports\ndevelopment with Swift Package Manager.\n\n### CocoaPods\n\nInstall\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n```ruby\npod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios\n```\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\nFirestore has a self contained Xcode project. See\n[Firestore/README.md](Firestore/README.md).\n\n#### Development for Catalyst\n* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Swift Package Manager\n* To enable test schemes: `./scripts/setup_spm_tests.sh`\n* `open Package.swift` or double click `Package.swift` in Finder.\n* Xcode will open the project\n  * Choose a scheme for a library to build or test suite to run\n  * Choose a target platform by selecting the run destination along with the scheme\n\n### Adding a New Firebase Pod\n\nSee [AddNewPod.md](AddNewPod.md).\n\n### Managing Headers and Imports\n\nSee [HeadersImports.md](HeadersImports.md).\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n### Running Sample Apps\nIn order to run the sample apps and integration tests, you'll need a valid\n`GoogleService-Info.plist` file. The Firebase Xcode project contains dummy plist\nfiles without real values, but can be replaced with real plist files. To get your own\n`GoogleService-Info.plist` files:\n\n1. Go to the [Firebase Console](https://console.firebase.google.com/)\n2. Create a new Firebase project, if you don't already have one\n3. For each sample app you want to test, create a new Firebase app with the sample app's bundle\nidentifier (e.g. `com.google.Database-Example`)\n4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project.\n\n### Coverage Report Generation\n\nSee [scripts/code_coverage_report/README.md](scripts/code_coverage_report/README.md).\n\n## Specific Component Instructions\nSee the sections below for any special instructions for those components.\n\n### Firebase Auth\n\nIf you're doing specific Firebase Auth development, see\n[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about\nbuilding and running the FirebaseAuth pod along with various samples and tests.\n\n### Firebase Database\n\nThe Firebase Database Integration tests can be run against a locally running Database Emulator\nor against a production instance.\n\nTo run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before\nrunning the integration test.\n\nTo run against a production instance, provide a valid GoogleServices-Info.plist and copy it to\n`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to\n[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are\nrunning.\n\n### Firebase Performance Monitoring\nIf you're doing specific Firebase Performance Monitoring development, see\n[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK\nand [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about\nintegrating Performance with the dev test App.\n\n### Firebase Storage\n\nTo run the Storage Integration tests, follow the instructions in\n[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m).\n\n#### Push Notifications\n\nPush notifications can only be delivered to specially provisioned App IDs in the developer portal.\nIn order to actually test receiving push notifications, you will need to:\n\n1. Change the bundle identifier of the sample app to something you own in your Apple Developer\naccount, and enable that App ID for push notifications.\n2. You'll also need to\n[upload your APNs Provider Authentication Key or certificate to the\nFirebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)\nat **Project Settings > Cloud Messaging > [Your Firebase App]**.\n3. Ensure your iOS device is added to your Apple Developer portal as a test device.\n\n#### iOS Simulator\n\nThe iOS Simulator cannot register for remote notifications, and will not receive push notifications.\nIn order to receive push notifications, you'll have to follow the steps above and run the app on a\nphysical device.\n\n## Building with Firebase on Apple platforms\n\nAt this time, not all of Firebase's products are available across all Apple platforms. However,\nFirebase is constantly evolving and community supported efforts have helped expand Firebase's support.\nTo keep up with the latest info regarding Firebase's support across Apple platforms, refer to\n[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform)\nin Firebase's documentation.\n\n### Community Supported Efforts\n\nWe've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are\nvery grateful!  We'd like to empower as many developers as we can to be able to use Firebase and\nparticipate in the Firebase community.\n\n#### tvOS, macOS, watchOS and Catalyst\nThanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and\nwork on tvOS, macOS, watchOS and Catalyst.\n\nFor tvOS, see the [Sample](Example/tvOSSample).\nFor watchOS, currently only Messaging, Storage and Crashlytics (and their dependencies) have limited\nsupport. See the [Independent Watch App Sample](Example/watchOSSample).\n\nKeep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and\nthis repository is actively developed primarily for iOS. While we can catch basic unit test issues\nwith GitHub Actions, there may be some changes where the SDK no longer works as expected on macOS,\ntvOS or watchOS. If you encounter this, please\n[file an issue](https://github.com/firebase/firebase-ios-sdk/issues).\n\nDuring app setup in the console, you may get to a step that mentions something like \"Checking if the\napp has communicated with our servers\". This relies on Analytics and will not work on\nmacOS/tvOS/watchOS/Catalyst.\n**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.\n\n#### Additional MacOS and Catalyst Notes\n\n* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`\nto Build Settings.\n* For Catalyst, FirebaseFirestore requires signing the\n[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).\n\n#### Additional Crashlytics Notes\n* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are\nnot recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded)\n\n## Roadmap\n\nSee [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source\nplans and directions.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase\niOS SDK.\n\n## License\n\nThe contents of this repository are licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\nYour use of Firebase is governed by the\n[Terms of Service for Firebase Services](https://firebase.google.com/terms/).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg\n[gh-appcheck-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/app_check/badge.svg\n[gh-appdistribution-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/appdistribution/badge.svg\n[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg\n[gh-cocoapods-integration-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/cocoapods-integration/badge.svg\n[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg\n[gh-core-diagnostics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core-diagnostics/badge.svg\n[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg\n[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg\n[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg\n[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg\n[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg\n[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg\n[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg\n[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg\n[gh-google-utilities-components-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities-components/badge.svg\n[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg\n[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg\n[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg\n[gh-mlmodeldownloader-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/mlmodeldownloader/badge.svg\n[gh-performance-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/performance/badge.svg\n[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg\n[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg\n[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg\n[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRAppInternal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <FirebaseCore/FIRApp.h>\n\n@class FIRComponentContainer;\n@protocol FIRLibrary;\n\n/**\n * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive\n * FIRApp notifications, log info about the success or failure of their configuration, and access\n * other internal functionality of FIRApp.\n *\n * TODO(b/28296561): Restructure this header.\n */\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_ENUM(NSInteger, FIRConfigType) {\n  FIRConfigTypeCore = 1,\n  FIRConfigTypeSDK = 2,\n};\n\nextern NSString *const kFIRDefaultAppName;\nextern NSString *const kFIRAppReadyToConfigureSDKNotification;\nextern NSString *const kFIRAppDeleteNotification;\nextern NSString *const kFIRAppIsDefaultAppKey;\nextern NSString *const kFIRAppNameKey;\nextern NSString *const kFIRGoogleAppIDKey;\nextern NSString *const kFirebaseCoreErrorDomain;\n\n/** The NSUserDefaults suite name for FirebaseCore, for those storage locations that use it. */\nextern NSString *const kFirebaseCoreDefaultsSuiteName;\n\n/**\n * The format string for the User Defaults key used for storing the data collection enabled flag.\n * This includes formatting to append the Firebase App's name.\n */\nextern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat;\n\n/**\n * The plist key used for storing the data collection enabled flag.\n */\nextern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey;\n\n/** @var FIRAuthStateDidChangeInternalNotification\n @brief The name of the @c NSNotificationCenter notification which is posted when the auth state\n changes (e.g. a new token has been produced, a user logs in or out). The object parameter of\n the notification is a dictionary possibly containing the key:\n @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not\n contain this key it indicates a sign-out event took place.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotification;\n\n/** @var FIRAuthStateDidChangeInternalNotificationTokenKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the new access token.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey;\n\n/** @var FIRAuthStateDidChangeInternalNotificationAppKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the FIRApp associated with the auth instance.\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey;\n\n/** @var FIRAuthStateDidChangeInternalNotificationUIDKey\n @brief A key present in the dictionary object parameter of the\n @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this\n key will contain the new user's UID (or nil if there is no longer a user signed in).\n */\nextern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey;\n\n@interface FIRApp ()\n\n/**\n * A flag indicating if this is the default app (has the default app name).\n */\n@property(nonatomic, readonly) BOOL isDefaultApp;\n\n/*\n * The container of interop SDKs for this app.\n */\n@property(nonatomic) FIRComponentContainer *container;\n\n/**\n * Checks if the default app is configured without trying to configure it.\n */\n+ (BOOL)isDefaultAppConfigured;\n\n/**\n * Registers a given third-party library with the given version number to be reported for\n * analytics.\n *\n * @param name Name of the library.\n * @param version Version of the library.\n */\n+ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version;\n\n/**\n * Registers a given internal library to be reported for analytics.\n *\n * @param library Optional parameter for component registration.\n * @param name Name of the library.\n */\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name;\n\n/**\n * Registers a given internal library with the given version number to be reported for\n * analytics. This should only be used for non-Firebase libraries that have their own versioning\n * scheme.\n *\n * @param library Optional parameter for component registration.\n * @param name Name of the library.\n * @param version Version of the library.\n */\n+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library\n                       withName:(nonnull NSString *)name\n                    withVersion:(nonnull NSString *)version;\n\n/**\n * A concatenated string representing all the third-party libraries and version numbers.\n */\n+ (NSString *)firebaseUserAgent;\n\n/**\n * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe.\n */\n+ (void)resetApps;\n\n/**\n * Can be used by the unit tests in each SDK to set customized options.\n */\n- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRComponent.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRApp;\n@class FIRComponentContainer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Provides a system to clean up cached instances returned from the component system.\nNS_SWIFT_NAME(ComponentLifecycleMaintainer)\n@protocol FIRComponentLifecycleMaintainer\n/// The associated app will be deleted, clean up any resources as they are about to be deallocated.\n- (void)appWillBeDeleted:(FIRApp *)app;\n@end\n\ntypedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container,\n                                                  BOOL *isCacheable)\n    NS_SWIFT_NAME(ComponentCreationBlock);\n\n@class FIRDependency;\n\n/// Describes the timing of instantiation. Note: new components should default to lazy unless there\n/// is a strong reason to be eager.\ntypedef NS_ENUM(NSInteger, FIRInstantiationTiming) {\n  FIRInstantiationTimingLazy,\n  FIRInstantiationTimingAlwaysEager,\n  FIRInstantiationTimingEagerInDefaultApp\n} NS_SWIFT_NAME(InstantiationTiming);\n\n/// A component that can be used from other Firebase SDKs.\nNS_SWIFT_NAME(Component)\n@interface FIRComponent : NSObject\n\n/// The protocol describing functionality provided from the Component.\n@property(nonatomic, strong, readonly) Protocol *protocol;\n\n/// The timing of instantiation.\n@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming;\n\n/// An array of dependencies for the component.\n@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies;\n\n/// A block to instantiate an instance of the component with the appropriate dependencies.\n@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock;\n\n// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format\n// for the next two methods.\n// clang-format off\n\n/// Creates a component with no dependencies that will be lazily initialized.\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                        creationBlock:(FIRComponentCreationBlock)creationBlock\nNS_SWIFT_NAME(init(_:creationBlock:));\n\n/// Creates a component to be registered with the component container.\n///\n/// @param protocol - The protocol describing functionality provided by the component.\n/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's\n///                              a good reason to be instantiated earlier.\n/// @param dependencies - Any dependencies the `implementingClass` has, optional or required.\n/// @param creationBlock - A block to instantiate the component with a container, and if\n/// @return A component that can be registered with the component container.\n+ (instancetype)componentWithProtocol:(Protocol *)protocol\n                  instantiationTiming:(FIRInstantiationTiming)instantiationTiming\n                         dependencies:(NSArray<FIRDependency *> *)dependencies\n                        creationBlock:(FIRComponentCreationBlock)creationBlock\nNS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:));\n\n// clang-format on\n\n/// Unavailable.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRComponentContainer.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A type-safe macro to retrieve a component from a container. This should be used to retrieve\n/// components instead of using the container directly.\n#define FIR_COMPONENT(type, container) \\\n  [FIRComponentType<id<type>> instanceForProtocol:@protocol(type) inContainer:container]\n\n@class FIRApp;\n\n/// A container that holds different components that are registered via the\n/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant`\n/// in order to properly register components for Core.\nNS_SWIFT_NAME(FirebaseComponentContainer)\n@interface FIRComponentContainer : NSObject\n\n/// A weak reference to the app that an instance of the container belongs to.\n@property(nonatomic, weak, readonly) FIRApp *app;\n\n/// Unavailable. Use the `container` property on `FIRApp`.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRComponentType.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRComponentContainer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Do not use directly. A placeholder type in order to provide a macro that will warn users of\n/// mis-matched protocols.\nNS_SWIFT_NAME(ComponentType)\n@interface FIRComponentType<__covariant T> : NSObject\n\n/// Do not use directly. A factory method to retrieve an instance that provides a specific\n/// functionality.\n+ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRDiagnosticsData;\n@class FIROptions;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Connects FIRCore with the CoreDiagnostics library. */\n@interface FIRCoreDiagnosticsConnector : NSObject\n\n/** Logs FirebaseCore  related data.\n *\n * @param options The options object containing data to log.\n */\n+ (void)logCoreTelemetryWithOptions:(FIROptions *)options;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRDependency.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A dependency on a specific protocol's functionality.\nNS_SWIFT_NAME(Dependency)\n@interface FIRDependency : NSObject\n\n/// The protocol describing functionality being depended on.\n@property(nonatomic, strong, readonly) Protocol *protocol;\n\n/// A flag to specify if the dependency is required or not.\n@property(nonatomic, readonly) BOOL isRequired;\n\n/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for\n/// the required parameter.\n/// Creates a required dependency on the specified protocol's functionality.\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol;\n\n/// Creates a dependency on the specified protocol's functionality and specify if it's required for\n/// the class's functionality.\n+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required;\n\n/// Use `dependencyWithProtocol:isRequired:` instead.\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRHeartbeatInfo : NSObject\n\n// Enum representing the different heartbeat codes.\ntypedef NS_ENUM(NSInteger, FIRHeartbeatInfoCode) {\n  FIRHeartbeatInfoCodeNone = 0,\n  FIRHeartbeatInfoCodeSDK = 1,\n  FIRHeartbeatInfoCodeGlobal = 2,\n  FIRHeartbeatInfoCodeCombined = 3,\n};\n\n/**\n * Get heartbeat code required for the sdk.\n * @param heartbeatTag String representing the sdk heartbeat tag.\n * @return Heartbeat code indicating whether or not an sdk/global heartbeat\n * needs to be sent\n */\n+ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRLibrary.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef FIRLibrary_h\n#define FIRLibrary_h\n\n#import <Foundation/Foundation.h>\n\n@class FIRApp;\n@class FIRComponent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Provide an interface to register a library for userAgent logging and availability to others.\nNS_SWIFT_NAME(Library)\n@protocol FIRLibrary\n\n/// Returns one or more FIRComponents that will be registered in\n/// FIRApp and participate in dependency resolution and injection.\n+ (NSArray<FIRComponent *> *)componentsToRegister;\n\n@optional\n/// Implement this method if the library needs notifications for lifecycle events. This method is\n/// called when the developer calls `FirebaseApp.configure()`.\n+ (void)configureWithApp:(FIRApp *)app;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\n#endif /* FIRLibrary_h */\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIRLogger.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import <FirebaseCore/FIRLoggerLevel.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The Firebase services used in Firebase logger.\n */\ntypedef NSString *const FIRLoggerService;\n\nextern FIRLoggerService kFIRLoggerAnalytics;\nextern FIRLoggerService kFIRLoggerCrash;\nextern FIRLoggerService kFIRLoggerCore;\nextern FIRLoggerService kFIRLoggerRemoteConfig;\n\n/**\n * The key used to store the logger's error count.\n */\nextern NSString *const kFIRLoggerErrorCountKey;\n\n/**\n * The key used to store the logger's warning count.\n */\nextern NSString *const kFIRLoggerWarningCountKey;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\n/**\n * Enables or disables Analytics debug mode.\n * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug.\n * Enabling the debug mode has no effect if the app is running from App Store.\n * (required) analytics debug mode flag.\n */\nvoid FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode);\n\n/**\n * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level.\n * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store.\n * (required) log level (one of the FIRLoggerLevel enum values).\n */\nvoid FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);\n\n/**\n * Checks if the specified logger level is loggable given the current settings.\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) whether or not this function is called from the Analytics component.\n */\nBOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent);\n\n/**\n * Logs a message to the Xcode console and the device log. If running from AppStore, will\n * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming.\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) service name of type FIRLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\nextern void FIRLogBasic(FIRLoggerLevel level,\n                        FIRLoggerService service,\n                        NSString *messageCode,\n                        NSString *message,\n// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable\n// See: http://stackoverflow.com/q/29095469\n#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX\n                        va_list args_ptr\n#else\n                        va_list _Nullable args_ptr\n#endif\n);\n\n/**\n * The following functions accept the following parameters in order:\n * (required) service name of type FIRLoggerService.\n * (required) message code starting from \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n *            See go/firebase-log-proposal for details.\n * (required) message string which can be a format string.\n * (optional) the list of arguments to substitute into the format string.\n * Example usage:\n * FIRLogError(kFIRLoggerCore, @\"I-COR000001\", @\"Configuration of %@ failed.\", app.name);\n */\nextern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\nextern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...)\n    NS_FORMAT_FUNCTION(3, 4);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif  // __cplusplus\n\n@interface FIRLoggerWrapper : NSObject\n\n/**\n * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger\n * (required) log level (one of the FIRLoggerLevel enum values).\n * (required) service name of type FIRLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\n\n+ (void)logWithLevel:(FIRLoggerLevel)level\n         withService:(FIRLoggerService)service\n            withCode:(NSString *)messageCode\n         withMessage:(NSString *)message\n            withArgs:(va_list)args;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FIROptionsInternal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <FirebaseCore/FIROptions.h>\n\n/**\n * Keys for the strings in the plist file.\n */\nextern NSString *const kFIRAPIKey;\nextern NSString *const kFIRTrackingID;\nextern NSString *const kFIRGoogleAppID;\nextern NSString *const kFIRClientID;\nextern NSString *const kFIRGCMSenderID;\nextern NSString *const kFIRAndroidClientID;\nextern NSString *const kFIRDatabaseURL;\nextern NSString *const kFIRStorageBucket;\nextern NSString *const kFIRBundleID;\nextern NSString *const kFIRProjectID;\n\n/**\n * Keys for the plist file name\n */\nextern NSString *const kServiceInfoFileName;\n\nextern NSString *const kServiceInfoFileType;\n\n/**\n * This header file exposes the initialization of FIROptions to internal use.\n */\n@interface FIROptions ()\n\n/**\n * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests.\n */\n+ (void)resetDefaultOptions;\n\n/**\n * Initializes the options with dictionary. The above strings are the keys of the dictionary.\n * This is the designated initializer.\n */\n- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary\n    NS_DESIGNATED_INITIALIZER;\n\n/**\n * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and\n * other first party services.\n */\n+ (FIROptions *)defaultOptions;\n\n+ (NSDictionary *)defaultOptionsDictionary;\n\n/**\n * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at\n * runtime.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet;\n\n/**\n * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless\n * explicitly disabled in GoogleService-Info.plist.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled;\n\n/**\n * Whether or not Analytics Collection was completely disabled. If YES, then\n * isAnalyticsCollectionEnabled will be NO.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated;\n\n/**\n * The version ID of the client library, e.g. @\"1100000\".\n */\n@property(nonatomic, readonly, copy) NSString *libraryVersionID;\n\n/**\n * The flag indicating whether this object was constructed with the values in the default plist\n * file.\n */\n@property(nonatomic) BOOL usingOptionsFromDefaultPlist;\n\n/**\n * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in\n * GoogleService-Info.plist.\n */\n@property(nonatomic, readonly) BOOL isMeasurementEnabled;\n\n/**\n * Whether or not Analytics was enabled in the developer console.\n */\n@property(nonatomic, readonly) BOOL isAnalyticsEnabled;\n\n/**\n * Whether or not SignIn was enabled in the developer console.\n */\n@property(nonatomic, readonly) BOOL isSignInEnabled;\n\n/**\n * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp.\n */\n@property(nonatomic, getter=isEditingLocked) BOOL editingLocked;\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseCore/Sources/Private/FirebaseCoreInternal.h",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// An umbrella header, for any other libraries in this repo to access Firebase Public and Private\n// headers. Any package manager complexity should be handled here.\n\n#import <FirebaseCore/FirebaseCore.h>\n\n#import \"FirebaseCore/Sources/Private/FIRAppInternal.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponent.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponentContainer.h\"\n#import \"FirebaseCore/Sources/Private/FIRComponentType.h\"\n#import \"FirebaseCore/Sources/Private/FIRDependency.h\"\n#import \"FirebaseCore/Sources/Private/FIRHeartbeatInfo.h\"\n#import \"FirebaseCore/Sources/Private/FIRLibrary.h\"\n#import \"FirebaseCore/Sources/Private/FIRLogger.h\"\n#import \"FirebaseCore/Sources/Private/FIROptionsInternal.h\"\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h\"\n\n@class FIRInstallationsHTTPError;\n@class FBLPromise<ResultType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\nvoid FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer);\n\n@interface FIRInstallationsErrorUtil : NSObject\n\n+ (NSError *)keyedArchiverErrorWithException:(NSException *)exception;\n+ (NSError *)keyedArchiverErrorWithError:(NSError *)error;\n\n+ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status;\n\n+ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName;\n\n+ (NSError *)JSONSerializationError:(NSError *)error;\n\n+ (NSError *)networkErrorWithError:(NSError *)error;\n\n+ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName;\n\n+ (NSError *)corruptedIIDTokenData;\n\n+ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse\n                                                   data:(nullable NSData *)data;\n+ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode;\n\n+ (NSError *)backoffIntervalWaitError;\n\n/**\n * Returns the passed error if it is already in the public domain or a new error with the passed\n * error at `NSUnderlyingErrorKey`.\n */\n+ (NSError *)publicDomainErrorWithError:(NSError *)error;\n\n+ (FBLPromise *)rejectedPromiseWithError:(NSError *)error;\n\n+ (NSError *)installationsErrorWithCode:(FIRInstallationsErrorCode)code\n                          failureReason:(nullable NSString *)failureReason\n                        underlyingError:(nullable NSError *)underlyingError;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\nNSString *const kFirebaseInstallationsErrorDomain = @\"com.firebase.installations\";\n\nvoid FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer) {\n  if (pointer != NULL) {\n    *pointer = error;\n  }\n}\n\n@implementation FIRInstallationsErrorUtil\n\n+ (NSError *)keyedArchiverErrorWithException:(NSException *)exception {\n  NSString *failureReason = [NSString\n      stringWithFormat:@\"NSKeyedArchiver exception with name: %@, reason: %@, userInfo: %@\",\n                       exception.name, exception.reason, exception.userInfo];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (NSError *)keyedArchiverErrorWithError:(NSError *)error {\n  NSString *failureReason = [NSString stringWithFormat:@\"NSKeyedArchiver error.\"];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:error];\n}\n\n+ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status {\n  NSString *failureReason = [NSString stringWithFormat:@\"%@ (%li)\", keychainFunction, (long)status];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeKeychain\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName {\n  NSString *failureReason =\n      [NSString stringWithFormat:@\"Installation for appID %@ appName %@ not found\", appID, appName];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (NSError *)corruptedIIDTokenData {\n  NSString *failureReason =\n      @\"IID token data stored in Keychain is corrupted or in an incompatible format.\";\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse\n                                                   data:(nullable NSData *)data {\n  return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:HTTPResponse data:data];\n}\n\n+ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode {\n  if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) {\n    return NO;\n  }\n\n  return [(FIRInstallationsHTTPError *)error HTTPResponse].statusCode == HTTPCode;\n}\n\n+ (NSError *)JSONSerializationError:(NSError *)error {\n  NSString *failureReason = [NSString stringWithFormat:@\"Failed to serialize JSON data.\"];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName {\n  NSString *failureReason = [NSString\n      stringWithFormat:@\"A required response field with name %@ is missing\", missingFieldName];\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:failureReason\n                          underlyingError:nil];\n}\n\n+ (NSError *)networkErrorWithError:(NSError *)error {\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeServerUnreachable\n                            failureReason:@\"Network connection error.\"\n                          underlyingError:error];\n}\n\n+ (NSError *)backoffIntervalWaitError {\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeServerUnreachable\n                            failureReason:@\"Too many server requests.\"\n                          underlyingError:nil];\n}\n\n+ (NSError *)publicDomainErrorWithError:(NSError *)error {\n  if ([error.domain isEqualToString:kFirebaseInstallationsErrorDomain]) {\n    return error;\n  }\n\n  return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                            failureReason:nil\n                          underlyingError:error];\n}\n\n+ (NSError *)installationsErrorWithCode:(FIRInstallationsErrorCode)code\n                          failureReason:(nullable NSString *)failureReason\n                        underlyingError:(nullable NSError *)underlyingError {\n  NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];\n  userInfo[NSUnderlyingErrorKey] = underlyingError;\n  userInfo[NSLocalizedFailureReasonErrorKey] =\n      failureReason\n          ?: [NSString\n                 stringWithFormat:@\"Underlying error: %@\", underlyingError.localizedDescription];\n\n  return [NSError errorWithDomain:kFirebaseInstallationsErrorDomain code:code userInfo:userInfo];\n}\n\n+ (FBLPromise *)rejectedPromiseWithError:(NSError *)error {\n  FBLPromise *rejectedPromise = [FBLPromise pendingPromise];\n  [rejectedPromise reject:error];\n  return rejectedPromise;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Represents an error caused by an unexpected API response. */\n@interface FIRInstallationsHTTPError : NSError\n\n@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse;\n@property(nonatomic, readonly, nonnull) NSData *data;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse data:(nullable NSData *)data;\n\n@end\n\nNS_ASSUME_NONNULL_END\n\ntypedef NS_ENUM(NSInteger, FIRInstallationsHTTPCodes) {\n  FIRInstallationsHTTPCodesTooManyRequests = 429,\n  FIRInstallationsHTTPCodesServerInternalError = 500,\n};\n\n/** Possible response HTTP codes for `CreateInstallation` API request. */\ntypedef NS_ENUM(NSInteger, FIRInstallationsRegistrationHTTPCode) {\n  FIRInstallationsRegistrationHTTPCodeSuccess = 201,\n  FIRInstallationsRegistrationHTTPCodeInvalidArgument = 400,\n  FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch = 403,\n  FIRInstallationsRegistrationHTTPCodeProjectNotFound = 404,\n  FIRInstallationsRegistrationHTTPCodeTooManyRequests = 429,\n  FIRInstallationsRegistrationHTTPCodeServerInternalError = 500\n};\n\ntypedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenHTTPCode) {\n  FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication = 401,\n  FIRInstallationsAuthTokenHTTPCodeFIDNotFound = 404,\n};\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h\"\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n\n@implementation FIRInstallationsHTTPError\n\n- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse\n                                data:(nullable NSData *)data {\n  NSDictionary *userInfo = [FIRInstallationsHTTPError userInfoWithHTTPResponse:HTTPResponse\n                                                                          data:data];\n  self = [super\n      initWithDomain:kFirebaseInstallationsErrorDomain\n                code:[FIRInstallationsHTTPError errorCodeWithHTTPCode:HTTPResponse.statusCode]\n            userInfo:userInfo];\n  if (self) {\n    _HTTPResponse = HTTPResponse;\n    _data = data;\n  }\n  return self;\n}\n\n+ (FIRInstallationsErrorCode)errorCodeWithHTTPCode:(NSInteger)HTTPCode {\n  return FIRInstallationsErrorCodeUnknown;\n}\n\n+ (NSDictionary *)userInfoWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse\n                                      data:(nullable NSData *)data {\n  NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];\n  NSString *failureReason =\n      [NSString stringWithFormat:@\"The server responded with an error: \\n - URL: %@ \\n - HTTP \"\n                                 @\"status code: %ld \\n - Response body: %@\",\n                                 HTTPResponse.URL, (long)HTTPResponse.statusCode, responseString];\n  return @{NSLocalizedFailureReasonErrorKey : failureReason};\n}\n\n#pragma mark - NSCopying\n\n- (id)copyWithZone:(NSZone *)zone {\n  return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:self.HTTPResponse data:self.data];\n}\n\n#pragma mark - NSSecureCoding\n\n- (nullable instancetype)initWithCoder:(NSCoder *)coder {\n  NSHTTPURLResponse *HTTPResponse = [coder decodeObjectOfClass:[NSHTTPURLResponse class]\n                                                        forKey:@\"HTTPResponse\"];\n  if (!HTTPResponse) {\n    return nil;\n  }\n  NSData *data = [coder decodeObjectOfClass:[NSData class] forKey:@\"data\"];\n\n  return [self initWithHTTPResponse:HTTPResponse data:data];\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder {\n  [coder encodeObject:self.HTTPResponse forKey:@\"HTTPResponse\"];\n  [coder encodeObject:self.data forKey:@\"data\"];\n}\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"FirebaseCore/Sources/Private/FirebaseCoreInternal.h\"\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsItem.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nstatic const NSUInteger kExpectedAPIKeyLength = 39;\n\n@protocol FIRInstallationsInstanceProvider <FIRLibrary>\n@end\n\n@interface FIRInstallations () <FIRInstallationsInstanceProvider>\n@property(nonatomic, readonly) FIROptions *appOptions;\n@property(nonatomic, readonly) NSString *appName;\n\n@property(nonatomic, readonly) FIRInstallationsIDController *installationsIDController;\n\n@end\n\n@implementation FIRInstallations\n\n#pragma mark - Firebase component\n\n+ (void)load {\n  [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self withName:@\"fire-install\"];\n}\n\n+ (nonnull NSArray<FIRComponent *> *)componentsToRegister {\n  FIRComponentCreationBlock creationBlock =\n      ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {\n    *isCacheable = YES;\n    FIRInstallations *installations = [[FIRInstallations alloc] initWithApp:container.app];\n    return installations;\n  };\n\n  FIRComponent *installationsProvider =\n      [FIRComponent componentWithProtocol:@protocol(FIRInstallationsInstanceProvider)\n                      instantiationTiming:FIRInstantiationTimingAlwaysEager\n                             dependencies:@[]\n                            creationBlock:creationBlock];\n  return @[ installationsProvider ];\n}\n\n- (instancetype)initWithApp:(FIRApp *)app {\n  return [self initWitAppOptions:app.options appName:app.name];\n}\n\n- (instancetype)initWitAppOptions:(FIROptions *)appOptions appName:(NSString *)appName {\n  FIRInstallationsIDController *IDController =\n      [[FIRInstallationsIDController alloc] initWithGoogleAppID:appOptions.googleAppID\n                                                        appName:appName\n                                                         APIKey:appOptions.APIKey\n                                                      projectID:appOptions.projectID\n                                                    GCMSenderID:appOptions.GCMSenderID\n                                                    accessGroup:appOptions.appGroupID];\n\n  // `prefetchAuthToken` is disabled due to b/156746574.\n  return [self initWithAppOptions:appOptions\n                          appName:appName\n        installationsIDController:IDController\n                prefetchAuthToken:NO];\n}\n\n/// The initializer is supposed to be used by tests to inject `installationsStore`.\n- (instancetype)initWithAppOptions:(FIROptions *)appOptions\n                           appName:(NSString *)appName\n         installationsIDController:(FIRInstallationsIDController *)installationsIDController\n                 prefetchAuthToken:(BOOL)prefetchAuthToken {\n  self = [super init];\n  if (self) {\n    [[self class] validateAppOptions:appOptions appName:appName];\n    [[self class] assertCompatibleIIDVersion];\n\n    _appOptions = [appOptions copy];\n    _appName = [appName copy];\n    _installationsIDController = installationsIDController;\n\n    // Pre-fetch auth token.\n    if (prefetchAuthToken) {\n      [self authTokenWithCompletion:^(FIRInstallationsAuthTokenResult *_Nullable tokenResult,\n                                      NSError *_Nullable error){\n      }];\n    }\n  }\n  return self;\n}\n\n+ (void)validateAppOptions:(FIROptions *)appOptions appName:(NSString *)appName {\n  NSMutableArray *missingFields = [NSMutableArray array];\n  if (appName.length < 1) {\n    [missingFields addObject:@\"`FirebaseApp.name`\"];\n  }\n  if (appOptions.APIKey.length < 1) {\n    [missingFields addObject:@\"`FirebaseOptions.APIKey`\"];\n  }\n  if (appOptions.googleAppID.length < 1) {\n    [missingFields addObject:@\"`FirebaseOptions.googleAppID`\"];\n  }\n\n  if (appOptions.projectID.length < 1) {\n    [missingFields addObject:@\"`FirebaseOptions.projectID`\"];\n  }\n\n  if (missingFields.count > 0) {\n    [NSException\n         raise:kFirebaseInstallationsErrorDomain\n        format:\n            @\"%@[%@] Could not configure Firebase Installations due to invalid FirebaseApp \"\n            @\"options. The following parameters are nil or empty: %@. If you use \"\n            @\"GoogleServices-Info.plist please download the most recent version from the Firebase \"\n            @\"Console. If you configure Firebase in code, please make sure you specify all \"\n            @\"required parameters.\",\n            kFIRLoggerInstallations, kFIRInstallationsMessageCodeInvalidFirebaseAppOptions,\n            [missingFields componentsJoinedByString:@\", \"]];\n  }\n\n  [self validateAPIKey:appOptions.APIKey];\n}\n\n+ (void)validateAPIKey:(nullable NSString *)APIKey {\n  NSMutableArray<NSString *> *validationIssues = [[NSMutableArray alloc] init];\n\n  if (APIKey.length != kExpectedAPIKeyLength) {\n    [validationIssues addObject:[NSString stringWithFormat:@\"API Key length must be %lu characters\",\n                                                           (unsigned long)kExpectedAPIKeyLength]];\n  }\n\n  if (![[APIKey substringToIndex:1] isEqualToString:@\"A\"]) {\n    [validationIssues addObject:@\"API Key must start with `A`\"];\n  }\n\n  NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];\n  [allowedCharacters\n      formUnionWithCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@\"-_\"]];\n\n  NSCharacterSet *characters = [NSCharacterSet characterSetWithCharactersInString:APIKey];\n  if (![allowedCharacters isSupersetOfSet:characters]) {\n    [validationIssues addObject:@\"API Key must contain only base64 url-safe characters characters\"];\n  }\n\n  if (validationIssues.count > 0) {\n    [NSException\n         raise:kFirebaseInstallationsErrorDomain\n        format:\n            @\"%@[%@] Could not configure Firebase Installations due to invalid FirebaseApp \"\n            @\"options. `FirebaseOptions.APIKey` doesn't match the expected format: %@. If you use \"\n            @\"GoogleServices-Info.plist please download the most recent version from the Firebase \"\n            @\"Console. If you configure Firebase in code, please make sure you specify all \"\n            @\"required parameters.\",\n            kFIRLoggerInstallations, kFIRInstallationsMessageCodeInvalidFirebaseAppOptions,\n            [validationIssues componentsJoinedByString:@\", \"]];\n  }\n}\n\n#pragma mark - Public\n\n+ (FIRInstallations *)installations {\n  FIRApp *defaultApp = [FIRApp defaultApp];\n  if (!defaultApp) {\n    [NSException raise:kFirebaseInstallationsErrorDomain\n                format:@\"The default FirebaseApp instance must be configured before the default\"\n                       @\"FirebaseApp instance can be initialized. One way to ensure this is to \"\n                       @\"call `FirebaseApp.configure()` in the App  Delegate's \"\n                       @\"`application(_:didFinishLaunchingWithOptions:)` \"\n                       @\"(or the `@main` struct's initializer in SwiftUI).\"];\n  }\n\n  return [self installationsWithApp:defaultApp];\n}\n\n+ (FIRInstallations *)installationsWithApp:(FIRApp *)app {\n  id<FIRInstallationsInstanceProvider> installations =\n      FIR_COMPONENT(FIRInstallationsInstanceProvider, app.container);\n  return (FIRInstallations *)installations;\n}\n\n- (void)installationIDWithCompletion:(FIRInstallationsIDHandler)completion {\n  [self.installationsIDController getInstallationItem]\n      .then(^id(FIRInstallationsItem *installation) {\n        completion(installation.firebaseInstallationID, nil);\n        return nil;\n      })\n      .catch(^(NSError *error) {\n        completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]);\n      });\n}\n\n- (void)authTokenWithCompletion:(FIRInstallationsTokenHandler)completion {\n  [self authTokenForcingRefresh:NO completion:completion];\n}\n\n- (void)authTokenForcingRefresh:(BOOL)forceRefresh\n                     completion:(FIRInstallationsTokenHandler)completion {\n  [self.installationsIDController getAuthTokenForcingRefresh:forceRefresh]\n      .then(^FIRInstallationsAuthTokenResult *(FIRInstallationsItem *installation) {\n        FIRInstallationsAuthTokenResult *result = [[FIRInstallationsAuthTokenResult alloc]\n             initWithToken:installation.authToken.token\n            expirationDate:installation.authToken.expirationDate];\n        return result;\n      })\n      .then(^id(FIRInstallationsAuthTokenResult *token) {\n        completion(token, nil);\n        return nil;\n      })\n      .catch(^void(NSError *error) {\n        completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]);\n      });\n}\n\n- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion {\n  [self.installationsIDController deleteInstallation]\n      .then(^id(id result) {\n        completion(nil);\n        return nil;\n      })\n      .catch(^void(NSError *error) {\n        completion([FIRInstallationsErrorUtil publicDomainErrorWithError:error]);\n      });\n}\n\n#pragma mark - IID version compatibility\n\n+ (void)assertCompatibleIIDVersion {\n  // We use this flag to disable IID compatibility exception for unit tests.\n#ifdef FIR_INSTALLATIONS_ALLOWS_INCOMPATIBLE_IID_VERSION\n  return;\n#else\n  if (![self isIIDVersionCompatible]) {\n    [NSException\n         raise:kFirebaseInstallationsErrorDomain\n        format:@\"Firebase Instance ID is not compatible with Firebase 8.x+. Please remove the \"\n               @\"dependency from the app. See the documentation at \"\n               @\"https://firebase.google.com/docs/cloud-messaging/ios/\"\n               @\"client#fetching-the-current-registration-token.\"];\n  }\n#endif\n}\n\n+ (BOOL)isIIDVersionCompatible {\n  Class IIDClass = NSClassFromString(@\"FIRInstanceID\");\n  if (IIDClass == nil) {\n    // It is OK if there is no IID at all.\n    return YES;\n  }\n  // We expect a compatible version having the method `+[FIRInstanceID usesFIS]` defined.\n  BOOL isCompatibleVersion = [IIDClass respondsToSelector:NSSelectorFromString(@\"usesFIS\")];\n  return isCompatibleVersion;\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h\"\n\n@implementation FIRInstallationsAuthTokenResult\n\n- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationDate {\n  self = [super init];\n  if (self) {\n    _authToken = [token copy];\n    _expirationDate = expirationDate;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRInstallationsAuthTokenResult (Internal)\n\n- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationTime;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h\"\n\n@class FIRInstallationsStoredItem;\n@class FIRInstallationsStoredAuthToken;\n@class FIRInstallationsStoredIIDCheckin;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The class represents the required installation ID and auth token data including possible states.\n * The data is stored to Keychain via `FIRInstallationsStoredItem` which has only the storage\n * relevant data and does not contain any logic. `FIRInstallationsItem` must be used on the logic\n * level (not `FIRInstallationsStoredItem`).\n */\n@interface FIRInstallationsItem : NSObject <NSCopying>\n\n/// A `FirebaseApp` identifier.\n@property(nonatomic, readonly) NSString *appID;\n/// A `FirebaseApp` name.\n@property(nonatomic, readonly) NSString *firebaseAppName;\n///  A stable identifier that uniquely identifies the app instance.\n@property(nonatomic, copy, nullable) NSString *firebaseInstallationID;\n/// The `refreshToken` is used to authorize the auth token requests.\n@property(nonatomic, copy, nullable) NSString *refreshToken;\n\n@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken;\n@property(nonatomic, assign) FIRInstallationsStatus registrationStatus;\n\n/// Instance ID default token imported from IID store as a part of IID migration.\n@property(nonatomic, nullable) NSString *IIDDefaultToken;\n\n- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName;\n\n/**\n * Populates `FIRInstallationsItem` properties with data from `FIRInstallationsStoredItem`.\n * @param item An instance of `FIRInstallationsStoredItem` to get data from.\n */\n- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item;\n\n/**\n * Creates a stored item with data from the object.\n * @return Returns a `FIRInstallationsStoredItem` instance with the data from the object.\n */\n- (FIRInstallationsStoredItem *)storedItem;\n\n/**\n * The installation identifier.\n * @return Returns a string uniquely identifying the installation.\n */\n- (NSString *)identifier;\n\n/** Validates if all the required item fields are populated and values don't explicitly conflict\n * with each other.\n *  @param outError A reference to be populated with an error containing validation failure details.\n *  @return `YES` if the item it valid, `NO` otherwise.\n */\n- (BOOL)isValid:(NSError *_Nullable *)outError;\n\n/**\n * The installation identifier.\n * @param appID A `FirebaseApp` identifier.\n * @param appName A `FirebaseApp` name.\n * @return Returns a string uniquely identifying the installation.\n */\n+ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName;\n\n/**\n * Generate a new Firebase Installation Identifier.\n * @return Returns a 22 characters long globally unique string created based on UUID.\n */\n+ (NSString *)generateFID;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsItem.h\"\n\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n\n@implementation FIRInstallationsItem\n\n- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName {\n  self = [super init];\n  if (self) {\n    _appID = [appID copy];\n    _firebaseAppName = [firebaseAppName copy];\n  }\n  return self;\n}\n\n- (nonnull id)copyWithZone:(nullable NSZone *)zone {\n  FIRInstallationsItem *clone = [[FIRInstallationsItem alloc] initWithAppID:self.appID\n                                                            firebaseAppName:self.firebaseAppName];\n  clone.firebaseInstallationID = [self.firebaseInstallationID copy];\n  clone.refreshToken = [self.refreshToken copy];\n  clone.authToken = [self.authToken copy];\n  clone.registrationStatus = self.registrationStatus;\n  clone.IIDDefaultToken = [self.IIDDefaultToken copy];\n\n  return clone;\n}\n\n- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item {\n  self.firebaseInstallationID = item.firebaseInstallationID;\n  self.refreshToken = item.refreshToken;\n  self.authToken = item.authToken;\n  self.registrationStatus = item.registrationStatus;\n  self.IIDDefaultToken = item.IIDDefaultToken;\n}\n\n- (FIRInstallationsStoredItem *)storedItem {\n  FIRInstallationsStoredItem *storedItem = [[FIRInstallationsStoredItem alloc] init];\n  storedItem.firebaseInstallationID = self.firebaseInstallationID;\n  storedItem.refreshToken = self.refreshToken;\n  storedItem.authToken = self.authToken;\n  storedItem.registrationStatus = self.registrationStatus;\n  storedItem.IIDDefaultToken = self.IIDDefaultToken;\n  return storedItem;\n}\n\n- (nonnull NSString *)identifier {\n  return [[self class] identifierWithAppID:self.appID appName:self.firebaseAppName];\n}\n\n- (BOOL)isValid:(NSError *_Nullable *)outError {\n  NSMutableArray<NSString *> *validationIssues = [NSMutableArray array];\n\n  if (self.appID.length == 0) {\n    [validationIssues addObject:@\"`appID` must not be empty\"];\n  }\n\n  if (self.firebaseAppName.length == 0) {\n    [validationIssues addObject:@\"`firebaseAppName` must not be empty\"];\n  }\n\n  if (self.firebaseInstallationID.length == 0) {\n    [validationIssues addObject:@\"`firebaseInstallationID` must not be empty\"];\n  }\n\n  switch (self.registrationStatus) {\n    case FIRInstallationStatusUnknown:\n      [validationIssues addObject:@\"invalid `registrationStatus`\"];\n      break;\n\n    case FIRInstallationStatusRegistered:\n      if (self.refreshToken == 0) {\n        [validationIssues addObject:@\"registered installation must have non-empty `refreshToken`\"];\n      }\n\n      if (self.authToken.token == 0) {\n        [validationIssues\n            addObject:@\"registered installation must have non-empty `authToken.token`\"];\n      }\n\n      if (self.authToken.expirationDate == nil) {\n        [validationIssues\n            addObject:@\"registered installation must have non-empty `authToken.expirationDate`\"];\n      }\n\n    case FIRInstallationStatusUnregistered:\n      break;\n  }\n\n  BOOL isValid = validationIssues.count == 0;\n\n  if (!isValid && outError) {\n    NSString *failureReason =\n        [NSString stringWithFormat:@\"FIRInstallationsItem validation errors: %@\",\n                                   [validationIssues componentsJoinedByString:@\", \"]];\n    *outError =\n        [FIRInstallationsErrorUtil installationsErrorWithCode:FIRInstallationsErrorCodeUnknown\n                                                failureReason:failureReason\n                                              underlyingError:nil];\n  }\n\n  return isValid;\n}\n\n+ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName {\n  return [appID stringByAppendingString:appName];\n}\n\n+ (NSString *)generateFID {\n  NSUUID *UUID = [NSUUID UUID];\n  uuid_t UUIDBytes;\n  [UUID getUUIDBytes:UUIDBytes];\n\n  NSUInteger UUIDLength = sizeof(uuid_t);\n  NSData *UUIDData = [NSData dataWithBytes:UUIDBytes length:UUIDLength];\n\n  uint8_t UUIDLast4Bits = UUIDBytes[UUIDLength - 1] & 0b00001111;\n\n  // FID first 4 bits must be `0111`. The last 4 UUID bits will be cut later to form a proper FID.\n  // To keep 16 random bytes we copy these last 4 UUID to the FID 1st byte after `0111` prefix.\n  uint8_t FIDPrefix = 0b01110000 | UUIDLast4Bits;\n  NSMutableData *FIDData = [NSMutableData dataWithBytes:&FIDPrefix length:1];\n\n  [FIDData appendData:UUIDData];\n  NSString *FIDString = [self base64URLEncodedStringWithData:FIDData];\n\n  // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5 bytes.\n  // Our generated ID has 16 bytes UUID + 1 byte prefix which after encoding with base64 will become\n  // 23 characters plus 1 character for \"=\" padding.\n\n  // Remove the 23rd character that was added because of the extra 4 bits at the\n  // end of our 17 byte data and the '=' padding.\n  return [FIDString substringWithRange:NSMakeRange(0, 22)];\n}\n\n+ (NSString *)base64URLEncodedStringWithData:(NSData *)data {\n  NSString *string = [data base64EncodedStringWithOptions:0];\n  string = [string stringByReplacingOccurrencesOfString:@\"/\" withString:@\"_\"];\n  string = [string stringByReplacingOccurrencesOfString:@\"+\" withString:@\"-\"];\n  return string;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseCore/Sources/Private/FirebaseCoreInternal.h\"\n\nextern FIRLoggerService kFIRLoggerInstallations;\n\n// FIRInstallationsAPIService.m\nextern NSString *const kFIRInstallationsMessageCodeSendAPIRequest;\nextern NSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError;\nextern NSString *const kFIRInstallationsMessageCodeAPIRequestResponse;\nextern NSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse;\nextern NSString *const kFIRInstallationsMessageCodeParsingAPIResponse;\nextern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed;\nextern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed;\nextern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed;\nextern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed;\n\n// FIRInstallationsIDController.m\nextern NSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated;\nextern NSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated;\nextern NSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated;\nextern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration;\nextern NSString *const kFIRInstallationsMessageCodeCorruptedStoredInstallation;\n\n// FIRInstallationsStoredItem.m\nextern NSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch;\n\n// FIRInstallationsStoredAuthToken.m\nextern NSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch;\n\n// FIRInstallationsStoredIIDCheckin.m\nextern NSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch;\nextern NSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode;\n\n// FIRInstallations.m\nextern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions;\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n\nFIRLoggerService kFIRLoggerInstallations = @\"[Firebase/Installations]\";\n\n// FIRInstallationsAPIService.m\nNSString *const kFIRInstallationsMessageCodeSendAPIRequest = @\"I-FIS001001\";\nNSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError = @\"I-FIS001002\";\nNSString *const kFIRInstallationsMessageCodeAPIRequestResponse = @\"I-FIS001003\";\nNSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse = @\"I-FIS001004\";\nNSString *const kFIRInstallationsMessageCodeParsingAPIResponse = @\"I-FIS001005\";\nNSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed = @\"I-FIS001006\";\nNSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed = @\"I-FIS001007\";\nNSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed = @\"I-FIS001008\";\nNSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed = @\"I-FIS001009\";\n\n// FIRInstallationsIDController.m\nNSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated = @\"I-FIS002000\";\nNSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated = @\"I-FIS002001\";\nNSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated = @\"I-FIS002002\";\nNSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration = @\"I-FIS002003\";\nNSString *const kFIRInstallationsMessageCodeCorruptedStoredInstallation = @\"I-FIS002004\";\n\n// FIRInstallationsStoredItem.m\nNSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch = @\"I-FIS003000\";\n\n// FIRInstallationsStoredAuthToken.m\nNSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch = @\"I-FIS004000\";\n\n// FIRInstallationsStoredIIDCheckin.m\nNSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch = @\"I-FIS007000\";\nNSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode = @\"I-FIS007001\";\n\n// FIRInstallations.m\nNSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions = @\"I-FIS008000\";\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The class encapsulates a port of a piece FirebaseInstanceID logic required to migrate IID. */\n@interface FIRInstallationsIIDStore : NSObject\n\n/**\n * Retrieves existing IID if present.\n * @return Returns a promise that is resolved with IID string if IID has been found or rejected with\n * an error otherwise.\n */\n- (FBLPromise<NSString *> *)existingIID;\n\n/**\n * Deletes existing IID if present.\n * @return Returns a promise that is resolved with `[NSNull null]` if the IID was successfully.\n * deleted or was not found. The promise is rejected otherwise.\n */\n- (FBLPromise<NSNull *> *)deleteExistingIID;\n\n#if TARGET_OS_OSX\n/// If not `nil`, then only this keychain will be used to save and read data (see\n/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests.\n@property(nonatomic, nullable) SecKeychainRef keychainRef;\n#endif  // TARGET_OSX\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import <CommonCrypto/CommonDigest.h>\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n\nstatic NSString *const kFIRInstallationsIIDKeyPairPublicTagPrefix =\n    @\"com.google.iid.keypair.public-\";\nstatic NSString *const kFIRInstallationsIIDKeyPairPrivateTagPrefix =\n    @\"com.google.iid.keypair.private-\";\nstatic NSString *const kFIRInstallationsIIDCreationTimePlistKey = @\"|S|cre\";\n\n@implementation FIRInstallationsIIDStore\n\n- (FBLPromise<NSString *> *)existingIID {\n  return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)\n                          do:^id _Nullable {\n                            if (![self hasPlistIIDFlag]) {\n                              return nil;\n                            }\n\n                            NSData *IIDPublicKeyData = [self IIDPublicKeyData];\n                            return [self IIDWithPublicKeyData:IIDPublicKeyData];\n                          }]\n      .validate(^BOOL(NSString *_Nullable IID) {\n        return IID.length > 0;\n      });\n}\n\n- (FBLPromise<NSNull *> *)deleteExistingIID {\n  return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)\n                          do:^id _Nullable {\n                            NSError *error;\n                            if (![self deleteIIDFlagFromPlist:&error]) {\n                              return error;\n                            }\n\n                            if (![self deleteIID:&error]) {\n                              return error;\n                            }\n\n                            return [NSNull null];\n                          }];\n}\n\n#pragma mark - IID decoding\n\n- (NSString *)IIDWithPublicKeyData:(NSData *)publicKeyData {\n  NSData *publicKeySHA1 = [self sha1WithData:publicKeyData];\n\n  const uint8_t *bytes = publicKeySHA1.bytes;\n  NSMutableData *identityData = [NSMutableData dataWithData:publicKeySHA1];\n\n  uint8_t b0 = bytes[0];\n  // Take the first byte and make the initial four 7 by initially making the initial 4 bits 0\n  // and then adding 0x70 to it.\n  b0 = 0x70 + (0xF & b0);\n  // failsafe should give you back b0 itself\n  b0 = (b0 & 0xFF);\n  [identityData replaceBytesInRange:NSMakeRange(0, 1) withBytes:&b0];\n  NSData *data = [identityData subdataWithRange:NSMakeRange(0, 8 * sizeof(Byte))];\n  return [self base64URLEncodedStringWithData:data];\n}\n\n/** FirebaseInstallations SDK uses the SHA1 hash for backwards compatibility with the legacy\n * FirebaseInstanceID SDK. The SHA1 hash is used to access Instance IDs stored on the device and not\n * for any security-relevant process. This is a one-time step that allows migration of old client\n * identifiers. Cryptographic security is not needed here, so potential hash collisions are not a\n * problem.\n */\n- (NSData *)sha1WithData:(NSData *)data {\n  unsigned char output[CC_SHA1_DIGEST_LENGTH];\n  unsigned int length = (unsigned int)[data length];\n\n  CC_SHA1(data.bytes, length, output);\n  return [NSData dataWithBytes:output length:CC_SHA1_DIGEST_LENGTH];\n}\n\n- (NSString *)base64URLEncodedStringWithData:(NSData *)data {\n  NSString *string = [data base64EncodedStringWithOptions:0];\n  string = [string stringByReplacingOccurrencesOfString:@\"/\" withString:@\"_\"];\n  string = [string stringByReplacingOccurrencesOfString:@\"+\" withString:@\"-\"];\n  string = [string stringByReplacingOccurrencesOfString:@\"=\" withString:@\"\"];\n  return string;\n}\n\n#pragma mark - Keychain\n\n- (NSData *)IIDPublicKeyData {\n  NSString *tag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix];\n  NSDictionary *query = [self keyPairQueryWithTag:tag returnData:YES];\n\n  CFTypeRef keyRef = NULL;\n  OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&keyRef);\n\n  if (status != noErr) {\n    if (keyRef) {\n      CFRelease(keyRef);\n    }\n    return nil;\n  }\n\n  return (__bridge NSData *)keyRef;\n}\n\n- (BOOL)deleteIID:(NSError **)outError {\n  if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix\n                                      error:outError]) {\n    return NO;\n  }\n\n  if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPrivateTagPrefix\n                                      error:outError]) {\n    return NO;\n  }\n\n  return YES;\n}\n\n- (BOOL)deleteKeychainKeyWithTagPrefix:(NSString *)tagPrefix error:(NSError **)outError {\n  NSString *keyTag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix];\n  NSDictionary *keyQuery = [self keyPairQueryWithTag:keyTag returnData:NO];\n\n  OSStatus status = SecItemDelete((__bridge CFDictionaryRef)keyQuery);\n\n  // When item is not found, it should NOT be considered as an error. The operation should\n  // continue.\n  if (status != noErr && status != errSecItemNotFound) {\n    FIRInstallationsItemSetErrorToPointer(\n        [FIRInstallationsErrorUtil keychainErrorWithFunction:@\"SecItemDelete\" status:status],\n        outError);\n    return NO;\n  }\n\n  return YES;\n}\n\n- (NSDictionary *)keyPairQueryWithTag:(NSString *)tag returnData:(BOOL)shouldReturnData {\n  NSMutableDictionary *query = [NSMutableDictionary dictionary];\n  NSData *tagData = [tag dataUsingEncoding:NSUTF8StringEncoding];\n\n  query[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;\n  query[(__bridge id)kSecAttrApplicationTag] = tagData;\n  query[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA;\n  if (shouldReturnData) {\n    query[(__bridge id)kSecReturnData] = @(YES);\n  }\n\n#if TARGET_OS_OSX\n  if (self.keychainRef) {\n    query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ];\n  }\n#endif  // TARGET_OSX\n\n  return query;\n}\n\n- (NSString *)keychainKeyTagWithPrefix:(NSString *)prefix {\n  NSString *mainAppBundleID = [[NSBundle mainBundle] bundleIdentifier];\n  if (mainAppBundleID.length == 0) {\n    return nil;\n  }\n  return [NSString stringWithFormat:@\"%@%@\", prefix, mainAppBundleID];\n}\n\n- (NSString *)mainbundleIdentifier {\n  NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];\n  if (!bundleIdentifier.length) {\n    return nil;\n  }\n  return bundleIdentifier;\n}\n\n#pragma mark - Plist\n\n- (BOOL)deleteIIDFlagFromPlist:(NSError **)outError {\n  NSString *path = [self plistPath];\n  if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {\n    return YES;\n  }\n\n  NSMutableDictionary *plistContent = [[NSMutableDictionary alloc] initWithContentsOfFile:path];\n  plistContent[kFIRInstallationsIIDCreationTimePlistKey] = nil;\n\n  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {\n    return [plistContent writeToURL:[NSURL fileURLWithPath:path] error:outError];\n  }\n\n  return [plistContent writeToFile:path atomically:YES];\n}\n\n- (BOOL)hasPlistIIDFlag {\n  NSString *path = [self plistPath];\n  if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {\n    return NO;\n  }\n\n  NSDictionary *plistContent = [[NSDictionary alloc] initWithContentsOfFile:path];\n  return plistContent[kFIRInstallationsIIDCreationTimePlistKey] != nil;\n}\n\n- (NSString *)plistPath {\n  NSString *plistNameWithExtension = @\"com.google.iid-keypair.plist\";\n  NSString *_subDirectoryName = @\"Google/FirebaseInstanceID\";\n\n  NSArray *directoryPaths =\n      NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES);\n  NSArray *components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ];\n\n  return [NSString pathWithComponents:components];\n}\n\n- (NSSearchPathDirectory)supportedDirectory {\n#if TARGET_OS_TV\n  return NSCachesDirectory;\n#else\n  return NSApplicationSupportDirectory;\n#endif\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The class reads a default IID token from IID store if available.\n */\n@interface FIRInstallationsIIDTokenStore : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID;\n\n- (FBLPromise<NSString *> *)existingIIDDefaultToken;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import <GoogleUtilities/GULKeychainUtils.h>\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n\nstatic NSString *const kFIRInstallationsIIDTokenKeychainId = @\"com.google.iid-tokens\";\n\n@interface FIRInstallationsIIDTokenInfo : NSObject <NSSecureCoding>\n@property(nonatomic, nullable, copy) NSString *token;\n@end\n\n@implementation FIRInstallationsIIDTokenInfo\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n- (void)encodeWithCoder:(nonnull NSCoder *)coder {\n}\n\n- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {\n  self = [super init];\n  if (self) {\n    _token = [coder decodeObjectOfClass:[NSString class] forKey:@\"token\"];\n  }\n  return self;\n}\n\n@end\n\n@interface FIRInstallationsIIDTokenStore ()\n@property(nonatomic, readonly) NSString *GCMSenderID;\n@end\n\n@implementation FIRInstallationsIIDTokenStore\n\n- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID {\n  self = [super init];\n  if (self) {\n    _GCMSenderID = GCMSenderID;\n  }\n  return self;\n}\n\n- (FBLPromise<NSString *> *)existingIIDDefaultToken {\n  return [[FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)\n                           do:^id _Nullable {\n                             return [self IIDDefaultTokenData];\n                           }] onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)\n                                 then:^id _Nullable(NSData *_Nullable keychainData) {\n                                   return [self IIDCheckinWithData:keychainData];\n                                 }];\n}\n\n- (FBLPromise<NSString *> *)IIDCheckinWithData:(NSData *)data {\n  FBLPromise<NSString *> *resultPromise = [FBLPromise pendingPromise];\n\n  NSError *archiverError;\n  NSKeyedUnarchiver *unarchiver;\n  if (@available(iOS 11.0, tvOS 11.0, macOS 10.13, *)) {\n    unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&archiverError];\n  } else {\n    @try {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n      unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];\n#pragma clang diagnostic pop\n    } @catch (NSException *exception) {\n      archiverError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception];\n    }\n  }\n\n  if (!unarchiver) {\n    NSError *error = archiverError ?: [FIRInstallationsErrorUtil corruptedIIDTokenData];\n    [resultPromise reject:error];\n    return resultPromise;\n  }\n\n  [unarchiver setClass:[FIRInstallationsIIDTokenInfo class] forClassName:@\"FIRInstanceIDTokenInfo\"];\n  FIRInstallationsIIDTokenInfo *IIDTokenInfo =\n      [unarchiver decodeObjectOfClass:[FIRInstallationsIIDTokenInfo class]\n                               forKey:NSKeyedArchiveRootObjectKey];\n\n  if (IIDTokenInfo.token.length < 1) {\n    [resultPromise reject:[FIRInstallationsErrorUtil corruptedIIDTokenData]];\n    return resultPromise;\n  }\n\n  [resultPromise fulfill:IIDTokenInfo.token];\n\n  return resultPromise;\n}\n\n- (FBLPromise<NSData *> *)IIDDefaultTokenData {\n  FBLPromise<NSData *> *resultPromise = [FBLPromise pendingPromise];\n\n  NSMutableDictionary *keychainQuery = [self IIDDefaultTokenDataKeychainQuery];\n  NSError *error;\n  NSData *data = [GULKeychainUtils getItemWithQuery:keychainQuery error:&error];\n\n  if (data) {\n    [resultPromise fulfill:data];\n    return resultPromise;\n  } else {\n    NSError *outError = error ?: [FIRInstallationsErrorUtil corruptedIIDTokenData];\n    [resultPromise reject:outError];\n    return resultPromise;\n  }\n}\n\n- (NSMutableDictionary *)IIDDefaultTokenDataKeychainQuery {\n  NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword};\n\n  NSMutableDictionary *finalQuery = [NSMutableDictionary dictionaryWithDictionary:query];\n  finalQuery[(__bridge NSString *)kSecAttrGeneric] = kFIRInstallationsIIDTokenKeychainId;\n\n  NSString *account = [self IIDAppIdentifier];\n  if ([account length]) {\n    finalQuery[(__bridge NSString *)kSecAttrAccount] = account;\n  }\n\n  finalQuery[(__bridge NSString *)kSecAttrService] =\n      [self serviceKeyForAuthorizedEntity:self.GCMSenderID scope:@\"*\"];\n  return finalQuery;\n}\n\n- (NSString *)IIDAppIdentifier {\n  return [[NSBundle mainBundle] bundleIdentifier] ?: @\"\";\n}\n\n- (NSString *)serviceKeyForAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {\n  return [NSString stringWithFormat:@\"%@:%@\", authorizedEntity, scope];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n@class FIRInstallationsItem;\n\nNS_ASSUME_NONNULL_BEGIN\n\nFOUNDATION_EXPORT NSString *const kFIRInstallationsUserAgentKey;\n\nFOUNDATION_EXPORT NSString *const kFIRInstallationsHeartbeatKey;\n\n/**\n * The class is responsible for interacting with HTTP REST API for Installations.\n */\n@interface FIRInstallationsAPIService : NSObject\n\n/**\n * The default initializer.\n * @param APIKey The Firebase project API key (see `FIROptions.APIKey`).\n * @param projectID The Firebase project ID (see `FIROptions.projectID`).\n */\n- (instancetype)initWithAPIKey:(NSString *)APIKey projectID:(NSString *)projectID;\n\n/**\n * Sends a request to register a new FID to get auth and refresh tokens.\n * @param installation The `FIRInstallationsItem` instance with the FID to register.\n * @return A promise that is resolved with a new `FIRInstallationsItem` instance with valid tokens.\n * It is rejected with an error in case of a failure.\n */\n- (FBLPromise<FIRInstallationsItem *> *)registerInstallation:(FIRInstallationsItem *)installation;\n\n- (FBLPromise<FIRInstallationsItem *> *)refreshAuthTokenForInstallation:\n    (FIRInstallationsItem *)installation;\n\n/**\n * Sends a request to delete the installation, related auth tokens and all related data from the\n * server.\n * @param installation The installation to delete.\n * @return Returns a promise that is resolved with the passed installation on successful deletion or\n * is rejected with an error otherwise.\n */\n- (FBLPromise<FIRInstallationsItem *> *)deleteInstallation:(FIRInstallationsItem *)installation;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"FirebaseCore/Sources/Private/FirebaseCoreInternal.h\"\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h\"\n\nNSString *const kFIRInstallationsAPIBaseURL = @\"https://firebaseinstallations.googleapis.com\";\nNSString *const kFIRInstallationsAPIKey = @\"X-Goog-Api-Key\";\nNSString *const kFIRInstallationsBundleId = @\"X-Ios-Bundle-Identifier\";\nNSString *const kFIRInstallationsIIDMigrationAuthHeader = @\"x-goog-fis-ios-iid-migration-auth\";\nNSString *const kFIRInstallationsHeartbeatKey = @\"X-firebase-client-log-type\";\nNSString *const kFIRInstallationsHeartbeatTag = @\"fire-installations\";\nNSString *const kFIRInstallationsUserAgentKey = @\"X-firebase-client\";\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRInstallationsURLSessionResponse : NSObject\n@property(nonatomic) NSHTTPURLResponse *HTTPResponse;\n@property(nonatomic) NSData *data;\n\n- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data;\n@end\n\n@implementation FIRInstallationsURLSessionResponse\n\n- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data {\n  self = [super init];\n  if (self) {\n    _HTTPResponse = response;\n    _data = data ?: [NSData data];\n  }\n  return self;\n}\n\n@end\n\n@interface FIRInstallationsAPIService ()\n@property(nonatomic, readonly) NSURLSession *URLSession;\n@property(nonatomic, readonly) NSString *APIKey;\n@property(nonatomic, readonly) NSString *projectID;\n@end\n\nNS_ASSUME_NONNULL_END\n\n@implementation FIRInstallationsAPIService\n\n- (instancetype)initWithAPIKey:(NSString *)APIKey projectID:(NSString *)projectID {\n  NSURLSession *URLSession = [NSURLSession\n      sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];\n  return [self initWithURLSession:URLSession APIKey:APIKey projectID:projectID];\n}\n\n/// The initializer for tests.\n- (instancetype)initWithURLSession:(NSURLSession *)URLSession\n                            APIKey:(NSString *)APIKey\n                         projectID:(NSString *)projectID {\n  self = [super init];\n  if (self) {\n    _URLSession = URLSession;\n    _APIKey = [APIKey copy];\n    _projectID = [projectID copy];\n  }\n  return self;\n}\n\n#pragma mark - Public\n\n- (FBLPromise<FIRInstallationsItem *> *)registerInstallation:(FIRInstallationsItem *)installation {\n  return [self validateInstallation:installation]\n      .then(^id _Nullable(FIRInstallationsItem *_Nullable validInstallation) {\n        return [self registerRequestWithInstallation:validInstallation];\n      })\n      .then(^id _Nullable(NSURLRequest *_Nullable request) {\n        return [self sendURLRequest:request];\n      })\n      .then(^id _Nullable(FIRInstallationsURLSessionResponse *response) {\n        return [self registeredInstallationWithInstallation:installation serverResponse:response];\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)refreshAuthTokenForInstallation:\n    (FIRInstallationsItem *)installation {\n  return [self authTokenRequestWithInstallation:installation]\n      .then(^id _Nullable(NSURLRequest *_Nullable request) {\n        return [self sendURLRequest:request];\n      })\n      .then(^FBLPromise<FIRInstallationsStoredAuthToken *> *(\n          FIRInstallationsURLSessionResponse *response) {\n        return [self authTokenWithServerResponse:response];\n      })\n      .then(^FIRInstallationsItem *(FIRInstallationsStoredAuthToken *authToken) {\n        FIRInstallationsItem *updatedInstallation = [installation copy];\n        updatedInstallation.authToken = authToken;\n        return updatedInstallation;\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)deleteInstallation:(FIRInstallationsItem *)installation {\n  return [self deleteInstallationRequestWithInstallation:installation]\n      .then(^id _Nullable(NSURLRequest *_Nullable request) {\n        return [self sendURLRequest:request];\n      })\n      .then(^id _Nullable(FIRInstallationsURLSessionResponse *_Nullable value) {\n        // Return the original installation on success.\n        return installation;\n      });\n}\n\n#pragma mark - Register Installation\n\n- (FBLPromise<NSURLRequest *> *)registerRequestWithInstallation:\n    (FIRInstallationsItem *)installation {\n  NSString *URLString = [NSString stringWithFormat:@\"%@/v1/projects/%@/installations/\",\n                                                   kFIRInstallationsAPIBaseURL, self.projectID];\n  NSURL *URL = [NSURL URLWithString:URLString];\n\n  NSDictionary *bodyDict = @{\n    // `firebaseInstallationID` is validated before but let's make sure it is not `nil` one more\n    // time to prevent a crash.\n    @\"fid\" : installation.firebaseInstallationID ?: @\"\",\n    @\"authVersion\" : @\"FIS_v2\",\n    @\"appId\" : installation.appID,\n    @\"sdkVersion\" : [self SDKVersion]\n  };\n\n  NSDictionary *headers;\n  if (installation.IIDDefaultToken) {\n    headers = @{kFIRInstallationsIIDMigrationAuthHeader : installation.IIDDefaultToken};\n  }\n\n  return [self requestWithURL:URL\n                   HTTPMethod:@\"POST\"\n                     bodyDict:bodyDict\n                 refreshToken:nil\n            additionalHeaders:headers];\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)\n    registeredInstallationWithInstallation:(FIRInstallationsItem *)installation\n                            serverResponse:(FIRInstallationsURLSessionResponse *)response {\n  return [FBLPromise do:^id {\n    FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse,\n                @\"Parsing server response for %@.\", response.HTTPResponse.URL);\n    NSError *error;\n    FIRInstallationsItem *registeredInstallation =\n        [installation registeredInstallationWithJSONData:response.data\n                                                    date:[NSDate date]\n                                                   error:&error];\n    if (registeredInstallation == nil) {\n      FIRLogDebug(kFIRLoggerInstallations,\n                  kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed,\n                  @\"Failed to parse FIRInstallationsItem: %@.\", error);\n      return error;\n    }\n\n    FIRLogDebug(kFIRLoggerInstallations,\n                kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed,\n                @\"FIRInstallationsItem parsed successfully.\");\n    return registeredInstallation;\n  }];\n}\n\n#pragma mark - Auth token\n\n- (FBLPromise<NSURLRequest *> *)authTokenRequestWithInstallation:\n    (FIRInstallationsItem *)installation {\n  NSString *URLString =\n      [NSString stringWithFormat:@\"%@/v1/projects/%@/installations/%@/authTokens:generate\",\n                                 kFIRInstallationsAPIBaseURL, self.projectID,\n                                 installation.firebaseInstallationID];\n  NSURL *URL = [NSURL URLWithString:URLString];\n\n  NSDictionary *bodyDict = @{@\"installation\" : @{@\"sdkVersion\" : [self SDKVersion]}};\n  return [self requestWithURL:URL\n                   HTTPMethod:@\"POST\"\n                     bodyDict:bodyDict\n                 refreshToken:installation.refreshToken];\n}\n\n- (FBLPromise<FIRInstallationsStoredAuthToken *> *)authTokenWithServerResponse:\n    (FIRInstallationsURLSessionResponse *)response {\n  return [FBLPromise do:^id {\n    FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse,\n                @\"Parsing server response for %@.\", response.HTTPResponse.URL);\n    NSError *error;\n    FIRInstallationsStoredAuthToken *token =\n        [FIRInstallationsItem authTokenWithGenerateTokenAPIJSONData:response.data\n                                                               date:[NSDate date]\n                                                              error:&error];\n    if (token == nil) {\n      FIRLogDebug(kFIRLoggerInstallations,\n                  kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed,\n                  @\"Failed to parse FIRInstallationsStoredAuthToken: %@.\", error);\n      return error;\n    }\n\n    FIRLogDebug(kFIRLoggerInstallations,\n                kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed,\n                @\"FIRInstallationsStoredAuthToken parsed successfully.\");\n    return token;\n  }];\n}\n\n#pragma mark - Delete Installation\n\n- (FBLPromise<NSURLRequest *> *)deleteInstallationRequestWithInstallation:\n    (FIRInstallationsItem *)installation {\n  NSString *URLString = [NSString stringWithFormat:@\"%@/v1/projects/%@/installations/%@/\",\n                                                   kFIRInstallationsAPIBaseURL, self.projectID,\n                                                   installation.firebaseInstallationID];\n  NSURL *URL = [NSURL URLWithString:URLString];\n\n  return [self requestWithURL:URL\n                   HTTPMethod:@\"DELETE\"\n                     bodyDict:@{}\n                 refreshToken:installation.refreshToken];\n}\n\n#pragma mark - URL Request\n- (FBLPromise<NSURLRequest *> *)requestWithURL:(NSURL *)requestURL\n                                    HTTPMethod:(NSString *)HTTPMethod\n                                      bodyDict:(NSDictionary *)bodyDict\n                                  refreshToken:(nullable NSString *)refreshToken {\n  return [self requestWithURL:requestURL\n                   HTTPMethod:HTTPMethod\n                     bodyDict:bodyDict\n                 refreshToken:refreshToken\n            additionalHeaders:nil];\n}\n\n- (FBLPromise<NSURLRequest *> *)requestWithURL:(NSURL *)requestURL\n                                    HTTPMethod:(NSString *)HTTPMethod\n                                      bodyDict:(NSDictionary *)bodyDict\n                                  refreshToken:(nullable NSString *)refreshToken\n                             additionalHeaders:(nullable NSDictionary<NSString *, NSString *> *)\n                                                   additionalHeaders {\n  return [FBLPromise\n      onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)\n           do:^id _Nullable {\n             __block NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];\n             request.HTTPMethod = HTTPMethod;\n             NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];\n             [request addValue:self.APIKey forHTTPHeaderField:kFIRInstallationsAPIKey];\n             [request addValue:bundleIdentifier forHTTPHeaderField:kFIRInstallationsBundleId];\n             [self setJSONHTTPBody:bodyDict forRequest:request];\n             if (refreshToken) {\n               NSString *authHeader = [NSString stringWithFormat:@\"FIS_v2 %@\", refreshToken];\n               [request setValue:authHeader forHTTPHeaderField:@\"Authorization\"];\n             }\n             // User agent Header.\n             [request setValue:[FIRApp firebaseUserAgent]\n                 forHTTPHeaderField:kFIRInstallationsUserAgentKey];\n             // Heartbeat Header.\n             [request setValue:@([FIRHeartbeatInfo\n                                     heartbeatCodeForTag:kFIRInstallationsHeartbeatTag])\n                                   .stringValue\n                 forHTTPHeaderField:kFIRInstallationsHeartbeatKey];\n             [additionalHeaders\n                 enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, NSString *_Nonnull obj,\n                                                     BOOL *_Nonnull stop) {\n                   [request setValue:obj forHTTPHeaderField:key];\n                 }];\n\n             return [request copy];\n           }];\n}\n\n- (FBLPromise<FIRInstallationsURLSessionResponse *> *)URLRequestPromise:(NSURLRequest *)request {\n  return [[FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n    FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeSendAPIRequest,\n                @\"Sending request: %@, body:%@, headers: %@.\", request,\n                [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],\n                request.allHTTPHeaderFields);\n    [[self.URLSession\n        dataTaskWithRequest:request\n          completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response,\n                              NSError *_Nullable error) {\n            if (error) {\n              FIRLogDebug(kFIRLoggerInstallations,\n                          kFIRInstallationsMessageCodeAPIRequestNetworkError,\n                          @\"Request failed: %@, error: %@.\", request, error);\n              reject(error);\n            } else {\n              FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeAPIRequestResponse,\n                          @\"Request response received: %@, error: %@, body: %@.\", request, error,\n                          [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);\n              fulfill([[FIRInstallationsURLSessionResponse alloc]\n                  initWithResponse:(NSHTTPURLResponse *)response\n                              data:data]);\n            }\n          }] resume];\n  }] then:^id _Nullable(FIRInstallationsURLSessionResponse *response) {\n    return [self validateHTTPResponseStatusCode:response];\n  }];\n}\n\n- (FBLPromise<FIRInstallationsURLSessionResponse *> *)validateHTTPResponseStatusCode:\n    (FIRInstallationsURLSessionResponse *)response {\n  NSInteger statusCode = response.HTTPResponse.statusCode;\n  return [FBLPromise do:^id _Nullable {\n    if (statusCode < 200 || statusCode >= 300) {\n      FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse,\n                  @\"Unexpected API response: %@, body: %@.\", response.HTTPResponse,\n                  [[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding]);\n      return [FIRInstallationsErrorUtil APIErrorWithHTTPResponse:response.HTTPResponse\n                                                            data:response.data];\n    }\n    return response;\n  }];\n}\n\n- (FBLPromise<FIRInstallationsURLSessionResponse *> *)sendURLRequest:(NSURLRequest *)request {\n  return [FBLPromise attempts:1\n      delay:1\n      condition:^BOOL(NSInteger remainingAttempts, NSError *_Nonnull error) {\n        return [FIRInstallationsErrorUtil isAPIError:error\n                                        withHTTPCode:FIRInstallationsHTTPCodesServerInternalError];\n      }\n      retry:^id _Nullable {\n        return [self URLRequestPromise:request];\n      }];\n}\n\n- (NSString *)SDKVersion {\n  return [NSString stringWithFormat:@\"i:%@\", FIRFirebaseVersion()];\n}\n\n#pragma mark - Validation\n\n- (FBLPromise<FIRInstallationsItem *> *)validateInstallation:(FIRInstallationsItem *)installation {\n  FBLPromise<FIRInstallationsItem *> *result = [FBLPromise pendingPromise];\n\n  NSError *validationError;\n  if ([installation isValid:&validationError]) {\n    [result fulfill:installation];\n  } else {\n    [result reject:validationError];\n  }\n  return result;\n}\n\n#pragma mark - JSON\n\n- (void)setJSONHTTPBody:(NSDictionary<NSString *, id> *)body\n             forRequest:(NSMutableURLRequest *)request {\n  [request setValue:@\"application/json\" forHTTPHeaderField:@\"Content-Type\"];\n\n  NSError *error;\n  NSData *JSONData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];\n  if (JSONData == nil) {\n    // TODO: Log or return an error.\n  }\n  request.HTTPBody = JSONData;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsItem.h\"\n\n@class FIRInstallationsStoredAuthToken;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FIRInstallationsItem (RegisterInstallationAPI)\n\n/**\n * Parses and validates the Register Installation API response and returns a corresponding\n * `FIRInstallationsItem` instance on success.\n * @param JSONData The data with JSON encoded API response.\n * @param date The installation auth token expiration date will be calculated as `date` +\n * `response.authToken.expiresIn`. For most of the cases `[NSDate date]` should be passed there. A\n * different value may be passed e.g. for unit tests.\n * @param outError A pointer to assign a specific `NSError` instance in case of failure. No error is\n * assigned in case of success.\n * @return Returns a new `FIRInstallationsItem` instance in the success case or `nil` otherwise.\n */\n- (nullable FIRInstallationsItem *)registeredInstallationWithJSONData:(NSData *)JSONData\n                                                                 date:(NSDate *)date\n                                                                error:\n                                                                    (NSError *_Nullable *)outError;\n\n+ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data\n                                                                               date:(NSDate *)date\n                                                                              error:(NSError **)\n                                                                                        outError;\n\n+ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict:\n                                                  (NSDictionary<NSString *, id> *)dict\n                                                               date:(NSDate *)date\n                                                              error:(NSError **)outError;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n\n@implementation FIRInstallationsItem (RegisterInstallationAPI)\n\n- (nullable FIRInstallationsItem *)\n    registeredInstallationWithJSONData:(NSData *)data\n                                  date:(NSDate *)date\n                                 error:(NSError *__autoreleasing _Nullable *_Nullable)outError {\n  NSDictionary *responseJSON = [FIRInstallationsItem dictionaryFromJSONData:data error:outError];\n  if (!responseJSON) {\n    return nil;\n  }\n\n  NSString *refreshToken = [FIRInstallationsItem validStringOrNilForKey:@\"refreshToken\"\n                                                               fromDict:responseJSON];\n  if (refreshToken == nil) {\n    FIRInstallationsItemSetErrorToPointer(\n        [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@\"refreshToken\"],\n        outError);\n    return nil;\n  }\n\n  NSDictionary *authTokenDict = responseJSON[@\"authToken\"];\n  if (![authTokenDict isKindOfClass:[NSDictionary class]]) {\n    FIRInstallationsItemSetErrorToPointer(\n        [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@\"authToken\"],\n        outError);\n    return nil;\n  }\n\n  FIRInstallationsStoredAuthToken *authToken =\n      [FIRInstallationsItem authTokenWithJSONDict:authTokenDict date:date error:outError];\n  if (authToken == nil) {\n    return nil;\n  }\n\n  FIRInstallationsItem *installation =\n      [[FIRInstallationsItem alloc] initWithAppID:self.appID firebaseAppName:self.firebaseAppName];\n  NSString *installationID = [FIRInstallationsItem validStringOrNilForKey:@\"fid\"\n                                                                 fromDict:responseJSON];\n  installation.firebaseInstallationID = installationID ?: self.firebaseInstallationID;\n  installation.refreshToken = refreshToken;\n  installation.authToken = authToken;\n  installation.registrationStatus = FIRInstallationStatusRegistered;\n\n  return installation;\n}\n\n#pragma mark - Auth token\n\n+ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data\n                                                                               date:(NSDate *)date\n                                                                              error:(NSError **)\n                                                                                        outError {\n  NSDictionary *dict = [self dictionaryFromJSONData:data error:outError];\n  if (!dict) {\n    return nil;\n  }\n\n  return [self authTokenWithJSONDict:dict date:date error:outError];\n}\n\n+ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict:\n                                                  (NSDictionary<NSString *, id> *)dict\n                                                               date:(NSDate *)date\n                                                              error:(NSError **)outError {\n  NSString *token = [self validStringOrNilForKey:@\"token\" fromDict:dict];\n  if (token == nil) {\n    FIRInstallationsItemSetErrorToPointer(\n        [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@\"authToken.token\"],\n        outError);\n    return nil;\n  }\n\n  NSString *expiresInString = [self validStringOrNilForKey:@\"expiresIn\" fromDict:dict];\n  if (expiresInString == nil) {\n    FIRInstallationsItemSetErrorToPointer(\n        [FIRInstallationsErrorUtil\n            FIDRegistrationErrorWithResponseMissingField:@\"authToken.expiresIn\"],\n        outError);\n    return nil;\n  }\n\n  // The response should contain the string in format like \"604800s\".\n  // The server should never response with anything else except seconds.\n  // Just drop the last character and parse a number from string.\n  NSString *expiresInSeconds = [expiresInString substringToIndex:expiresInString.length - 1];\n  NSTimeInterval expiresIn = [expiresInSeconds doubleValue];\n  NSDate *expirationDate = [date dateByAddingTimeInterval:expiresIn];\n\n  FIRInstallationsStoredAuthToken *authToken = [[FIRInstallationsStoredAuthToken alloc] init];\n  authToken.status = FIRInstallationsAuthTokenStatusTokenReceived;\n  authToken.token = token;\n  authToken.expirationDate = expirationDate;\n\n  return authToken;\n}\n\n#pragma mark - JSON\n\n+ (nullable NSDictionary<NSString *, id> *)dictionaryFromJSONData:(NSData *)data\n                                                            error:(NSError **)outError {\n  NSError *error;\n  NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];\n\n  if (![responseJSON isKindOfClass:[NSDictionary class]]) {\n    FIRInstallationsItemSetErrorToPointer([FIRInstallationsErrorUtil JSONSerializationError:error],\n                                          outError);\n    return nil;\n  }\n\n  return responseJSON;\n}\n\n+ (NSString *)validStringOrNilForKey:(NSString *)key fromDict:(NSDictionary *)dict {\n  NSString *string = dict[key];\n  if ([string isKindOfClass:[NSString class]] && string.length > 0) {\n    return string;\n  }\n  return nil;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A block returning current date. */\ntypedef NSDate *_Nonnull (^FIRCurrentDateProvider)(void);\n\n/** The function returns a `FIRCurrentDateProvider` block that returns a real current date. */\nFIRCurrentDateProvider FIRRealCurrentDateProvider(void);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h\"\n\nFIRCurrentDateProvider FIRRealCurrentDateProvider(void) {\n  return ^NSDate *(void) {\n    return [NSDate date];\n  };\n}\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_ENUM(NSInteger, FIRInstallationsBackoffEvent) {\n  FIRInstallationsBackoffEventSuccess,\n  FIRInstallationsBackoffEventRecoverableFailure,\n  FIRInstallationsBackoffEventUnrecoverableFailure\n};\n\n/** The protocol defines API for a class that encapsulates backoff logic that prevents the SDK from\n * sending unnecessary server requests. See API docs for the methods for more details. */\n\n@protocol FIRInstallationsBackoffControllerProtocol <NSObject>\n\n/** The client must call the method each time a protected server request succeeds of fails. It will\n * affect the `isNextRequestAllowed` method result for the current time, e.g. when 3 recoverable\n * errors were logged in a row, then `isNextRequestAllowed` will return `YES` only in `pow(2, 3)`\n * seconds. */\n- (void)registerEvent:(FIRInstallationsBackoffEvent)event;\n\n/** Returns if sending a next protected is recommended based on the time and the sequence of logged\n * events and the current time. See also `registerEvent:`. */\n- (BOOL)isNextRequestAllowed;\n\n@end\n\n/** An implementation of `FIRInstallationsBackoffControllerProtocol` with exponential backoff for\n * recoverable errors and constant backoff for recoverable errors. */\n@interface FIRInstallationsBackoffController : NSObject <FIRInstallationsBackoffControllerProtocol>\n\n- (instancetype)initWithCurrentDateProvider:(FIRCurrentDateProvider)currentDateProvider;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h\"\n\nstatic const NSTimeInterval k24Hours = 24 * 60 * 60;\nstatic const NSTimeInterval k30Minutes = 30 * 60;\n\n/** The class represents `FIRInstallationsBackoffController` sate required to calculate next allowed\n request time. The properties of the class are intentionally immutable because changing them\n separately leads to an inconsistent state. */\n@interface FIRInstallationsBackoffEventData : NSObject\n\n@property(nonatomic, readonly) FIRInstallationsBackoffEvent eventType;\n@property(nonatomic, readonly) NSDate *lastEventDate;\n@property(nonatomic, readonly) NSInteger eventCount;\n\n@property(nonatomic, readonly) NSTimeInterval backoffTimeInterval;\n\n@end\n\n@implementation FIRInstallationsBackoffEventData\n\n- (instancetype)initWithEvent:(FIRInstallationsBackoffEvent)eventType\n                lastEventDate:(NSDate *)lastEventDate\n                   eventCount:(NSInteger)eventCount {\n  self = [super init];\n  if (self) {\n    _eventType = eventType;\n    _lastEventDate = lastEventDate;\n    _eventCount = eventCount;\n\n    _backoffTimeInterval = [[self class] backoffTimeIntervalWithEvent:eventType\n                                                           eventCount:eventCount];\n  }\n  return self;\n}\n\n+ (NSTimeInterval)backoffTimeIntervalWithEvent:(FIRInstallationsBackoffEvent)eventType\n                                    eventCount:(NSInteger)eventCount {\n  switch (eventType) {\n    case FIRInstallationsBackoffEventSuccess:\n      return 0;\n      break;\n\n    case FIRInstallationsBackoffEventRecoverableFailure:\n      return [self recoverableErrorBackoffTimeForAttemptNumber:eventCount];\n      break;\n\n    case FIRInstallationsBackoffEventUnrecoverableFailure:\n      return k24Hours;\n      break;\n  }\n}\n\n+ (NSTimeInterval)recoverableErrorBackoffTimeForAttemptNumber:(NSInteger)attemptNumber {\n  NSTimeInterval exponentialInterval = pow(2, attemptNumber) + [self randomMilliseconds];\n  return MIN(exponentialInterval, k30Minutes);\n}\n\n+ (NSTimeInterval)randomMilliseconds {\n  int32_t random_millis = ABS(arc4random() % 1000);\n  return (double)random_millis * 0.001;\n}\n\n@end\n\n@interface FIRInstallationsBackoffController ()\n\n@property(nonatomic, readonly) FIRCurrentDateProvider currentDateProvider;\n\n@property(nonatomic, nullable) FIRInstallationsBackoffEventData *lastEventData;\n\n@end\n\n@implementation FIRInstallationsBackoffController\n\n- (instancetype)init {\n  return [self initWithCurrentDateProvider:FIRRealCurrentDateProvider()];\n}\n\n- (instancetype)initWithCurrentDateProvider:(FIRCurrentDateProvider)currentDateProvider {\n  self = [super init];\n  if (self) {\n    _currentDateProvider = [currentDateProvider copy];\n  }\n  return self;\n}\n\n- (BOOL)isNextRequestAllowed {\n  @synchronized(self) {\n    if (self.lastEventData == nil) {\n      return YES;\n    }\n\n    NSTimeInterval timeSinceLastEvent =\n        [self.currentDateProvider() timeIntervalSinceDate:self.lastEventData.lastEventDate];\n    return timeSinceLastEvent >= self.lastEventData.backoffTimeInterval;\n  }\n}\n\n- (void)registerEvent:(FIRInstallationsBackoffEvent)event {\n  @synchronized(self) {\n    // Event of the same type as was registered before.\n    if (self.lastEventData && self.lastEventData.eventType == event) {\n      self.lastEventData = [[FIRInstallationsBackoffEventData alloc]\n          initWithEvent:event\n          lastEventDate:self.currentDateProvider()\n             eventCount:self.lastEventData.eventCount + 1];\n    } else {  // A different event.\n      self.lastEventData =\n          [[FIRInstallationsBackoffEventData alloc] initWithEvent:event\n                                                    lastEventDate:self.currentDateProvider()\n                                                       eventCount:1];\n    }\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class FBLPromise<ValueType>;\n@class FIRInstallationsItem;\n\n/**\n * The class is responsible for managing FID for a given `FIRApp`.\n */\n@interface FIRInstallationsIDController : NSObject\n\n- (instancetype)initWithGoogleAppID:(NSString *)appID\n                            appName:(NSString *)appName\n                             APIKey:(NSString *)APIKey\n                          projectID:(NSString *)projectID\n                        GCMSenderID:(NSString *)GCMSenderID\n                        accessGroup:(nullable NSString *)accessGroup;\n\n- (FBLPromise<FIRInstallationsItem *> *)getInstallationItem;\n\n- (FBLPromise<FIRInstallationsItem *> *)getAuthTokenForcingRefresh:(BOOL)forceRefresh;\n\n- (FBLPromise<NSNull *> *)deleteInstallation;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import <GoogleUtilities/GULKeychainStorage.h>\n#import \"FirebaseCore/Sources/Private/FirebaseCoreInternal.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsItem.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n#import \"FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h\"\n#import \"FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h\"\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n\nconst NSNotificationName FIRInstallationIDDidChangeNotification =\n    @\"FIRInstallationIDDidChangeNotification\";\nNSString *const kFIRInstallationIDDidChangeNotificationAppNameKey =\n    @\"FIRInstallationIDDidChangeNotification\";\n\nNSTimeInterval const kFIRInstallationsTokenExpirationThreshold = 60 * 60;  // 1 hour.\n\nstatic NSString *const kKeychainService = @\"com.firebase.FIRInstallations.installations\";\n\n@interface FIRInstallationsIDController ()\n@property(nonatomic, readonly) NSString *appID;\n@property(nonatomic, readonly) NSString *appName;\n\n@property(nonatomic, readonly) FIRInstallationsStore *installationsStore;\n@property(nonatomic, readonly) FIRInstallationsIIDStore *IIDStore;\n@property(nonatomic, readonly) FIRInstallationsIIDTokenStore *IIDTokenStore;\n\n@property(nonatomic, readonly) FIRInstallationsAPIService *APIService;\n\n@property(nonatomic, readonly) id<FIRInstallationsBackoffControllerProtocol> backoffController;\n\n@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache<FIRInstallationsItem *>\n    *getInstallationPromiseCache;\n@property(nonatomic, readonly)\n    FIRInstallationsSingleOperationPromiseCache<FIRInstallationsItem *> *authTokenPromiseCache;\n@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache<FIRInstallationsItem *>\n    *authTokenForcingRefreshPromiseCache;\n@property(nonatomic, readonly)\n    FIRInstallationsSingleOperationPromiseCache<NSNull *> *deleteInstallationPromiseCache;\n@end\n\n@implementation FIRInstallationsIDController\n\n- (instancetype)initWithGoogleAppID:(NSString *)appID\n                            appName:(NSString *)appName\n                             APIKey:(NSString *)APIKey\n                          projectID:(NSString *)projectID\n                        GCMSenderID:(NSString *)GCMSenderID\n                        accessGroup:(nullable NSString *)accessGroup {\n  NSString *serviceName = [FIRInstallationsIDController keychainServiceWithAppID:appID];\n  GULKeychainStorage *secureStorage = [[GULKeychainStorage alloc] initWithService:serviceName];\n  FIRInstallationsStore *installationsStore =\n      [[FIRInstallationsStore alloc] initWithSecureStorage:secureStorage accessGroup:accessGroup];\n\n  FIRInstallationsAPIService *apiService =\n      [[FIRInstallationsAPIService alloc] initWithAPIKey:APIKey projectID:projectID];\n\n  FIRInstallationsIIDStore *IIDStore = [[FIRInstallationsIIDStore alloc] init];\n  FIRInstallationsIIDTokenStore *IIDCheckingStore =\n      [[FIRInstallationsIIDTokenStore alloc] initWithGCMSenderID:GCMSenderID];\n\n  FIRInstallationsBackoffController *backoffController =\n      [[FIRInstallationsBackoffController alloc] init];\n\n  return [self initWithGoogleAppID:appID\n                           appName:appName\n                installationsStore:installationsStore\n                        APIService:apiService\n                          IIDStore:IIDStore\n                     IIDTokenStore:IIDCheckingStore\n                 backoffController:backoffController];\n}\n\n/// The initializer is supposed to be used by tests to inject `installationsStore`.\n- (instancetype)initWithGoogleAppID:(NSString *)appID\n                            appName:(NSString *)appName\n                 installationsStore:(FIRInstallationsStore *)installationsStore\n                         APIService:(FIRInstallationsAPIService *)APIService\n                           IIDStore:(FIRInstallationsIIDStore *)IIDStore\n                      IIDTokenStore:(FIRInstallationsIIDTokenStore *)IIDTokenStore\n                  backoffController:\n                      (id<FIRInstallationsBackoffControllerProtocol>)backoffController {\n  self = [super init];\n  if (self) {\n    _appID = appID;\n    _appName = appName;\n    _installationsStore = installationsStore;\n    _APIService = APIService;\n    _IIDStore = IIDStore;\n    _IIDTokenStore = IIDTokenStore;\n    _backoffController = backoffController;\n\n    __weak FIRInstallationsIDController *weakSelf = self;\n\n    _getInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]\n        initWithNewOperationHandler:^FBLPromise *_Nonnull {\n          FIRInstallationsIDController *strongSelf = weakSelf;\n          return [strongSelf createGetInstallationItemPromise];\n        }];\n\n    _authTokenPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]\n        initWithNewOperationHandler:^FBLPromise *_Nonnull {\n          FIRInstallationsIDController *strongSelf = weakSelf;\n          return [strongSelf installationWithValidAuthTokenForcingRefresh:NO];\n        }];\n\n    _authTokenForcingRefreshPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]\n        initWithNewOperationHandler:^FBLPromise *_Nonnull {\n          FIRInstallationsIDController *strongSelf = weakSelf;\n          return [strongSelf installationWithValidAuthTokenForcingRefresh:YES];\n        }];\n\n    _deleteInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]\n        initWithNewOperationHandler:^FBLPromise *_Nonnull {\n          FIRInstallationsIDController *strongSelf = weakSelf;\n          return [strongSelf createDeleteInstallationPromise];\n        }];\n  }\n  return self;\n}\n\n#pragma mark - Get Installation.\n\n- (FBLPromise<FIRInstallationsItem *> *)getInstallationItem {\n  return [self.getInstallationPromiseCache getExistingPendingOrCreateNewPromise];\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)createGetInstallationItemPromise {\n  FIRLogDebug(kFIRLoggerInstallations,\n              kFIRInstallationsMessageCodeNewGetInstallationOperationCreated, @\"%s, appName: %@\",\n              __PRETTY_FUNCTION__, self.appName);\n\n  FBLPromise<FIRInstallationsItem *> *installationItemPromise =\n      [self getStoredInstallation].recover(^id(NSError *error) {\n        return [self createAndSaveFID];\n      });\n\n  // Initiate registration process on success if needed, but return the installation without waiting\n  // for it.\n  installationItemPromise.then(^id(FIRInstallationsItem *installation) {\n    [self getAuthTokenForcingRefresh:NO];\n    return nil;\n  });\n\n  return installationItemPromise;\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)getStoredInstallation {\n  return [self.installationsStore installationForAppID:self.appID appName:self.appName].validate(\n      ^BOOL(FIRInstallationsItem *installation) {\n        NSError *validationError;\n        BOOL isValid = [installation isValid:&validationError];\n\n        if (!isValid) {\n          FIRLogWarning(\n              kFIRLoggerInstallations, kFIRInstallationsMessageCodeCorruptedStoredInstallation,\n              @\"Stored installation validation error: %@\", validationError.localizedDescription);\n        }\n\n        return isValid;\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)createAndSaveFID {\n  return [self migrateOrGenerateInstallation]\n      .then(^FBLPromise<FIRInstallationsItem *> *(FIRInstallationsItem *installation) {\n        return [self saveInstallation:installation];\n      })\n      .then(^FIRInstallationsItem *(FIRInstallationsItem *installation) {\n        [self postFIDDidChangeNotification];\n        return installation;\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)saveInstallation:(FIRInstallationsItem *)installation {\n  return [self.installationsStore saveInstallation:installation].then(\n      ^FIRInstallationsItem *(NSNull *result) {\n        return installation;\n      });\n}\n\n/**\n * Tries to migrate IID data stored by FirebaseInstanceID SDK or generates a new Installation ID if\n * not found.\n */\n- (FBLPromise<FIRInstallationsItem *> *)migrateOrGenerateInstallation {\n  if (![self isDefaultApp]) {\n    // Existing IID should be used only for default FirebaseApp.\n    FIRInstallationsItem *installation =\n        [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil];\n    return [FBLPromise resolvedWith:installation];\n  }\n\n  return [[[FBLPromise\n      all:@[ [self.IIDStore existingIID], [self.IIDTokenStore existingIIDDefaultToken] ]]\n      then:^id _Nullable(NSArray *_Nullable results) {\n        NSString *existingIID = results[0];\n        NSString *IIDDefaultToken = results[1];\n\n        return [self createInstallationWithFID:existingIID IIDDefaultToken:IIDDefaultToken];\n      }] recover:^id _Nullable(NSError *_Nonnull error) {\n    return [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil];\n  }];\n}\n\n- (FIRInstallationsItem *)createInstallationWithFID:(NSString *)FID\n                                    IIDDefaultToken:(nullable NSString *)IIDDefaultToken {\n  FIRInstallationsItem *installation = [[FIRInstallationsItem alloc] initWithAppID:self.appID\n                                                                   firebaseAppName:self.appName];\n  installation.firebaseInstallationID = FID;\n  installation.IIDDefaultToken = IIDDefaultToken;\n  installation.registrationStatus = FIRInstallationStatusUnregistered;\n  return installation;\n}\n\n#pragma mark - FID registration\n\n- (FBLPromise<FIRInstallationsItem *> *)registerInstallationIfNeeded:\n    (FIRInstallationsItem *)installation {\n  switch (installation.registrationStatus) {\n    case FIRInstallationStatusRegistered:\n      // Already registered. Do nothing.\n      return [FBLPromise resolvedWith:installation];\n\n    case FIRInstallationStatusUnknown:\n    case FIRInstallationStatusUnregistered:\n      // Registration required. Proceed.\n      break;\n  }\n\n  // Check for backoff.\n  if (![self.backoffController isNextRequestAllowed]) {\n    return [FIRInstallationsErrorUtil\n        rejectedPromiseWithError:[FIRInstallationsErrorUtil backoffIntervalWaitError]];\n  }\n\n  return [self.APIService registerInstallation:installation]\n      .catch(^(NSError *_Nonnull error) {\n        [self updateBackoffWithSuccess:NO APIError:error];\n\n        if ([self doesRegistrationErrorRequireConfigChange:error]) {\n          FIRLogError(kFIRLoggerInstallations,\n                      kFIRInstallationsMessageCodeInvalidFirebaseConfiguration,\n                      @\"Firebase Installation registration failed for app with name: %@, error:\\n\"\n                      @\"%@\\nPlease make sure you use valid GoogleService-Info.plist\",\n                      self.appName, error.userInfo[NSLocalizedFailureReasonErrorKey]);\n        }\n      })\n      .then(^id(FIRInstallationsItem *registeredInstallation) {\n        [self updateBackoffWithSuccess:YES APIError:nil];\n        return [self saveInstallation:registeredInstallation];\n      })\n      .then(^FIRInstallationsItem *(FIRInstallationsItem *registeredInstallation) {\n        // Server may respond with a different FID if the sent one cannot be accepted.\n        if (![registeredInstallation.firebaseInstallationID\n                isEqualToString:installation.firebaseInstallationID]) {\n          [self postFIDDidChangeNotification];\n        }\n        return registeredInstallation;\n      });\n}\n\n- (BOOL)doesRegistrationErrorRequireConfigChange:(NSError *)error {\n  FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error;\n  if (![HTTPError isKindOfClass:[FIRInstallationsHTTPError class]]) {\n    return NO;\n  }\n\n  switch (HTTPError.HTTPResponse.statusCode) {\n    // These are the errors that require Firebase configuration change.\n    case FIRInstallationsRegistrationHTTPCodeInvalidArgument:\n    case FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch:\n    case FIRInstallationsRegistrationHTTPCodeProjectNotFound:\n      return YES;\n\n    default:\n      return NO;\n  }\n}\n\n#pragma mark - Auth Token\n\n- (FBLPromise<FIRInstallationsItem *> *)getAuthTokenForcingRefresh:(BOOL)forceRefresh {\n  if (forceRefresh || [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise] != nil) {\n    return [self.authTokenForcingRefreshPromiseCache getExistingPendingOrCreateNewPromise];\n  } else {\n    return [self.authTokenPromiseCache getExistingPendingOrCreateNewPromise];\n  }\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)installationWithValidAuthTokenForcingRefresh:\n    (BOOL)forceRefresh {\n  FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated,\n              @\"-[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:%@], \"\n              @\"appName: %@\",\n              @(forceRefresh), self.appName);\n\n  return [self getInstallationItem]\n      .then(^FBLPromise<FIRInstallationsItem *> *(FIRInstallationsItem *installation) {\n        return [self registerInstallationIfNeeded:installation];\n      })\n      .then(^id(FIRInstallationsItem *registeredInstallation) {\n        BOOL isTokenExpiredOrExpiresSoon =\n            [registeredInstallation.authToken.expirationDate timeIntervalSinceDate:[NSDate date]] <\n            kFIRInstallationsTokenExpirationThreshold;\n        if (forceRefresh || isTokenExpiredOrExpiresSoon) {\n          return [self refreshAuthTokenForInstallation:registeredInstallation];\n        } else {\n          return registeredInstallation;\n        }\n      })\n      .recover(^id(NSError *error) {\n        return [self regenerateFIDOnRefreshTokenErrorIfNeeded:error];\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)refreshAuthTokenForInstallation:\n    (FIRInstallationsItem *)installation {\n  // Check for backoff.\n  if (![self.backoffController isNextRequestAllowed]) {\n    return [FIRInstallationsErrorUtil\n        rejectedPromiseWithError:[FIRInstallationsErrorUtil backoffIntervalWaitError]];\n  }\n\n  return [[[self.APIService refreshAuthTokenForInstallation:installation]\n      then:^id _Nullable(FIRInstallationsItem *_Nullable refreshedInstallation) {\n        [self updateBackoffWithSuccess:YES APIError:nil];\n        return [self saveInstallation:refreshedInstallation];\n      }] recover:^id _Nullable(NSError *_Nonnull error) {\n    // Pass the error to the backoff controller.\n    [self updateBackoffWithSuccess:NO APIError:error];\n    return error;\n  }];\n}\n\n- (id)regenerateFIDOnRefreshTokenErrorIfNeeded:(NSError *)error {\n  if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) {\n    // No recovery possible. Return the same error.\n    return error;\n  }\n\n  FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error;\n  switch (HTTPError.HTTPResponse.statusCode) {\n    case FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication:\n    case FIRInstallationsAuthTokenHTTPCodeFIDNotFound:\n      // The stored installation was damaged or blocked by the server.\n      // Delete the stored installation then generate and register a new one.\n      return [self getInstallationItem]\n          .then(^FBLPromise<NSNull *> *(FIRInstallationsItem *installation) {\n            return [self deleteInstallationLocally:installation];\n          })\n          .then(^FBLPromise<FIRInstallationsItem *> *(id result) {\n            return [self installationWithValidAuthTokenForcingRefresh:NO];\n          });\n\n    default:\n      // No recovery possible. Return the same error.\n      return error;\n  }\n}\n\n#pragma mark - Delete FID\n\n- (FBLPromise<NSNull *> *)deleteInstallation {\n  return [self.deleteInstallationPromiseCache getExistingPendingOrCreateNewPromise];\n}\n\n- (FBLPromise<NSNull *> *)createDeleteInstallationPromise {\n  FIRLogDebug(kFIRLoggerInstallations,\n              kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated, @\"%s, appName: %@\",\n              __PRETTY_FUNCTION__, self.appName);\n\n  // Check for ongoing requests first, if there is no a request, then check local storage for\n  // existing installation.\n  FBLPromise<FIRInstallationsItem *> *currentInstallationPromise =\n      [self mostRecentInstallationOperation] ?: [self getStoredInstallation];\n\n  return currentInstallationPromise\n      .then(^id(FIRInstallationsItem *installation) {\n        return [self sendDeleteInstallationRequestIfNeeded:installation];\n      })\n      .then(^id(FIRInstallationsItem *installation) {\n        // Remove the installation from the local storage.\n        return [self deleteInstallationLocally:installation];\n      });\n}\n\n- (FBLPromise<NSNull *> *)deleteInstallationLocally:(FIRInstallationsItem *)installation {\n  return [self.installationsStore removeInstallationForAppID:installation.appID\n                                                     appName:installation.firebaseAppName]\n      .then(^FBLPromise<NSNull *> *(NSNull *result) {\n        return [self deleteExistingIIDIfNeeded];\n      })\n      .then(^NSNull *(NSNull *result) {\n        [self postFIDDidChangeNotification];\n        return result;\n      });\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)sendDeleteInstallationRequestIfNeeded:\n    (FIRInstallationsItem *)installation {\n  switch (installation.registrationStatus) {\n    case FIRInstallationStatusUnknown:\n    case FIRInstallationStatusUnregistered:\n      // The installation is not registered, so it is safe to be deleted as is, so return early.\n      return [FBLPromise resolvedWith:installation];\n      break;\n\n    case FIRInstallationStatusRegistered:\n      // Proceed to de-register the installation on the server.\n      break;\n  }\n\n  return [self.APIService deleteInstallation:installation].recover(^id(NSError *APIError) {\n    if ([FIRInstallationsErrorUtil isAPIError:APIError withHTTPCode:404]) {\n      // The installation was not found on the server.\n      // Return success.\n      return installation;\n    } else {\n      // Re-throw the error otherwise.\n      return APIError;\n    }\n  });\n}\n\n- (FBLPromise<NSNull *> *)deleteExistingIIDIfNeeded {\n  if ([self isDefaultApp]) {\n    return [self.IIDStore deleteExistingIID];\n  } else {\n    return [FBLPromise resolvedWith:[NSNull null]];\n  }\n}\n\n- (nullable FBLPromise<FIRInstallationsItem *> *)mostRecentInstallationOperation {\n  return [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise]\n             ?: [self.authTokenPromiseCache getExistingPendingPromise]\n                    ?: [self.getInstallationPromiseCache getExistingPendingPromise];\n}\n\n#pragma mark - Backoff\n\n- (void)updateBackoffWithSuccess:(BOOL)success APIError:(nullable NSError *)APIError {\n  if (success) {\n    [self.backoffController registerEvent:FIRInstallationsBackoffEventSuccess];\n  } else if ([APIError isKindOfClass:[FIRInstallationsHTTPError class]]) {\n    FIRInstallationsHTTPError *HTTPResponseError = (FIRInstallationsHTTPError *)APIError;\n    NSInteger statusCode = HTTPResponseError.HTTPResponse.statusCode;\n\n    if (statusCode == FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication ||\n        statusCode == FIRInstallationsAuthTokenHTTPCodeFIDNotFound) {\n      // These errors are explicitly excluded because they are handled by FIS SDK itself so don't\n      // require backoff.\n    } else if (statusCode == 400 || statusCode == 403) {  // Explicitly unrecoverable errors.\n      [self.backoffController registerEvent:FIRInstallationsBackoffEventUnrecoverableFailure];\n    } else if (statusCode == 429 ||\n               (statusCode >= 500 && statusCode < 600)) {  // Explicitly recoverable errors.\n      [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure];\n    } else {  // Treat all unknown errors as recoverable.\n      [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure];\n    }\n  }\n\n  // If the error class is not `FIRInstallationsHTTPError` it indicates a connection error. Such\n  // errors should not change backoff interval.\n}\n\n#pragma mark - Notifications\n\n- (void)postFIDDidChangeNotification {\n  [[NSNotificationCenter defaultCenter]\n      postNotificationName:FIRInstallationIDDidChangeNotification\n                    object:nil\n                  userInfo:@{kFIRInstallationIDDidChangeNotificationAppNameKey : self.appName}];\n}\n\n#pragma mark - Default App\n\n- (BOOL)isDefaultApp {\n  return [self.appName isEqualToString:kFIRDefaultAppName];\n}\n\n#pragma mark - Keychain\n\n+ (NSString *)keychainServiceWithAppID:(NSString *)appID {\n#if TARGET_OS_MACCATALYST || TARGET_OS_OSX\n  // We need to keep service name unique per application on macOS.\n  // Applications on macOS may request access to Keychain items stored by other applications. It\n  // means that when the app looks up for a relevant Keychain item in the service scope it will\n  // request user password to grant access to the Keychain if there are other Keychain items from\n  // other applications stored under the same Keychain Service.\n  return [kKeychainService stringByAppendingFormat:@\".%@\", appID];\n#else\n  // Use a constant Keychain service for non-macOS because:\n  // 1. Keychain items cannot be shared between apps until configured specifically so the service\n  // name collisions are not a concern\n  // 2. We don't want to change the service name to avoid doing a migration.\n  return kKeychainService;\n#endif\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The class makes sure the a single operation (represented by a promise) is performed at a time. If\n * there is an ongoing operation, then its existing corresponding promise will be returned instead\n * of starting a new operation.\n */\n@interface FIRInstallationsSingleOperationPromiseCache<__covariant ResultType> : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n * The designated initializer.\n * @param newOperationHandler The block that must return a new promise representing the\n * single-at-a-time operation. The promise should be fulfilled when the operation is completed. The\n * factory block will be used to create a new promise when needed.\n */\n- (instancetype)initWithNewOperationHandler:\n    (FBLPromise<ResultType> *_Nonnull (^)(void))newOperationHandler NS_DESIGNATED_INITIALIZER;\n\n/**\n * Creates a new promise or returns an existing pending one.\n * @return Returns and existing pending promise if exists. If the pending promise does not exist\n * then a new one will be created using the `factory` block passed in the initializer. Once the\n * pending promise gets resolved, it is removed, so calling the method again will lead to creating\n * and caching another promise.\n */\n- (FBLPromise<ResultType> *)getExistingPendingOrCreateNewPromise;\n\n/**\n * Returns an existing pending promise or `nil`.\n * @return Returns an existing pending promise if there is one or `nil` otherwise.\n */\n- (nullable FBLPromise<ResultType> *)getExistingPendingPromise;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n@interface FIRInstallationsSingleOperationPromiseCache <ResultType>()\n@property(nonatomic, readonly) FBLPromise *_Nonnull (^newOperationHandler)(void);\n@property(nonatomic, nullable) FBLPromise *pendingPromise;\n@end\n\n@implementation FIRInstallationsSingleOperationPromiseCache\n\n- (instancetype)initWithNewOperationHandler:\n    (FBLPromise<id> *_Nonnull (^)(void))newOperationHandler {\n  if (newOperationHandler == nil) {\n    [NSException raise:NSInvalidArgumentException\n                format:@\"`newOperationHandler` must not be `nil`.\"];\n  }\n\n  self = [super init];\n  if (self) {\n    _newOperationHandler = [newOperationHandler copy];\n  }\n  return self;\n}\n\n- (FBLPromise *)getExistingPendingOrCreateNewPromise {\n  @synchronized(self) {\n    if (!self.pendingPromise) {\n      self.pendingPromise = self.newOperationHandler();\n\n      self.pendingPromise\n          .then(^id(id result) {\n            @synchronized(self) {\n              self.pendingPromise = nil;\n              return nil;\n            }\n          })\n          .catch(^void(NSError *error) {\n            @synchronized(self) {\n              self.pendingPromise = nil;\n            }\n          });\n    }\n\n    return self.pendingPromise;\n  }\n}\n\n- (nullable FBLPromise *)getExistingPendingPromise {\n  @synchronized(self) {\n    return self.pendingPromise;\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * The enum represent possible states of the installation ID.\n *\n * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredItem`. Modification\n * of it can lead to incompatibility with previous version. Any modification must be evaluated and,\n * if it is really needed, the `storageVersion` must be bumped and proper migration code added.\n */\ntypedef NS_ENUM(NSInteger, FIRInstallationsStatus) {\n  /** Represents either an initial status when a FIRInstallationsItem instance was created but not\n   * stored to Keychain or an undefined status (e.g. when the status failed to deserialize).\n   */\n  FIRInstallationStatusUnknown,\n  /// The Firebase Installation has not yet been registered with FIS.\n  FIRInstallationStatusUnregistered,\n  /// The Firebase Installation has successfully been registered with FIS.\n  FIRInstallationStatusRegistered,\n};\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n@class FIRInstallationsItem;\n@class GULKeychainStorage;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The user defaults suite name used to store data.\nextern NSString *const kFIRInstallationsStoreUserDefaultsID;\n\n/// The class is responsible for storing and accessing the installations data.\n@interface FIRInstallationsStore : NSObject\n\n/**\n * The default initializer.\n * @param storage The secure storage to save installations data.\n * @param accessGroup The Keychain Access Group to store and request the installations data.\n */\n- (instancetype)initWithSecureStorage:(GULKeychainStorage *)storage\n                          accessGroup:(nullable NSString *)accessGroup;\n\n/**\n * Retrieves existing installation ID if there is.\n * @param appID The Firebase(Google) Application ID.\n * @param appName The Firebase Application Name.\n *\n * @return Returns a `FBLPromise` instance. The promise is resolved with a FIRInstallationsItem\n * instance if there is a valid installation stored for `appID` and `appName`. The promise is\n * rejected with a specific error when the installation has not been found or with another possible\n * error.\n */\n- (FBLPromise<FIRInstallationsItem *> *)installationForAppID:(NSString *)appID\n                                                     appName:(NSString *)appName;\n\n/**\n * Saves the given installation.\n *\n * @param installationItem The installation data.\n * @return Returns a promise that is resolved with `[NSNull null]` on success.\n */\n- (FBLPromise<NSNull *> *)saveInstallation:(FIRInstallationsItem *)installationItem;\n\n/**\n * Removes installation data for the given app parameters.\n * @param appID The Firebase(Google) Application ID.\n * @param appName The Firebase Application Name.\n *\n * @return Returns a promise that is resolved with `[NSNull null]` on success.\n */\n- (FBLPromise<NSNull *> *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h\"\n\n#import <GoogleUtilities/GULUserDefaults.h>\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import <GoogleUtilities/GULKeychainStorage.h>\n\n#import \"FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h\"\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsItem.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h\"\n\nNSString *const kFIRInstallationsStoreUserDefaultsID = @\"com.firebase.FIRInstallations\";\n\n@interface FIRInstallationsStore ()\n@property(nonatomic, readonly) GULKeychainStorage *secureStorage;\n@property(nonatomic, readonly, nullable) NSString *accessGroup;\n@property(nonatomic, readonly) dispatch_queue_t queue;\n@property(nonatomic, readonly) GULUserDefaults *userDefaults;\n@end\n\n@implementation FIRInstallationsStore\n\n- (instancetype)initWithSecureStorage:(GULKeychainStorage *)storage\n                          accessGroup:(NSString *)accessGroup {\n  self = [super init];\n  if (self) {\n    _secureStorage = storage;\n    _accessGroup = [accessGroup copy];\n    _queue = dispatch_queue_create(\"com.firebase.FIRInstallationsStore\", DISPATCH_QUEUE_SERIAL);\n\n    NSString *userDefaultsSuiteName = _accessGroup ?: kFIRInstallationsStoreUserDefaultsID;\n    _userDefaults = [[GULUserDefaults alloc] initWithSuiteName:userDefaultsSuiteName];\n  }\n  return self;\n}\n\n- (FBLPromise<FIRInstallationsItem *> *)installationForAppID:(NSString *)appID\n                                                     appName:(NSString *)appName {\n  NSString *itemID = [FIRInstallationsItem identifierWithAppID:appID appName:appName];\n  return [self installationExistsForAppID:appID appName:appName]\n      .then(^id(id result) {\n        return [self.secureStorage getObjectForKey:itemID\n                                       objectClass:[FIRInstallationsStoredItem class]\n                                       accessGroup:self.accessGroup];\n      })\n      .then(^id(FIRInstallationsStoredItem *_Nullable storedItem) {\n        if (storedItem == nil) {\n          return [FIRInstallationsErrorUtil installationItemNotFoundForAppID:appID appName:appName];\n        }\n\n        FIRInstallationsItem *item = [[FIRInstallationsItem alloc] initWithAppID:appID\n                                                                 firebaseAppName:appName];\n        [item updateWithStoredItem:storedItem];\n        return item;\n      });\n}\n\n- (FBLPromise<NSNull *> *)saveInstallation:(FIRInstallationsItem *)installationItem {\n  FIRInstallationsStoredItem *storedItem = [installationItem storedItem];\n  NSString *identifier = [installationItem identifier];\n\n  return\n      [self.secureStorage setObject:storedItem forKey:identifier accessGroup:self.accessGroup].then(\n          ^id(id result) {\n            return [self setInstallationExists:YES forItemWithIdentifier:identifier];\n          });\n}\n\n- (FBLPromise<NSNull *> *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName {\n  NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName];\n  return [self.secureStorage removeObjectForKey:identifier accessGroup:self.accessGroup].then(\n      ^id(id result) {\n        return [self setInstallationExists:NO forItemWithIdentifier:identifier];\n      });\n}\n\n#pragma mark - User defaults\n\n- (FBLPromise<NSNull *> *)installationExistsForAppID:(NSString *)appID appName:(NSString *)appName {\n  NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName];\n  return [FBLPromise onQueue:self.queue\n                          do:^id _Nullable {\n                            return [[self userDefaults] objectForKey:identifier] != nil\n                                       ? [NSNull null]\n                                       : [FIRInstallationsErrorUtil\n                                             installationItemNotFoundForAppID:appID\n                                                                      appName:appName];\n                          }];\n}\n\n- (FBLPromise<NSNull *> *)setInstallationExists:(BOOL)exists\n                          forItemWithIdentifier:(NSString *)identifier {\n  return [FBLPromise onQueue:self.queue\n                          do:^id _Nullable {\n                            if (exists) {\n                              [[self userDefaults] setBool:YES forKey:identifier];\n                            } else {\n                              [[self userDefaults] removeObjectForKey:identifier];\n                            }\n\n                            return [NSNull null];\n                          }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The enum represent possible states of the installation auth token.\n *\n * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredAuthToken`.\n * Modification of it can lead to incompatibility with previous version. Any modification must be\n * evaluated and, if it is really needed, the `storageVersion` must be bumped and proper migration\n * code added.\n */\ntypedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenStatus) {\n  /// An initial status or an undefined value.\n  FIRInstallationsAuthTokenStatusUnknown,\n  /// The auth token has been received from the server.\n  FIRInstallationsAuthTokenStatusTokenReceived\n};\n\n/**\n * This class serializes and deserializes the installation data into/from `NSData` to be stored in\n * Keychain. This class is primarily used by `FIRInstallationsStore`. It is also used on the logic\n * level as a data object (see `FIRInstallationsItem.authToken`).\n *\n * WARNING: Modification of the class properties can lead to incompatibility with the stored data\n * encoded by the previous class versions. Any modification must be evaluated and, if it is really\n * needed, the `storageVersion` must be bumped and proper migration code added.\n */\n@interface FIRInstallationsStoredAuthToken : NSObject <NSSecureCoding, NSCopying>\n@property FIRInstallationsAuthTokenStatus status;\n\n/// The installation auth token string that can be used to authorize requests to Firebase backend.\n@property(nullable, copy) NSString *token;\n/// The installation auth token expiration date.\n@property(nullable, copy) NSDate *expirationDate;\n\n/// The version of local storage.\n@property(nonatomic, readonly) NSInteger storageVersion;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n\nNSString *const kFIRInstallationsStoredAuthTokenStatusKey = @\"status\";\nNSString *const kFIRInstallationsStoredAuthTokenTokenKey = @\"token\";\nNSString *const kFIRInstallationsStoredAuthTokenExpirationDateKey = @\"expirationDate\";\nNSString *const kFIRInstallationsStoredAuthTokenStorageVersionKey = @\"storageVersion\";\n\nNSInteger const kFIRInstallationsStoredAuthTokenStorageVersion = 1;\n\n@implementation FIRInstallationsStoredAuthToken\n\n- (NSInteger)storageVersion {\n  return kFIRInstallationsStoredAuthTokenStorageVersion;\n}\n\n- (nonnull id)copyWithZone:(nullable NSZone *)zone {\n  FIRInstallationsStoredAuthToken *clone = [[FIRInstallationsStoredAuthToken alloc] init];\n  clone.status = self.status;\n  clone.token = [self.token copy];\n  clone.expirationDate = self.expirationDate;\n  return clone;\n}\n\n- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {\n  [aCoder encodeInteger:self.status forKey:kFIRInstallationsStoredAuthTokenStatusKey];\n  [aCoder encodeObject:self.token forKey:kFIRInstallationsStoredAuthTokenTokenKey];\n  [aCoder encodeObject:self.expirationDate\n                forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey];\n  [aCoder encodeInteger:self.storageVersion\n                 forKey:kFIRInstallationsStoredAuthTokenStorageVersionKey];\n}\n\n- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {\n  NSInteger storageVersion =\n      [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStorageVersionKey];\n  if (storageVersion > kFIRInstallationsStoredAuthTokenStorageVersion) {\n    FIRLogWarning(kFIRLoggerInstallations,\n                  kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch,\n                  @\"FIRInstallationsStoredAuthToken was encoded by a newer coder version %ld. \"\n                  @\"Current coder version is %ld. Some auth token data may be lost.\",\n                  (long)storageVersion, (long)kFIRInstallationsStoredAuthTokenStorageVersion);\n  }\n\n  FIRInstallationsStoredAuthToken *object = [[FIRInstallationsStoredAuthToken alloc] init];\n  object.status = [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStatusKey];\n  object.token = [aDecoder decodeObjectOfClass:[NSString class]\n                                        forKey:kFIRInstallationsStoredAuthTokenTokenKey];\n  object.expirationDate =\n      [aDecoder decodeObjectOfClass:[NSDate class]\n                             forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey];\n\n  return object;\n}\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h\"\n\n@class FIRInstallationsStoredAuthToken;\n@class FIRInstallationsStoredIIDCheckin;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The class is supposed to be used by `FIRInstallationsStore` only. It is required to\n * serialize/deserialize the installation data into/from `NSData` to be stored in Keychain.\n *\n * WARNING: Modification of the class properties can lead to incompatibility with the stored data\n * encoded by the previous class versions. Any modification must be evaluated and, if it is really\n * needed, the `storageVersion` must be bumped and proper migration code added.\n */\n@interface FIRInstallationsStoredItem : NSObject <NSSecureCoding>\n\n///  A stable identifier that uniquely identifies the app instance.\n@property(nonatomic, copy, nullable) NSString *firebaseInstallationID;\n/// The `refreshToken` is used to authorize the installation auth token requests.\n@property(nonatomic, copy, nullable) NSString *refreshToken;\n\n@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken;\n@property(nonatomic) FIRInstallationsStatus registrationStatus;\n\n/// Instance ID default auth token imported from IID store as a part of IID migration.\n@property(nonatomic, nullable) NSString *IIDDefaultToken;\n\n/// The version of local storage.\n@property(nonatomic, readonly) NSInteger storageVersion;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h\"\n\n#import \"FirebaseInstallations/Source/Library/FIRInstallationsLogger.h\"\n#import \"FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h\"\n\nNSString *const kFIRInstallationsStoredItemFirebaseInstallationIDKey = @\"firebaseInstallationID\";\nNSString *const kFIRInstallationsStoredItemRefreshTokenKey = @\"refreshToken\";\nNSString *const kFIRInstallationsStoredItemAuthTokenKey = @\"authToken\";\nNSString *const kFIRInstallationsStoredItemRegistrationStatusKey = @\"registrationStatus\";\nNSString *const kFIRInstallationsStoredItemIIDDefaultTokenKey = @\"IIDDefaultToken\";\nNSString *const kFIRInstallationsStoredItemStorageVersionKey = @\"storageVersion\";\n\nNSInteger const kFIRInstallationsStoredItemStorageVersion = 1;\n\n@implementation FIRInstallationsStoredItem\n\n- (NSInteger)storageVersion {\n  return kFIRInstallationsStoredItemStorageVersion;\n}\n\n- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {\n  [aCoder encodeObject:self.firebaseInstallationID\n                forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey];\n  [aCoder encodeObject:self.refreshToken forKey:kFIRInstallationsStoredItemRefreshTokenKey];\n  [aCoder encodeObject:self.authToken forKey:kFIRInstallationsStoredItemAuthTokenKey];\n  [aCoder encodeInteger:self.registrationStatus\n                 forKey:kFIRInstallationsStoredItemRegistrationStatusKey];\n  [aCoder encodeObject:self.IIDDefaultToken forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey];\n  [aCoder encodeInteger:self.storageVersion forKey:kFIRInstallationsStoredItemStorageVersionKey];\n}\n\n- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {\n  NSInteger storageVersion =\n      [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemStorageVersionKey];\n  if (storageVersion > self.storageVersion) {\n    FIRLogWarning(kFIRLoggerInstallations,\n                  kFIRInstallationsMessageCodeInstallationCoderVersionMismatch,\n                  @\"FIRInstallationsStoredItem was encoded by a newer coder version %ld. Current \"\n                  @\"coder version is %ld. Some installation data may be lost.\",\n                  (long)storageVersion, (long)kFIRInstallationsStoredItemStorageVersion);\n  }\n\n  FIRInstallationsStoredItem *item = [[FIRInstallationsStoredItem alloc] init];\n  item.firebaseInstallationID =\n      [aDecoder decodeObjectOfClass:[NSString class]\n                             forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey];\n  item.refreshToken = [aDecoder decodeObjectOfClass:[NSString class]\n                                             forKey:kFIRInstallationsStoredItemRefreshTokenKey];\n  item.authToken = [aDecoder decodeObjectOfClass:[FIRInstallationsStoredAuthToken class]\n                                          forKey:kFIRInstallationsStoredItemAuthTokenKey];\n  item.registrationStatus =\n      [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemRegistrationStatusKey];\n  item.IIDDefaultToken =\n      [aDecoder decodeObjectOfClass:[NSString class]\n                             forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey];\n\n  return item;\n}\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// An umbrella header, for any other libraries in this repo to access Firebase\n// Installations Public headers. Any package manager complexity should be\n// handled here.\n\n#import <FirebaseInstallations/FirebaseInstallations.h>\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FIRApp;\n@class FIRInstallationsAuthTokenResult;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A notification with this name is sent each time an installation is created or deleted. */\n// clang-format off\n// clang-format12 merges the next two lines.\nFOUNDATION_EXPORT const NSNotificationName FIRInstallationIDDidChangeNotification\n    NS_SWIFT_NAME(InstallationIDDidChange);\n/** `userInfo` key for the `FirebaseApp.name` in `FIRInstallationIDDidChangeNotification`. */\nFOUNDATION_EXPORT NSString *const kFIRInstallationIDDidChangeNotificationAppNameKey\n    NS_SWIFT_NAME(InstallationIDDidChangeAppNameKey);\n// clang-format on\n\n/**\n * An installation ID handler block.\n * @param identifier The installation ID string if exists or `nil` otherwise.\n * @param error The error when `identifier == nil` or `nil` otherwise.\n */\ntypedef void (^FIRInstallationsIDHandler)(NSString *__nullable identifier,\n                                          NSError *__nullable error)\n    NS_SWIFT_NAME(InstallationsIDHandler);\n\n/**\n * An authorization token handler block.\n * @param tokenResult An instance of `InstallationsAuthTokenResult` in case of success or `nil`\n * otherwise.\n * @param error The error when `tokenResult == nil` or `nil` otherwise.\n */\ntypedef void (^FIRInstallationsTokenHandler)(\n    FIRInstallationsAuthTokenResult *__nullable tokenResult, NSError *__nullable error)\n    NS_SWIFT_NAME(InstallationsTokenHandler);\n\n/**\n * The class provides API for Firebase Installations.\n * Each configured `FirebaseApp` has a corresponding single instance of `Installations`.\n * An instance of the class provides access to the installation info for the `FirebaseApp` as well\n * as the ability to delete it. A Firebase Installation is unique by `FirebaseApp.name` and\n * `FirebaseApp.options.googleAppID` .\n */\nNS_SWIFT_NAME(Installations)\n@interface FIRInstallations : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n * Returns a default instance of `Installations`.\n * @returns An instance of `Installations` for `FirebaseApp.defaultApp().\n * @throw Throws an exception if the default app is not configured yet or required  `FirebaseApp`\n * options are missing.\n */\n+ (FIRInstallations *)installations NS_SWIFT_NAME(installations());\n\n/**\n * Returns an instance of `Installations` for an application.\n * @param application A configured `FirebaseApp` instance.\n * @returns An instance of `Installations` corresponding to the passed application.\n * @throw Throws an exception if required `FirebaseApp` options are missing.\n */\n+ (FIRInstallations *)installationsWithApp:(FIRApp *)application\n    NS_SWIFT_NAME(installations(app:));\n\n/**\n * The method creates or retrieves an installation ID. The installation ID is a stable identifier\n * that uniquely identifies the app instance. NOTE: If the application already has an existing\n * FirebaseInstanceID then the InstanceID identifier will be used.\n * @param completion A completion handler which is invoked when the operation completes. See\n * `InstallationsIDHandler` for additional details.\n */\n- (void)installationIDWithCompletion:(FIRInstallationsIDHandler)completion;\n\n/**\n * Retrieves (locally if it exists or from the server) a valid installation auth token. An existing\n * token may be invalidated or expired, so it is recommended to fetch the installation auth token\n * before each server request. The method does the same as `Installations.authTokenForcingRefresh(:,\n * completion:)` with forcing refresh `NO`.\n * @param completion A completion handler which is invoked when the operation completes. See\n * `InstallationsTokenHandler` for additional details.\n */\n- (void)authTokenWithCompletion:(FIRInstallationsTokenHandler)completion;\n\n/**\n * Retrieves (locally or from the server depending on `forceRefresh` value) a valid installation\n * auth token. An existing token may be invalidated or expire, so it is recommended to fetch the\n * installation auth token before each server request. This method should be used with `forceRefresh\n * == YES` when e.g. a request with the previously fetched installation auth token failed with \"Not\n * Authorized\" error.\n * @param forceRefresh If `YES` then the locally cached installation auth token will be ignored and\n * a new one will be requested from the server. If `NO`, then the locally cached installation auth\n * token will be returned if exists and has not expired yet.\n * @param completion  A completion handler which is invoked when the operation completes. See\n * `InstallationsTokenHandler` for additional details.\n */\n- (void)authTokenForcingRefresh:(BOOL)forceRefresh\n                     completion:(FIRInstallationsTokenHandler)completion;\n\n/**\n * Deletes all the installation data including the unique identifier, auth tokens and\n * all related data on the server side. A network connection is required for the method to\n * succeed. If fails, the existing installation data remains untouched.\n * @param completion A completion handler which is invoked when the operation completes. `error ==\n * nil` indicates success.\n */\n- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The class represents a result of the installation auth token request. */\nNS_SWIFT_NAME(InstallationsAuthTokenResult)\n@interface FIRInstallationsAuthTokenResult : NSObject\n\n/** The installation auth token string. */\n@property(nonatomic, readonly) NSString *authToken;\n\n/** The installation auth token expiration date. */\n@property(nonatomic, readonly) NSDate *expirationDate;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nextern NSString *const kFirebaseInstallationsErrorDomain;\n\ntypedef NS_ENUM(NSUInteger, FIRInstallationsErrorCode) {\n  /** Unknown error. See `userInfo` for details. */\n  FIRInstallationsErrorCodeUnknown = 0,\n\n  /** Keychain error. See `userInfo` for details. */\n  FIRInstallationsErrorCodeKeychain = 1,\n\n  /** Server unreachable. A network error or server is unavailable. See `userInfo` for details. */\n  FIRInstallationsErrorCodeServerUnreachable = 2,\n\n  /** FirebaseApp configuration issues e.g. invalid GMP-App-ID, etc. See `userInfo` for details. */\n  FIRInstallationsErrorCodeInvalidConfiguration = 3,\n\n} NS_SWIFT_NAME(InstallationsErrorCode);\n"
  },
  {
    "path": "Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"FIRInstallations.h\"\n#import \"FIRInstallationsAuthTokenResult.h\"\n#import \"FIRInstallationsErrors.h\"\n"
  },
  {
    "path": "Pods/FirebaseInstallations/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/FirebaseInstallations/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![License](https://img.shields.io/cocoapods/l/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n[![Platform](https://img.shields.io/cocoapods/p/Firebase.svg?style=flat)](https://cocoapods.org/pods/Firebase)\n\n[![Actions Status][gh-abtesting-badge]][gh-actions]\n[![Actions Status][gh-appcheck-badge]][gh-actions]\n[![Actions Status][gh-appdistribution-badge]][gh-actions]\n[![Actions Status][gh-auth-badge]][gh-actions]\n[![Actions Status][gh-cocoapods-integration-badge]][gh-actions]\n[![Actions Status][gh-core-badge]][gh-actions]\n[![Actions Status][gh-core-diagnostics-badge]][gh-actions]\n[![Actions Status][gh-crashlytics-badge]][gh-actions]\n[![Actions Status][gh-database-badge]][gh-actions]\n[![Actions Status][gh-datatransport-badge]][gh-actions]\n[![Actions Status][gh-dynamiclinks-badge]][gh-actions]\n[![Actions Status][gh-firebasepod-badge]][gh-actions]\n[![Actions Status][gh-firestore-badge]][gh-actions]\n[![Actions Status][gh-functions-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-badge]][gh-actions]\n[![Actions Status][gh-google-utilities-components-badge]][gh-actions]\n[![Actions Status][gh-inappmessaging-badge]][gh-actions]\n[![Actions Status][gh-interop-badge]][gh-actions]\n[![Actions Status][gh-messaging-badge]][gh-actions]\n[![Actions Status][gh-mlmodeldownloader-badge]][gh-actions]\n[![Actions Status][gh-performance-badge]][gh-actions]\n[![Actions Status][gh-remoteconfig-badge]][gh-actions]\n[![Actions Status][gh-storage-badge]][gh-actions]\n[![Actions Status][gh-symbolcollision-badge]][gh-actions]\n[![Actions Status][gh-zip-badge]][gh-actions]\n[![Travis](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)\n\n# Firebase Apple Open Source Development\n\nThis repository contains all Apple platform Firebase SDK source except FirebaseAnalytics\nand FirebaseML.\n\nFirebase is an app development platform with tools to help you build, grow and\nmonetize your app. More information about Firebase can be found on the\n[official Firebase website](https://firebase.google.com).\n\n**Note** _FirebaseCombineSwift_ contains support for Apple's Combine framework. This module is currently under development, and not yet supported for use in production environments. Fore more details, please refer to the [docs](FirebaseCombineSwift/README.md).\n\n## Installation\n\nSee the subsections below for details about the different installation methods.\n1. [Standard pod install](README.md#standard-pod-install)\n1. [Swift Package Manager](SwiftPackageManager.md)\n1. [Installing from the GitHub repo](README.md#installing-from-github)\n1. [Experimental Carthage](README.md#carthage-ios-only)\n\n### Standard pod install\n\nGo to\n[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).\n\n### Swift Package Manager\n\nInstructions for [Swift Package Manager](https://swift.org/package-manager/) support can be\nfound at [SwiftPackageManager.md](SwiftPackageManager.md).\n\n### Installing from GitHub\n\nThese instructions can be used to access the Firebase repo at other branches,\ntags, or commits.\n\n#### Background\n\nSee\n[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)\nfor instructions and options about overriding pod source locations.\n\n#### Accessing Firebase Source Snapshots\n\nAll of the official releases are tagged in this repo and available via CocoaPods. To access a local\nsource snapshot or unreleased branch, use Podfile directives like the following:\n\nTo access FirebaseFirestore via a branch:\n```ruby\npod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\npod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'\n```\n\nTo access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:\n\n```ruby\npod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'\npod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'\n```\n\n### Carthage (iOS only)\n\nInstructions for the experimental Carthage distribution are at\n[Carthage](Carthage.md).\n\n### Using Firebase from a Framework or a library\n\n[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md)\n\n## Development\n\nTo develop Firebase software in this repository, ensure that you have at least\nthe following software:\n\n  * Xcode 12.2 (or later)\n\nCocoaPods is still the canonical way to develop, but much of the repo now supports\ndevelopment with Swift Package Manager.\n\n### CocoaPods\n\nInstall\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n```ruby\npod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios\n```\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\nFirestore has a self contained Xcode project. See\n[Firestore/README.md](Firestore/README.md).\n\n#### Development for Catalyst\n* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Swift Package Manager\n* To enable test schemes: `./scripts/setup_spm_tests.sh`\n* `open Package.swift` or double click `Package.swift` in Finder.\n* Xcode will open the project\n  * Choose a scheme for a library to build or test suite to run\n  * Choose a target platform by selecting the run destination along with the scheme\n\n### Adding a New Firebase Pod\n\nSee [AddNewPod.md](AddNewPod.md).\n\n### Managing Headers and Imports\n\nSee [HeadersImports.md](HeadersImports.md).\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n### Running Sample Apps\nIn order to run the sample apps and integration tests, you'll need a valid\n`GoogleService-Info.plist` file. The Firebase Xcode project contains dummy plist\nfiles without real values, but can be replaced with real plist files. To get your own\n`GoogleService-Info.plist` files:\n\n1. Go to the [Firebase Console](https://console.firebase.google.com/)\n2. Create a new Firebase project, if you don't already have one\n3. For each sample app you want to test, create a new Firebase app with the sample app's bundle\nidentifier (e.g. `com.google.Database-Example`)\n4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project.\n\n### Coverage Report Generation\n\nSee [scripts/code_coverage_report/README.md](scripts/code_coverage_report/README.md).\n\n## Specific Component Instructions\nSee the sections below for any special instructions for those components.\n\n### Firebase Auth\n\nIf you're doing specific Firebase Auth development, see\n[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about\nbuilding and running the FirebaseAuth pod along with various samples and tests.\n\n### Firebase Database\n\nThe Firebase Database Integration tests can be run against a locally running Database Emulator\nor against a production instance.\n\nTo run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before\nrunning the integration test.\n\nTo run against a production instance, provide a valid GoogleServices-Info.plist and copy it to\n`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to\n[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are\nrunning.\n\n### Firebase Performance Monitoring\nIf you're doing specific Firebase Performance Monitoring development, see\n[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK\nand [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about\nintegrating Performance with the dev test App.\n\n### Firebase Storage\n\nTo run the Storage Integration tests, follow the instructions in\n[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m).\n\n#### Push Notifications\n\nPush notifications can only be delivered to specially provisioned App IDs in the developer portal.\nIn order to actually test receiving push notifications, you will need to:\n\n1. Change the bundle identifier of the sample app to something you own in your Apple Developer\naccount, and enable that App ID for push notifications.\n2. You'll also need to\n[upload your APNs Provider Authentication Key or certificate to the\nFirebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)\nat **Project Settings > Cloud Messaging > [Your Firebase App]**.\n3. Ensure your iOS device is added to your Apple Developer portal as a test device.\n\n#### iOS Simulator\n\nThe iOS Simulator cannot register for remote notifications, and will not receive push notifications.\nIn order to receive push notifications, you'll have to follow the steps above and run the app on a\nphysical device.\n\n## Building with Firebase on Apple platforms\n\nAt this time, not all of Firebase's products are available across all Apple platforms. However,\nFirebase is constantly evolving and community supported efforts have helped expand Firebase's support.\nTo keep up with the latest info regarding Firebase's support across Apple platforms, refer to\n[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform)\nin Firebase's documentation.\n\n### Community Supported Efforts\n\nWe've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are\nvery grateful!  We'd like to empower as many developers as we can to be able to use Firebase and\nparticipate in the Firebase community.\n\n#### tvOS, macOS, watchOS and Catalyst\nThanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and\nwork on tvOS, macOS, watchOS and Catalyst.\n\nFor tvOS, see the [Sample](Example/tvOSSample).\nFor watchOS, currently only Messaging, Storage and Crashlytics (and their dependencies) have limited\nsupport. See the [Independent Watch App Sample](Example/watchOSSample).\n\nKeep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and\nthis repository is actively developed primarily for iOS. While we can catch basic unit test issues\nwith GitHub Actions, there may be some changes where the SDK no longer works as expected on macOS,\ntvOS or watchOS. If you encounter this, please\n[file an issue](https://github.com/firebase/firebase-ios-sdk/issues).\n\nDuring app setup in the console, you may get to a step that mentions something like \"Checking if the\napp has communicated with our servers\". This relies on Analytics and will not work on\nmacOS/tvOS/watchOS/Catalyst.\n**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.\n\n#### Additional MacOS and Catalyst Notes\n\n* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`\nto Build Settings.\n* For Catalyst, FirebaseFirestore requires signing the\n[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).\n\n#### Additional Crashlytics Notes\n* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are\nnot recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded)\n\n## Roadmap\n\nSee [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source\nplans and directions.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase\niOS SDK.\n\n## License\n\nThe contents of this repository are licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\nYour use of Firebase is governed by the\n[Terms of Service for Firebase Services](https://firebase.google.com/terms/).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg\n[gh-appcheck-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/app_check/badge.svg\n[gh-appdistribution-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/appdistribution/badge.svg\n[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg\n[gh-cocoapods-integration-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/cocoapods-integration/badge.svg\n[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg\n[gh-core-diagnostics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core-diagnostics/badge.svg\n[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg\n[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg\n[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg\n[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg\n[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg\n[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg\n[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg\n[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg\n[gh-google-utilities-components-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities-components/badge.svg\n[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg\n[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg\n[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg\n[gh-mlmodeldownloader-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/mlmodeldownloader/badge.svg\n[gh-performance-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/performance/badge.svg\n[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg\n[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg\n[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg\n[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg\n"
  },
  {
    "path": "Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/Info.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>AvailableLibraries</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>LibraryIdentifier</key>\n\t\t\t<string>ios-arm64_armv7</string>\n\t\t\t<key>LibraryPath</key>\n\t\t\t<string>GoogleAppMeasurement.framework</string>\n\t\t\t<key>SupportedArchitectures</key>\n\t\t\t<array>\n\t\t\t\t<string>arm64</string>\n\t\t\t\t<string>armv7</string>\n\t\t\t</array>\n\t\t\t<key>SupportedPlatform</key>\n\t\t\t<string>ios</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>LibraryIdentifier</key>\n\t\t\t<string>ios-arm64_i386_x86_64-simulator</string>\n\t\t\t<key>LibraryPath</key>\n\t\t\t<string>GoogleAppMeasurement.framework</string>\n\t\t\t<key>SupportedArchitectures</key>\n\t\t\t<array>\n\t\t\t\t<string>arm64</string>\n\t\t\t\t<string>i386</string>\n\t\t\t\t<string>x86_64</string>\n\t\t\t</array>\n\t\t\t<key>SupportedPlatform</key>\n\t\t\t<string>ios</string>\n\t\t\t<key>SupportedPlatformVariant</key>\n\t\t\t<string>simulator</string>\n\t\t</dict>\n\t</array>\n\t<key>CFBundlePackageType</key>\n\t<string>XFWK</string>\n\t<key>XCFrameworkFormatVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/Info.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>CFBundleExecutable</key>\n\t<string>GoogleAppMeasurement</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.firebase.Firebase-GoogleAppMeasurement</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>GoogleAppMeasurement</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleVersion</key>\n\t<string>8.3.0</string>\n\t<key>DTSDKName</key>\n\t<string>iphonesimulator11.2</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/Modules/module.modulemap",
    "content": "framework module GoogleAppMeasurement {\numbrella header \"GoogleAppMeasurement-umbrella.h\"\nexport *\nmodule * { export * }\n  link framework \"Security\"\n  link framework \"SystemConfiguration\"\n  link \"c++\"\n  link \"sqlite3\"\n  link \"z\"\n}\n"
  },
  {
    "path": "Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_i386_x86_64-simulator/GoogleAppMeasurement.framework/Info.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>CFBundleExecutable</key>\n\t<string>GoogleAppMeasurement</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.firebase.Firebase-GoogleAppMeasurement</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>GoogleAppMeasurement</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleVersion</key>\n\t<string>8.3.0</string>\n\t<key>DTSDKName</key>\n\t<string>iphonesimulator11.2</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_i386_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap",
    "content": "framework module GoogleAppMeasurement {\numbrella header \"GoogleAppMeasurement-umbrella.h\"\nexport *\nmodule * { export * }\n  link framework \"Security\"\n  link framework \"SystemConfiguration\"\n  link \"c++\"\n  link \"sqlite3\"\n  link \"z\"\n}\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/GDTCCTCompressionHelper.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTCompressionHelper.h\"\n\n#import <zlib.h>\n\n@implementation GDTCCTCompressionHelper\n\n+ (nullable NSData *)gzippedData:(NSData *)data {\n#if defined(__LP64__) && __LP64__\n  // Don't support > 32bit length for 64 bit, see note in header.\n  if (data.length > UINT_MAX) {\n    return nil;\n  }\n#endif\n\n  enum { kChunkSize = 1024 };\n\n  const void *bytes = [data bytes];\n  NSUInteger length = [data length];\n\n  int level = Z_DEFAULT_COMPRESSION;\n  if (!bytes || !length) {\n    return nil;\n  }\n\n  z_stream strm;\n  bzero(&strm, sizeof(z_stream));\n\n  int memLevel = 8;          // Default.\n  int windowBits = 15 + 16;  // Enable gzip header instead of zlib header.\n\n  int retCode;\n  if (deflateInit2(&strm, level, Z_DEFLATED, windowBits, memLevel, Z_DEFAULT_STRATEGY) != Z_OK) {\n    return nil;\n  }\n\n  // Hint the size at 1/4 the input size.\n  NSMutableData *result = [NSMutableData dataWithCapacity:(length / 4)];\n  unsigned char output[kChunkSize];\n\n  // Setup the input.\n  strm.avail_in = (unsigned int)length;\n  strm.next_in = (unsigned char *)bytes;\n\n  // Collect the data.\n  do {\n    // update what we're passing in\n    strm.avail_out = kChunkSize;\n    strm.next_out = output;\n    retCode = deflate(&strm, Z_FINISH);\n    if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {\n      deflateEnd(&strm);\n      return nil;\n    }\n    // Collect what we got.\n    unsigned gotBack = kChunkSize - strm.avail_out;\n    if (gotBack > 0) {\n      [result appendBytes:output length:gotBack];\n    }\n\n  } while (retCode == Z_OK);\n\n  // If the loop exits, it used all input and the stream ended.\n  NSAssert(strm.avail_in == 0,\n           @\"Should have finished deflating without using all input, %u bytes left\", strm.avail_in);\n  NSAssert(retCode == Z_STREAM_END,\n           @\"thought we finished deflate w/o getting a result of stream end, code %d\", retCode);\n\n  // Clean up.\n  deflateEnd(&strm);\n\n  return result;\n}\n\n+ (BOOL)isGzipped:(NSData *)data {\n  const UInt8 *bytes = (const UInt8 *)data.bytes;\n  return (data.length >= 2 && bytes[0] == 0x1f && bytes[1] == 0x8b);\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/GDTCCTNanopbHelpers.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h\"\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n#import <UIKit/UIKit.h>\n#elif TARGET_OS_OSX\n#import <AppKit/AppKit.h>\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import <nanopb/pb.h>\n#import <nanopb/pb_decode.h>\n#import <nanopb/pb_encode.h>\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h\"\n\n#pragma mark - General purpose encoders\n\npb_bytes_array_t *GDTCCTEncodeString(NSString *string) {\n  NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding];\n  return GDTCCTEncodeData(stringBytes);\n}\n\npb_bytes_array_t *GDTCCTEncodeData(NSData *data) {\n  pb_bytes_array_t *pbBytesArray = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(data.length));\n  if (pbBytesArray != NULL) {\n    [data getBytes:pbBytesArray->bytes length:data.length];\n    pbBytesArray->size = (pb_size_t)data.length;\n  }\n  return pbBytesArray;\n}\n\n#pragma mark - CCT object constructors\n\nNSData *_Nullable GDTCCTEncodeBatchedLogRequest(gdt_cct_BatchedLogRequest *batchedLogRequest) {\n  pb_ostream_t sizestream = PB_OSTREAM_SIZING;\n  // Encode 1 time to determine the size.\n  if (!pb_encode(&sizestream, gdt_cct_BatchedLogRequest_fields, batchedLogRequest)) {\n    GDTCORLogError(GDTCORMCEGeneralError, @\"Error in nanopb encoding for size: %s\",\n                   PB_GET_ERROR(&sizestream));\n  }\n\n  // Encode a 2nd time to actually get the bytes from it.\n  size_t bufferSize = sizestream.bytes_written;\n  CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);\n  CFDataSetLength(dataRef, bufferSize);\n  pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);\n  if (!pb_encode(&ostream, gdt_cct_BatchedLogRequest_fields, batchedLogRequest)) {\n    GDTCORLogError(GDTCORMCEGeneralError, @\"Error in nanopb encoding for bytes: %s\",\n                   PB_GET_ERROR(&ostream));\n  }\n\n  return CFBridgingRelease(dataRef);\n}\n\ngdt_cct_BatchedLogRequest GDTCCTConstructBatchedLogRequest(\n    NSDictionary<NSString *, NSSet<GDTCOREvent *> *> *logMappingIDToLogSet) {\n  gdt_cct_BatchedLogRequest batchedLogRequest = gdt_cct_BatchedLogRequest_init_default;\n  NSUInteger numberOfLogRequests = logMappingIDToLogSet.count;\n  gdt_cct_LogRequest *logRequests = calloc(numberOfLogRequests, sizeof(gdt_cct_LogRequest));\n  if (logRequests == NULL) {\n    return batchedLogRequest;\n  }\n\n  __block int i = 0;\n  [logMappingIDToLogSet enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull logMappingID,\n                                                            NSSet<GDTCOREvent *> *_Nonnull logSet,\n                                                            BOOL *_Nonnull stop) {\n    int32_t logSource = [logMappingID intValue];\n    gdt_cct_LogRequest logRequest = GDTCCTConstructLogRequest(logSource, logSet);\n    logRequests[i] = logRequest;\n    i++;\n  }];\n\n  batchedLogRequest.log_request = logRequests;\n  batchedLogRequest.log_request_count = (pb_size_t)numberOfLogRequests;\n  return batchedLogRequest;\n}\n\ngdt_cct_LogRequest GDTCCTConstructLogRequest(int32_t logSource,\n                                             NSSet<GDTCOREvent *> *_Nonnull logSet) {\n  if (logSet.count == 0) {\n    GDTCORLogError(GDTCORMCEGeneralError, @\"%@\",\n                   @\"An empty event set can't be serialized to proto.\");\n    gdt_cct_LogRequest logRequest = gdt_cct_LogRequest_init_default;\n    return logRequest;\n  }\n  gdt_cct_LogRequest logRequest = gdt_cct_LogRequest_init_default;\n  logRequest.log_source = logSource;\n  logRequest.has_log_source = 1;\n  logRequest.client_info = GDTCCTConstructClientInfo();\n  logRequest.has_client_info = 1;\n  logRequest.log_event = calloc(logSet.count, sizeof(gdt_cct_LogEvent));\n  if (logRequest.log_event == NULL) {\n    return logRequest;\n  }\n  int i = 0;\n  for (GDTCOREvent *log in logSet) {\n    gdt_cct_LogEvent logEvent = GDTCCTConstructLogEvent(log);\n    logRequest.log_event[i] = logEvent;\n    i++;\n  }\n  logRequest.log_event_count = (pb_size_t)logSet.count;\n\n  GDTCORClock *currentTime = [GDTCORClock snapshot];\n  logRequest.request_time_ms = currentTime.timeMillis;\n  logRequest.has_request_time_ms = 1;\n  logRequest.request_uptime_ms = [currentTime uptimeMilliseconds];\n  logRequest.has_request_uptime_ms = 1;\n\n  return logRequest;\n}\n\ngdt_cct_LogEvent GDTCCTConstructLogEvent(GDTCOREvent *event) {\n  gdt_cct_LogEvent logEvent = gdt_cct_LogEvent_init_default;\n  logEvent.event_time_ms = event.clockSnapshot.timeMillis;\n  logEvent.has_event_time_ms = 1;\n  logEvent.event_uptime_ms = [event.clockSnapshot uptimeMilliseconds];\n  logEvent.has_event_uptime_ms = 1;\n  logEvent.timezone_offset_seconds = event.clockSnapshot.timezoneOffsetSeconds;\n  logEvent.has_timezone_offset_seconds = 1;\n  if (event.customBytes) {\n    NSData *networkConnectionInfoData = event.networkConnectionInfoData;\n    if (networkConnectionInfoData) {\n      [networkConnectionInfoData getBytes:&logEvent.network_connection_info\n                                   length:networkConnectionInfoData.length];\n      logEvent.has_network_connection_info = 1;\n    }\n    NSNumber *eventCode = event.eventCode;\n    if (eventCode != nil) {\n      logEvent.has_event_code = 1;\n      logEvent.event_code = [eventCode intValue];\n    }\n  }\n  NSError *error;\n  NSData *extensionBytes;\n  extensionBytes = event.serializedDataObjectBytes;\n  if (error) {\n    GDTCORLogWarning(GDTCORMCWFileReadError,\n                     @\"There was an error reading extension bytes from disk: %@\", error);\n    return logEvent;\n  }\n  logEvent.source_extension = GDTCCTEncodeData(extensionBytes);  // read bytes from the file.\n  return logEvent;\n}\n\ngdt_cct_ClientInfo GDTCCTConstructClientInfo() {\n  gdt_cct_ClientInfo clientInfo = gdt_cct_ClientInfo_init_default;\n  clientInfo.client_type = gdt_cct_ClientInfo_ClientType_IOS_FIREBASE;\n  clientInfo.has_client_type = 1;\n#if TARGET_OS_IOS || TARGET_OS_TV\n  clientInfo.ios_client_info = GDTCCTConstructiOSClientInfo();\n  clientInfo.has_ios_client_info = 1;\n#elif TARGET_OS_OSX\n  // TODO(mikehaney24): Expand the proto to include macOS client info.\n#endif\n  return clientInfo;\n}\n\ngdt_cct_IosClientInfo GDTCCTConstructiOSClientInfo() {\n  gdt_cct_IosClientInfo iOSClientInfo = gdt_cct_IosClientInfo_init_default;\n#if TARGET_OS_IOS || TARGET_OS_TV\n  UIDevice *device = [UIDevice currentDevice];\n  NSBundle *bundle = [NSBundle mainBundle];\n  NSLocale *locale = [NSLocale currentLocale];\n  iOSClientInfo.os_full_version = GDTCCTEncodeString(device.systemVersion);\n  NSArray *versionComponents = [device.systemVersion componentsSeparatedByString:@\".\"];\n  iOSClientInfo.os_major_version = GDTCCTEncodeString(versionComponents[0]);\n  NSString *version = [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];\n  if (version) {\n    iOSClientInfo.application_build = GDTCCTEncodeString(version);\n  }\n  NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];\n  if (countryCode) {\n    iOSClientInfo.country = GDTCCTEncodeString([locale objectForKey:NSLocaleCountryCode]);\n  }\n  iOSClientInfo.model = GDTCCTEncodeString(GDTCORDeviceModel());\n  NSString *languageCode = bundle.preferredLocalizations.firstObject;\n  iOSClientInfo.language_code =\n      languageCode ? GDTCCTEncodeString(languageCode) : GDTCCTEncodeString(@\"en\");\n  iOSClientInfo.application_bundle_id = GDTCCTEncodeString(bundle.bundleIdentifier);\n#endif\n  return iOSClientInfo;\n}\n\nNSData *GDTCCTConstructNetworkConnectionInfoData() {\n  gdt_cct_NetworkConnectionInfo networkConnectionInfo = gdt_cct_NetworkConnectionInfo_init_default;\n  NSInteger currentNetworkType = GDTCORNetworkTypeMessage();\n  if (currentNetworkType) {\n    networkConnectionInfo.has_network_type = 1;\n    if (currentNetworkType == GDTCORNetworkTypeMobile) {\n      networkConnectionInfo.network_type = gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE;\n      networkConnectionInfo.mobile_subtype = GDTCCTNetworkConnectionInfoNetworkMobileSubtype();\n      if (networkConnectionInfo.mobile_subtype !=\n          gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE) {\n        networkConnectionInfo.has_mobile_subtype = 1;\n      }\n    } else {\n      networkConnectionInfo.network_type = gdt_cct_NetworkConnectionInfo_NetworkType_WIFI;\n    }\n  }\n  NSData *networkConnectionInfoData = [NSData dataWithBytes:&networkConnectionInfo\n                                                     length:sizeof(networkConnectionInfo)];\n  return networkConnectionInfoData;\n}\n\ngdt_cct_NetworkConnectionInfo_MobileSubtype GDTCCTNetworkConnectionInfoNetworkMobileSubtype() {\n  NSNumber *networkMobileSubtypeMessage = @(GDTCORNetworkMobileSubTypeMessage());\n  if (!networkMobileSubtypeMessage.intValue) {\n    return gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE;\n  }\n  static NSDictionary<NSNumber *, NSNumber *> *MessageToNetworkSubTypeMessage;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    MessageToNetworkSubTypeMessage = @{\n      @(GDTCORNetworkMobileSubtypeGPRS) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_GPRS),\n      @(GDTCORNetworkMobileSubtypeEdge) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_EDGE),\n      @(GDTCORNetworkMobileSubtypeWCDMA) :\n          @(gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE),\n      @(GDTCORNetworkMobileSubtypeHSDPA) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_HSDPA),\n      @(GDTCORNetworkMobileSubtypeHSUPA) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_HSUPA),\n      @(GDTCORNetworkMobileSubtypeCDMA1x) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_CDMA),\n      @(GDTCORNetworkMobileSubtypeCDMAEVDORev0) :\n          @(gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_0),\n      @(GDTCORNetworkMobileSubtypeCDMAEVDORevA) :\n          @(gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_A),\n      @(GDTCORNetworkMobileSubtypeCDMAEVDORevB) :\n          @(gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_B),\n      @(GDTCORNetworkMobileSubtypeHRPD) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_EHRPD),\n      @(GDTCORNetworkMobileSubtypeLTE) : @(gdt_cct_NetworkConnectionInfo_MobileSubtype_LTE),\n    };\n  });\n  NSNumber *networkMobileSubtype = MessageToNetworkSubTypeMessage[networkMobileSubtypeMessage];\n  return networkMobileSubtype.intValue;\n}\n\n#pragma mark - CCT Object decoders\n\ngdt_cct_LogResponse GDTCCTDecodeLogResponse(NSData *data, NSError **error) {\n  gdt_cct_LogResponse response = gdt_cct_LogResponse_init_default;\n  pb_istream_t istream = pb_istream_from_buffer([data bytes], [data length]);\n  if (!pb_decode(&istream, gdt_cct_LogResponse_fields, &response)) {\n    NSString *nanopb_error = [NSString stringWithFormat:@\"%s\", PB_GET_ERROR(&istream)];\n    NSDictionary *userInfo = @{@\"nanopb error:\" : nanopb_error};\n    if (error != NULL) {\n      *error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:userInfo];\n    }\n    response = (gdt_cct_LogResponse)gdt_cct_LogResponse_init_default;\n  }\n  return response;\n}\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/GDTCCTUploadOperation.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploadOperation.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadBatch.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import <nanopb/pb.h>\n#import <nanopb/pb_decode.h>\n#import <nanopb/pb_encode.h>\n\n#import <GoogleUtilities/GULURLSessionDataResponse.h>\n#import <GoogleUtilities/NSURLSession+GULPromises.h>\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTCompressionHelper.h\"\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h\"\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n#ifdef GDTCOR_VERSION\n#define STR(x) STR_EXPAND(x)\n#define STR_EXPAND(x) #x\nstatic NSString *const kGDTCCTSupportSDKVersion = @STR(GDTCOR_VERSION);\n#else\nstatic NSString *const kGDTCCTSupportSDKVersion = @\"UNKNOWN\";\n#endif  // GDTCOR_VERSION\n\ntypedef void (^GDTCCTUploaderURLTaskCompletion)(NSNumber *batchID,\n                                                NSSet<GDTCOREvent *> *_Nullable events,\n                                                NSData *_Nullable data,\n                                                NSURLResponse *_Nullable response,\n                                                NSError *_Nullable error);\n\ntypedef void (^GDTCCTUploaderEventBatchBlock)(NSNumber *_Nullable batchID,\n                                              NSSet<GDTCOREvent *> *_Nullable events);\n\n@interface GDTCCTUploadOperation () <NSURLSessionDelegate>\n\n/// The properties to store parameters passed in the initializer. See the initialized docs for\n/// details.\n@property(nonatomic, readonly) GDTCORTarget target;\n@property(nonatomic, readonly) GDTCORUploadConditions conditions;\n@property(nonatomic, readonly) NSURL *uploadURL;\n@property(nonatomic, readonly) id<GDTCORStoragePromiseProtocol> storage;\n@property(nonatomic, readonly) id<GDTCCTUploadMetadataProvider> metadataProvider;\n\n/** The URL session that will attempt upload. */\n@property(nonatomic) NSURLSession *uploaderSession;\n\n/// NSOperation state properties implementation.\n@property(nonatomic, readwrite, getter=isExecuting) BOOL executing;\n@property(nonatomic, readwrite, getter=isFinished) BOOL finished;\n\n@property(nonatomic, readwrite) BOOL uploadAttempted;\n\n@end\n\n@implementation GDTCCTUploadOperation\n\n- (instancetype)initWithTarget:(GDTCORTarget)target\n                    conditions:(GDTCORUploadConditions)conditions\n                     uploadURL:(NSURL *)uploadURL\n                         queue:(dispatch_queue_t)queue\n                       storage:(id<GDTCORStoragePromiseProtocol>)storage\n              metadataProvider:(id<GDTCCTUploadMetadataProvider>)metadataProvider {\n  self = [super init];\n  if (self) {\n    _uploaderQueue = queue;\n    _target = target;\n    _conditions = conditions;\n    _uploadURL = uploadURL;\n    _storage = storage;\n    _metadataProvider = metadataProvider;\n  }\n  return self;\n}\n\n- (NSURLSession *)uploaderSessionCreateIfNeeded {\n  if (_uploaderSession == nil) {\n    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];\n    _uploaderSession = [NSURLSession sessionWithConfiguration:config\n                                                     delegate:self\n                                                delegateQueue:nil];\n  }\n  return _uploaderSession;\n}\n\n- (void)uploadTarget:(GDTCORTarget)target withConditions:(GDTCORUploadConditions)conditions {\n  __block GDTCORBackgroundIdentifier backgroundTaskID = GDTCORBackgroundIdentifierInvalid;\n\n  dispatch_block_t backgroundTaskCompletion = ^{\n    // End the background task if there was one.\n    if (backgroundTaskID != GDTCORBackgroundIdentifierInvalid) {\n      [[GDTCORApplication sharedApplication] endBackgroundTask:backgroundTaskID];\n      backgroundTaskID = GDTCORBackgroundIdentifierInvalid;\n    }\n  };\n\n  backgroundTaskID = [[GDTCORApplication sharedApplication]\n      beginBackgroundTaskWithName:@\"GDTCCTUploader-upload\"\n                expirationHandler:^{\n                  if (backgroundTaskID != GDTCORBackgroundIdentifierInvalid) {\n                    // Cancel the upload and complete delivery.\n                    [self.currentTask cancel];\n\n                    // End the background task.\n                    backgroundTaskCompletion();\n                  }\n                }];\n\n  id<GDTCORStoragePromiseProtocol> storage = self.storage;\n\n  // 1. Check if the conditions for the target are suitable.\n  [self isReadyToUploadTarget:target conditions:conditions]\n      .thenOn(self.uploaderQueue,\n              ^id(id result) {\n                // 2. Remove previously attempted batches\n                return [storage removeAllBatchesForTarget:target deleteEvents:NO];\n              })\n      .thenOn(self.uploaderQueue,\n              ^FBLPromise<NSNumber *> *(id result) {\n                // There may be a big amount of events stored, so creating a batch may be an\n                // expensive operation.\n\n                // 3. Do a lightweight check if there are any events for the target first to\n                // finish early if there are no.\n                return [storage hasEventsForTarget:target];\n              })\n      .validateOn(self.uploaderQueue,\n                  ^BOOL(NSNumber *hasEvents) {\n                    // Stop operation if there are no events to upload.\n                    return hasEvents.boolValue;\n                  })\n      .thenOn(self.uploaderQueue,\n              ^FBLPromise<GDTCORUploadBatch *> *(id result) {\n                if (self.isCancelled) {\n                  return nil;\n                }\n\n                // 4. Fetch events to upload.\n                GDTCORStorageEventSelector *eventSelector = [self eventSelectorTarget:target\n                                                                       withConditions:conditions];\n                return [storage batchWithEventSelector:eventSelector\n                                       batchExpiration:[NSDate dateWithTimeIntervalSinceNow:600]];\n              })\n      .validateOn(self.uploaderQueue,\n                  ^BOOL(GDTCORUploadBatch *batch) {\n                    // 5. Validate batch.\n                    return batch.batchID != nil && batch.events.count > 0;\n                  })\n      .thenOn(self.uploaderQueue,\n              ^FBLPromise *(GDTCORUploadBatch *batch) {\n                // A non-empty batch has been created, consider it as an upload attempt.\n                self.uploadAttempted = YES;\n\n                // 6. Perform upload URL request.\n                return [self sendURLRequestWithBatch:batch target:target storage:storage];\n              })\n      .thenOn(self.uploaderQueue,\n              ^id(id result) {\n                // 7. Finish operation.\n                [self finishOperation];\n                backgroundTaskCompletion();\n                return nil;\n              })\n      .catchOn(self.uploaderQueue, ^(NSError *error) {\n        // TODO: Maybe report the error to the client.\n        [self finishOperation];\n        backgroundTaskCompletion();\n      });\n}\n\n#pragma mark - Upload implementation details\n\n/** Sends URL request to upload the provided batch and handle the response. */\n- (FBLPromise<NSNull *> *)sendURLRequestWithBatch:(GDTCORUploadBatch *)batch\n                                           target:(GDTCORTarget)target\n                                          storage:(id<GDTCORStoragePromiseProtocol>)storage {\n  NSNumber *batchID = batch.batchID;\n\n  // 1. Send URL request.\n  return [self sendURLRequestWithBatch:batch target:target]\n      .thenOn(\n          self.uploaderQueue,\n          ^FBLPromise<NSNull *> *(GULURLSessionDataResponse *response) {\n            // 2. Parse response and update the next upload time if can.\n            [self updateNextUploadTimeWithResponse:response forTarget:target];\n\n            // 3. Cleanup batch.\n\n            // Only retry if one of these codes is returned:\n            // 429 - Too many requests;\n            // 5xx - Server errors.\n            NSInteger statusCode = response.HTTPResponse.statusCode;\n            if (statusCode == 429 || (statusCode >= 500 && statusCode < 600)) {\n              // Move the events back to the main storage to be uploaded on the next attempt.\n              return [storage removeBatchWithID:batchID deleteEvents:NO];\n            } else {\n              if (statusCode >= 200 && statusCode <= 300) {\n                GDTCORLogDebug(@\"CCT: batch %@ delivered\", batchID);\n              } else {\n                GDTCORLogDebug(\n                    @\"CCT: batch %@ was rejected by the server and will be deleted with all events\",\n                    batchID);\n              }\n\n              // The events are either delivered or unrecoverable broken, so remove the batch with\n              // events.\n              return [storage removeBatchWithID:batch.batchID deleteEvents:YES];\n            }\n          })\n      .recoverOn(self.uploaderQueue, ^id(NSError *error) {\n        // In the case of a network error move the events back to the main storage to be uploaded on\n        // the next attempt.\n        return [storage removeBatchWithID:batchID deleteEvents:NO];\n      });\n}\n\n/** Composes and sends URL request. */\n- (FBLPromise<GULURLSessionDataResponse *> *)sendURLRequestWithBatch:(GDTCORUploadBatch *)batch\n                                                              target:(GDTCORTarget)target {\n  return [FBLPromise\n             onQueue:self.uploaderQueue\n                  do:^NSURLRequest * {\n                    // 1. Prepare URL request.\n                    NSData *requestProtoData = [self constructRequestProtoWithEvents:batch.events];\n                    NSData *gzippedData = [GDTCCTCompressionHelper gzippedData:requestProtoData];\n                    BOOL usingGzipData =\n                        gzippedData != nil && gzippedData.length < requestProtoData.length;\n                    NSData *dataToSend = usingGzipData ? gzippedData : requestProtoData;\n                    NSURLRequest *request = [self constructRequestWithURL:self.uploadURL\n                                                                forTarget:target\n                                                                     data:dataToSend];\n                    GDTCORLogDebug(@\"CTT: request containing %lu events for batch: %@ for target: \"\n                                   @\"%ld created: %@\",\n                                   (unsigned long)batch.events.count, batch.batchID, (long)target,\n                                   request);\n                    return request;\n                  }]\n      .thenOn(self.uploaderQueue,\n              ^FBLPromise<GULURLSessionDataResponse *> *(NSURLRequest *request) {\n                // 2. Send URL request.\n                return\n                    [[self uploaderSessionCreateIfNeeded] gul_dataTaskPromiseWithRequest:request];\n              })\n      .thenOn(self.uploaderQueue,\n              ^GULURLSessionDataResponse *(GULURLSessionDataResponse *response) {\n                // Invalidate session to release the delegate (which is `self`) to break the retain\n                // cycle.\n                [self.uploaderSession finishTasksAndInvalidate];\n                return response;\n              })\n      .recoverOn(self.uploaderQueue, ^id(NSError *error) {\n        // Invalidate session to release the delegate (which is `self`) to break the retain cycle.\n        [self.uploaderSession finishTasksAndInvalidate];\n        // Re-throw the error.\n        return error;\n      });\n}\n\n/** Parses server response and update next upload time for the specified target based on it. */\n- (void)updateNextUploadTimeWithResponse:(GULURLSessionDataResponse *)response\n                               forTarget:(GDTCORTarget)target {\n  GDTCORClock *futureUploadTime;\n  if (response.HTTPBody) {\n    NSError *decodingError;\n    gdt_cct_LogResponse logResponse = GDTCCTDecodeLogResponse(response.HTTPBody, &decodingError);\n    if (!decodingError && logResponse.has_next_request_wait_millis) {\n      GDTCORLogDebug(@\"CCT: The backend responded asking to not upload for %lld millis from now.\",\n                     logResponse.next_request_wait_millis);\n      futureUploadTime =\n          [GDTCORClock clockSnapshotInTheFuture:logResponse.next_request_wait_millis];\n    } else if (decodingError) {\n      GDTCORLogDebug(@\"There was a response decoding error: %@\", decodingError);\n    }\n    pb_release(gdt_cct_LogResponse_fields, &logResponse);\n  }\n\n  // If no futureUploadTime was parsed from the response body, then check\n  // [Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header.\n  if (!futureUploadTime) {\n    NSString *retryAfterHeader = response.HTTPResponse.allHeaderFields[@\"Retry-After\"];\n    if (retryAfterHeader.length > 0) {\n      NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];\n      formatter.numberStyle = NSNumberFormatterDecimalStyle;\n      NSNumber *retryAfterSeconds = [formatter numberFromString:retryAfterHeader];\n      if (retryAfterSeconds != nil) {\n        uint64_t retryAfterMillis = retryAfterSeconds.unsignedIntegerValue * 1000u;\n        futureUploadTime = [GDTCORClock clockSnapshotInTheFuture:retryAfterMillis];\n      }\n    }\n  }\n\n  if (!futureUploadTime) {\n    GDTCORLogDebug(@\"%@\", @\"CCT: The backend response failed to parse, so the next request \"\n                          @\"won't occur until 15 minutes from now\");\n    // 15 minutes from now.\n    futureUploadTime = [GDTCORClock clockSnapshotInTheFuture:15 * 60 * 1000];\n  }\n\n  [self.metadataProvider setNextUploadTime:futureUploadTime forTarget:target];\n}\n\n#pragma mark - Private helper methods\n\n/** @return A resolved promise if is ready and a rejected promise if not. */\n- (FBLPromise<NSNull *> *)isReadyToUploadTarget:(GDTCORTarget)target\n                                     conditions:(GDTCORUploadConditions)conditions {\n  FBLPromise<NSNull *> *promise = [FBLPromise pendingPromise];\n  if ([self readyToUploadTarget:target conditions:conditions]) {\n    [promise fulfill:[NSNull null]];\n  } else {\n    NSString *reason =\n        [NSString stringWithFormat:@\"Target %ld is not ready to upload with condition: %ld\",\n                                   (long)target, (long)conditions];\n    [promise reject:[self genericRejectedPromiseErrorWithReason:reason]];\n  }\n  return promise;\n}\n\n// TODO: Move to a separate class/extension/file when needed in other files.\n/** Returns an error object with the specified failure reason. */\n- (NSError *)genericRejectedPromiseErrorWithReason:(NSString *)reason {\n  return [NSError errorWithDomain:@\"GDTCCTUploader\"\n                             code:-1\n                         userInfo:@{NSLocalizedFailureReasonErrorKey : reason}];\n}\n\n/** Returns if the specified target is ready to be uploaded based on the specified conditions. */\n- (BOOL)readyToUploadTarget:(GDTCORTarget)target conditions:(GDTCORUploadConditions)conditions {\n  // Not ready to upload with no network connection.\n  // TODO: Reconsider using reachability to prevent an upload attempt.\n  // See https://developer.apple.com/videos/play/wwdc2019/712/ (49:40) for more details.\n  if (conditions & GDTCORUploadConditionNoNetwork) {\n    GDTCORLogDebug(@\"%@\", @\"CCT: Not ready to upload without a network connection.\");\n    return NO;\n  }\n\n  // Upload events with no additional conditions if high priority.\n  if ((conditions & GDTCORUploadConditionHighPriority) == GDTCORUploadConditionHighPriority) {\n    GDTCORLogDebug(@\"%@\", @\"CCT: a high priority event is allowing an upload\");\n    return YES;\n  }\n\n  // Check next upload time for the target.\n  BOOL isAfterNextUploadTime = YES;\n  GDTCORClock *nextUploadTime = [self.metadataProvider nextUploadTimeForTarget:target];\n  if (nextUploadTime) {\n    isAfterNextUploadTime = [[GDTCORClock snapshot] isAfter:nextUploadTime];\n  }\n\n  if (isAfterNextUploadTime) {\n    GDTCORLogDebug(@\"CCT: can upload to target %ld because the request wait time has transpired\",\n                   (long)target);\n  } else {\n    GDTCORLogDebug(@\"CCT: can't upload to target %ld because the backend asked to wait\",\n                   (long)target);\n  }\n\n  return isAfterNextUploadTime;\n}\n\n/** Constructs data given an upload package.\n *\n * @param events The events used to construct the request proto bytes.\n * @return Proto bytes representing a gdt_cct_LogRequest object.\n */\n- (nonnull NSData *)constructRequestProtoWithEvents:(NSSet<GDTCOREvent *> *)events {\n  // Segment the log events by log type.\n  NSMutableDictionary<NSString *, NSMutableSet<GDTCOREvent *> *> *logMappingIDToLogSet =\n      [[NSMutableDictionary alloc] init];\n  [events enumerateObjectsUsingBlock:^(GDTCOREvent *_Nonnull event, BOOL *_Nonnull stop) {\n    NSMutableSet *logSet = logMappingIDToLogSet[event.mappingID];\n    logSet = logSet ? logSet : [[NSMutableSet alloc] init];\n    [logSet addObject:event];\n    logMappingIDToLogSet[event.mappingID] = logSet;\n  }];\n\n  gdt_cct_BatchedLogRequest batchedLogRequest =\n      GDTCCTConstructBatchedLogRequest(logMappingIDToLogSet);\n\n  NSData *data = GDTCCTEncodeBatchedLogRequest(&batchedLogRequest);\n  pb_release(gdt_cct_BatchedLogRequest_fields, &batchedLogRequest);\n  return data ? data : [[NSData alloc] init];\n}\n\n/** Constructs a request to the given URL and target with the specified request body data.\n *\n * @param target The target backend to send the request to.\n * @param data The request body data.\n * @return A new NSURLRequest ready to be sent to FLL.\n */\n- (nullable NSURLRequest *)constructRequestWithURL:(NSURL *)URL\n                                         forTarget:(GDTCORTarget)target\n                                              data:(NSData *)data {\n  if (data == nil || data.length == 0) {\n    GDTCORLogDebug(@\"There was no data to construct a request for target %ld.\", (long)target);\n    return nil;\n  }\n\n  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];\n  NSString *targetString;\n  switch (target) {\n    case kGDTCORTargetCCT:\n      targetString = @\"cct\";\n      break;\n\n    case kGDTCORTargetFLL:\n      targetString = @\"fll\";\n      break;\n\n    case kGDTCORTargetCSH:\n      targetString = @\"csh\";\n      break;\n    case kGDTCORTargetINT:\n      targetString = @\"int\";\n      break;\n\n    default:\n      targetString = @\"unknown\";\n      break;\n  }\n  NSString *userAgent =\n      [NSString stringWithFormat:@\"datatransport/%@ %@support/%@ apple/\", kGDTCORVersion,\n                                 targetString, kGDTCCTSupportSDKVersion];\n\n  [request setValue:[self.metadataProvider APIKeyForTarget:target]\n      forHTTPHeaderField:@\"X-Goog-Api-Key\"];\n\n  if ([GDTCCTCompressionHelper isGzipped:data]) {\n    [request setValue:@\"gzip\" forHTTPHeaderField:@\"Content-Encoding\"];\n  }\n  [request setValue:@\"application/x-protobuf\" forHTTPHeaderField:@\"Content-Type\"];\n  [request setValue:@\"gzip\" forHTTPHeaderField:@\"Accept-Encoding\"];\n  [request setValue:userAgent forHTTPHeaderField:@\"User-Agent\"];\n  request.HTTPMethod = @\"POST\";\n  [request setHTTPBody:data];\n  return request;\n}\n\n/** Creates and returns a storage event selector for the specified target and conditions. */\n- (GDTCORStorageEventSelector *)eventSelectorTarget:(GDTCORTarget)target\n                                     withConditions:(GDTCORUploadConditions)conditions {\n  if ((conditions & GDTCORUploadConditionHighPriority) == GDTCORUploadConditionHighPriority) {\n    return [GDTCORStorageEventSelector eventSelectorForTarget:target];\n  }\n  NSMutableSet<NSNumber *> *qosTiers = [[NSMutableSet alloc] init];\n  if (conditions & GDTCORUploadConditionWifiData) {\n    [qosTiers addObjectsFromArray:@[\n      @(GDTCOREventQoSFast), @(GDTCOREventQoSWifiOnly), @(GDTCOREventQosDefault),\n      @(GDTCOREventQoSTelemetry), @(GDTCOREventQoSUnknown)\n    ]];\n  }\n  if (conditions & GDTCORUploadConditionMobileData) {\n    [qosTiers addObjectsFromArray:@[ @(GDTCOREventQoSFast), @(GDTCOREventQosDefault) ]];\n  }\n\n  return [[GDTCORStorageEventSelector alloc] initWithTarget:target\n                                                   eventIDs:nil\n                                                 mappingIDs:nil\n                                                   qosTiers:qosTiers];\n}\n\n#pragma mark - NSURLSessionDelegate\n\n- (void)URLSession:(NSURLSession *)session\n                          task:(NSURLSessionTask *)task\n    willPerformHTTPRedirection:(NSHTTPURLResponse *)response\n                    newRequest:(NSURLRequest *)request\n             completionHandler:(void (^)(NSURLRequest *_Nullable))completionHandler {\n  if (!completionHandler) {\n    return;\n  }\n  if (response.statusCode == 302 || response.statusCode == 301) {\n    NSURLRequest *newRequest = [self constructRequestWithURL:request.URL\n                                                   forTarget:kGDTCORTargetCCT\n                                                        data:task.originalRequest.HTTPBody];\n    completionHandler(newRequest);\n  } else {\n    completionHandler(request);\n  }\n}\n\n#pragma mark - NSOperation methods\n\n@synthesize executing = _executing;\n@synthesize finished = _finished;\n\n- (BOOL)isFinished {\n  @synchronized(self) {\n    return _finished;\n  }\n}\n\n- (BOOL)isExecuting {\n  @synchronized(self) {\n    return _executing;\n  }\n}\n\n- (BOOL)isAsynchronous {\n  return YES;\n}\n\n- (void)startOperation {\n  @synchronized(self) {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    [self willChangeValueForKey:@\"isFinished\"];\n    self->_executing = YES;\n    self->_finished = NO;\n    [self didChangeValueForKey:@\"isExecuting\"];\n    [self didChangeValueForKey:@\"isFinished\"];\n  }\n}\n\n- (void)finishOperation {\n  @synchronized(self) {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    [self willChangeValueForKey:@\"isFinished\"];\n    self->_executing = NO;\n    self->_finished = YES;\n    [self didChangeValueForKey:@\"isExecuting\"];\n    [self didChangeValueForKey:@\"isFinished\"];\n  }\n}\n\n- (void)main {\n  [self startOperation];\n\n  GDTCORLogDebug(@\"Upload operation started: %@\", self);\n  [self uploadTarget:self.target withConditions:self.conditions];\n}\n\n- (void)cancel {\n  @synchronized(self) {\n    [super cancel];\n\n    // If the operation hasn't been started we can set `isFinished = YES` straight away.\n    if (!_executing) {\n      _executing = NO;\n      _finished = YES;\n    }\n  }\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/GDTCCTUploader.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploader.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREndpoints.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploadOperation.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GDTCCTUploader () <NSURLSessionDelegate, GDTCCTUploadMetadataProvider>\n\n@property(nonatomic, readonly) NSOperationQueue *uploadOperationQueue;\n@property(nonatomic, readonly) dispatch_queue_t uploadQueue;\n\n@property(nonatomic, readonly)\n    NSMutableDictionary<NSNumber * /*GDTCORTarget*/, GDTCORClock *> *nextUploadTimeByTarget;\n\n@end\n\n@implementation GDTCCTUploader\n\nstatic NSURL *_testServerURL = nil;\n\n+ (void)load {\n  GDTCCTUploader *uploader = [GDTCCTUploader sharedInstance];\n  [[GDTCORRegistrar sharedInstance] registerUploader:uploader target:kGDTCORTargetCCT];\n  [[GDTCORRegistrar sharedInstance] registerUploader:uploader target:kGDTCORTargetFLL];\n  [[GDTCORRegistrar sharedInstance] registerUploader:uploader target:kGDTCORTargetCSH];\n  [[GDTCORRegistrar sharedInstance] registerUploader:uploader target:kGDTCORTargetINT];\n}\n\n+ (instancetype)sharedInstance {\n  static GDTCCTUploader *sharedInstance;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[GDTCCTUploader alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _uploadQueue = dispatch_queue_create(\"com.google.GDTCCTUploader\", DISPATCH_QUEUE_SERIAL);\n    _uploadOperationQueue = [[NSOperationQueue alloc] init];\n    _uploadOperationQueue.maxConcurrentOperationCount = 1;\n    _nextUploadTimeByTarget = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n- (void)uploadTarget:(GDTCORTarget)target withConditions:(GDTCORUploadConditions)conditions {\n  // Current GDTCCTUploader expected behaviour:\n  // 1. Accept multiple upload request\n  // 2. Verify if there are events eligible for upload and start upload for the first suitable\n  // target\n  // 3. Ignore other requests while an upload is in-progress.\n\n  // TODO: Revisit expected behaviour.\n  // Potentially better option:\n  // 1. Accept and enqueue all upload requests\n  // 2. Notify the client of upload stages\n  // 3. Allow the client cancelling upload requests as needed.\n\n  id<GDTCORStoragePromiseProtocol> storage = GDTCORStoragePromiseInstanceForTarget(target);\n  if (storage == nil) {\n    GDTCORLogError(GDTCORMCEGeneralError,\n                   @\"Failed to upload target: %ld - could not find corresponding storage instance.\",\n                   (long)target);\n    return;\n  }\n\n  GDTCCTUploadOperation *uploadOperation =\n      [[GDTCCTUploadOperation alloc] initWithTarget:target\n                                         conditions:conditions\n                                          uploadURL:[[self class] serverURLForTarget:target]\n                                              queue:self.uploadQueue\n                                            storage:storage\n                                   metadataProvider:self];\n\n  GDTCORLogDebug(@\"Upload operation created: %@, target: %@\", uploadOperation, @(target));\n\n  __weak __auto_type weakSelf = self;\n  __weak GDTCCTUploadOperation *weakOperation = uploadOperation;\n  uploadOperation.completionBlock = ^{\n    __auto_type strongSelf = weakSelf;\n    GDTCCTUploadOperation *strongOperation = weakOperation;\n    if (strongSelf == nil || strongOperation == nil) {\n      GDTCORLogDebug(@\"Internal inconsistency: GDTCCTUploader was deallocated during upload.\", nil);\n      return;\n    }\n\n    GDTCORLogDebug(@\"Upload operation finished: %@, uploadAttempted: %@\", strongOperation,\n                   @(strongOperation.uploadAttempted));\n\n    if (strongOperation.uploadAttempted) {\n      // Ignore all upload requests received when the upload was in progress.\n      [strongSelf.uploadOperationQueue cancelAllOperations];\n    }\n  };\n\n  [self.uploadOperationQueue addOperation:uploadOperation];\n  GDTCORLogDebug(@\"Upload operation scheduled: %@, operation count: %@\", uploadOperation,\n                 @(self.uploadOperationQueue.operationCount));\n}\n\n#pragma mark - URLs\n\n+ (void)setTestServerURL:(NSURL *_Nullable)serverURL {\n  _testServerURL = serverURL;\n}\n\n+ (NSURL *_Nullable)testServerURL {\n  return _testServerURL;\n}\n\n+ (nullable NSURL *)serverURLForTarget:(GDTCORTarget)target {\n#if !NDEBUG\n  if (_testServerURL) {\n    return _testServerURL;\n  }\n#endif  // !NDEBUG\n\n  return [GDTCOREndpoints uploadURLForTarget:target];\n}\n\n- (NSString *)FLLAndCSHAndINTAPIKey {\n  static NSString *defaultServerKey;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    // These strings should be interleaved to construct the real key.\n    const char *p1 = \"AzSBG0honD6A-PxV5nBc\";\n    const char *p2 = \"Iay44Iwtu2vV0AOrz1C\";\n    const char defaultKey[40] = {p1[0],  p2[0],  p1[1],  p2[1],  p1[2],  p2[2],  p1[3],  p2[3],\n                                 p1[4],  p2[4],  p1[5],  p2[5],  p1[6],  p2[6],  p1[7],  p2[7],\n                                 p1[8],  p2[8],  p1[9],  p2[9],  p1[10], p2[10], p1[11], p2[11],\n                                 p1[12], p2[12], p1[13], p2[13], p1[14], p2[14], p1[15], p2[15],\n                                 p1[16], p2[16], p1[17], p2[17], p1[18], p2[18], p1[19], '\\0'};\n    defaultServerKey = [NSString stringWithUTF8String:defaultKey];\n  });\n  return defaultServerKey;\n}\n\n#pragma mark - GDTCCTUploadMetadataProvider\n\n- (nullable GDTCORClock *)nextUploadTimeForTarget:(GDTCORTarget)target {\n  @synchronized(self.nextUploadTimeByTarget) {\n    return self.nextUploadTimeByTarget[@(target)];\n  }\n}\n\n- (void)setNextUploadTime:(nullable GDTCORClock *)time forTarget:(GDTCORTarget)target {\n  @synchronized(self.nextUploadTimeByTarget) {\n    self.nextUploadTimeByTarget[@(target)] = time;\n  }\n}\n\n- (nullable NSString *)APIKeyForTarget:(GDTCORTarget)target {\n  if (target == kGDTCORTargetFLL || target == kGDTCORTargetCSH) {\n    return [self FLLAndCSHAndINTAPIKey];\n  }\n\n  if (target == kGDTCORTargetINT) {\n    return [self FLLAndCSHAndINTAPIKey];\n  }\n\n  return nil;\n}\n\n#if !NDEBUG\n\n- (BOOL)waitForUploadFinishedWithTimeout:(NSTimeInterval)timeout {\n  NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:timeout];\n  while ([expirationDate compare:[NSDate date]] == NSOrderedDescending) {\n    if (self.uploadOperationQueue.operationCount == 0) {\n      return YES;\n    } else {\n      [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n    }\n  }\n\n  GDTCORLogDebug(@\"Uploader wait for finish timeout exceeded. Operations still in queue: %@\",\n                 self.uploadOperationQueue.operations);\n  return NO;\n}\n\n#endif  // !NDEBUG\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/GDTCOREvent+GDTCCTSupport.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\nNSString *const GDTCCTNeedsNetworkConnectionInfo = @\"needs_network_connection_info\";\n\nNSString *const GDTCCTNetworkConnectionInfo = @\"network_connection_info\";\n\nNSString *const GDTCCTEventCodeInfo = @\"event_code_info\";\n\n@implementation GDTCOREvent (GDTCCTSupport)\n\n- (void)setNeedsNetworkConnectionInfoPopulated:(BOOL)needsNetworkConnectionInfoPopulated {\n  if (!needsNetworkConnectionInfoPopulated) {\n    if (!self.customBytes) {\n      return;\n    }\n\n    // Make sure we don't destroy the eventCode data, if any is present.\n    @try {\n      NSError *error;\n      NSMutableDictionary *bytesDict =\n          [[NSJSONSerialization JSONObjectWithData:self.customBytes options:0\n                                             error:&error] mutableCopy];\n      if (error) {\n        GDTCORLogDebug(@\"Error when setting an event's event_code: %@\", error);\n        return;\n      }\n      NSNumber *eventCode = bytesDict[GDTCCTEventCodeInfo];\n      if (eventCode != nil) {\n        self.customBytes =\n            [NSJSONSerialization dataWithJSONObject:@{GDTCCTEventCodeInfo : eventCode}\n                                            options:0\n                                              error:&error];\n      }\n    } @catch (NSException *exception) {\n      GDTCORLogDebug(@\"Error when setting the event for needs_network_connection_info: %@\",\n                     exception);\n    }\n  } else {\n    @try {\n      NSError *error;\n      NSMutableDictionary *bytesDict;\n      if (self.customBytes) {\n        bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                     options:0\n                                                       error:&error] mutableCopy];\n        if (error) {\n          GDTCORLogDebug(@\"Error when setting an even'ts event_code: %@\", error);\n          return;\n        }\n      } else {\n        bytesDict = [[NSMutableDictionary alloc] init];\n      }\n      [bytesDict setObject:@YES forKey:GDTCCTNeedsNetworkConnectionInfo];\n      self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];\n    } @catch (NSException *exception) {\n      GDTCORLogDebug(@\"Error when setting the event for needs_network_connection_info: %@\",\n                     exception);\n    }\n  }\n}\n\n- (BOOL)needsNetworkConnectionInfoPopulated {\n  if (self.customBytes) {\n    @try {\n      NSError *error;\n      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                                options:0\n                                                                  error:&error];\n      return bytesDict && !error && [bytesDict[GDTCCTNeedsNetworkConnectionInfo] boolValue];\n    } @catch (NSException *exception) {\n      GDTCORLogDebug(@\"Error when checking the event for needs_network_connection_info: %@\",\n                     exception);\n    }\n  }\n  return NO;\n}\n\n- (void)setNetworkConnectionInfoData:(NSData *)networkConnectionInfoData {\n  @try {\n    NSError *error;\n    NSString *dataString = [networkConnectionInfoData base64EncodedStringWithOptions:0];\n    if (dataString != nil) {\n      NSMutableDictionary *bytesDict;\n      if (self.customBytes) {\n        bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                     options:0\n                                                       error:&error] mutableCopy];\n        if (error) {\n          GDTCORLogDebug(@\"Error when setting an even'ts event_code: %@\", error);\n          return;\n        }\n      } else {\n        bytesDict = [[NSMutableDictionary alloc] init];\n      }\n      [bytesDict setObject:dataString forKey:GDTCCTNetworkConnectionInfo];\n      self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];\n      if (error) {\n        self.customBytes = nil;\n        GDTCORLogDebug(@\"Error when setting an event's network_connection_info: %@\", error);\n      }\n    }\n  } @catch (NSException *exception) {\n    GDTCORLogDebug(@\"Error when setting an event's network_connection_info: %@\", exception);\n  }\n}\n\n- (nullable NSData *)networkConnectionInfoData {\n  if (self.customBytes) {\n    @try {\n      NSError *error;\n      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                                options:0\n                                                                  error:&error];\n      NSString *base64Data = bytesDict[GDTCCTNetworkConnectionInfo];\n      if (base64Data == nil) {\n        return nil;\n      }\n\n      NSData *networkConnectionInfoData = [[NSData alloc] initWithBase64EncodedString:base64Data\n                                                                              options:0];\n      if (error) {\n        GDTCORLogDebug(@\"Error when getting an event's network_connection_info: %@\", error);\n        return nil;\n      } else {\n        return networkConnectionInfoData;\n      }\n    } @catch (NSException *exception) {\n      GDTCORLogDebug(@\"Error when getting an event's network_connection_info: %@\", exception);\n    }\n  }\n  return nil;\n}\n\n- (NSNumber *)eventCode {\n  if (self.customBytes) {\n    @try {\n      NSError *error;\n      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                                options:0\n                                                                  error:&error];\n      NSString *eventCodeString = bytesDict[GDTCCTEventCodeInfo];\n\n      if (!eventCodeString) {\n        return nil;\n      }\n\n      NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];\n      formatter.numberStyle = NSNumberFormatterDecimalStyle;\n      NSNumber *eventCode = [formatter numberFromString:eventCodeString];\n\n      if (error) {\n        GDTCORLogDebug(@\"Error when getting an event's network_connection_info: %@\", error);\n        return nil;\n      } else {\n        return eventCode;\n      }\n    } @catch (NSException *exception) {\n      GDTCORLogDebug(@\"Error when getting an event's event_code: %@\", exception);\n    }\n  }\n  return nil;\n}\n\n- (void)setEventCode:(NSNumber *)eventCode {\n  if (eventCode == nil) {\n    if (!self.customBytes) {\n      return;\n    }\n\n    NSError *error;\n    NSMutableDictionary *bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes\n                                                                      options:0\n                                                                        error:&error] mutableCopy];\n    if (error) {\n      GDTCORLogDebug(@\"Error when setting an event's event_code: %@\", error);\n      return;\n    }\n\n    [bytesDict removeObjectForKey:GDTCCTEventCodeInfo];\n    self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];\n    if (error) {\n      self.customBytes = nil;\n      GDTCORLogDebug(@\"Error when setting an event's event_code: %@\", error);\n      return;\n    }\n    return;\n  }\n\n  @try {\n    NSMutableDictionary *bytesDict;\n    NSError *error;\n    if (self.customBytes) {\n      bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes options:0\n                                                     error:&error] mutableCopy];\n      if (error) {\n        GDTCORLogDebug(@\"Error when setting an event's event_code: %@\", error);\n        return;\n      }\n    } else {\n      bytesDict = [[NSMutableDictionary alloc] init];\n    }\n\n    NSString *eventCodeString = [eventCode stringValue];\n    if (eventCodeString == nil) {\n      return;\n    }\n\n    [bytesDict setObject:eventCodeString forKey:GDTCCTEventCodeInfo];\n\n    self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];\n    if (error) {\n      self.customBytes = nil;\n      GDTCORLogDebug(@\"Error when setting an event's network_connection_info: %@\", error);\n      return;\n    }\n\n  } @catch (NSException *exception) {\n    GDTCORLogDebug(@\"Error when getting an event's network_connection_info: %@\", exception);\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTCompressionHelper.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A class with methods to help with gzipped data. */\n@interface GDTCCTCompressionHelper : NSObject\n\n/** Compresses the given data and returns a new data object.\n *\n * @note Reduced version from GULNSData+zlib.m of GoogleUtilities.\n * @return Compressed data, or nil if there was an error.\n */\n+ (nullable NSData *)gzippedData:(NSData *)data;\n\n/** Returns YES if the data looks like it was gzip compressed by checking for the gzip magic number.\n *\n * @note: From https://en.wikipedia.org/wiki/Gzip, gzip's magic number is 1f 8b.\n * @return YES if the data appears gzipped, NO otherwise.\n */\n+ (BOOL)isGzipped:(NSData *)data;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n#pragma mark - General purpose encoders\n\n/** Converts an NSString* to a pb_bytes_array_t*.\n *\n * @note calloc is called in this method. Ensure that pb_release is called on this or the parent.\n *\n * @param string The string to convert.\n * @return A newly allocated array of bytes representing the UTF8 encoding of the string.\n */\npb_bytes_array_t *GDTCCTEncodeString(NSString *string);\n\n/** Converts an NSData to a pb_bytes_array_t*.\n *\n * @note calloc is called in this method. Ensure that pb_release is called on this or the parent.\n *\n * @param data The data to convert.\n * @return A newly allocated array of bytes with [data bytes] copied into it.\n */\npb_bytes_array_t *GDTCCTEncodeData(NSData *data);\n\n#pragma mark - CCT object constructors\n\n/** Encodes a batched log request.\n *\n * @note Ensure that pb_release is called on the batchedLogRequest param.\n *\n * @param batchedLogRequest A pointer to the log batch to encode to bytes.\n * @return An NSData object representing the bytes of the log request batch.\n */\nFOUNDATION_EXPORT\nNSData *GDTCCTEncodeBatchedLogRequest(gdt_cct_BatchedLogRequest *batchedLogRequest);\n\n/** Constructs a gdt_cct_BatchedLogRequest given sets of events segemented by mapping ID.\n *\n * @note calloc is called in this method. Ensure that pb_release is called on this or the parent.\n *\n * @param logMappingIDToLogSet A map of mapping IDs to sets of events to convert into a batch.\n * @return A newly created gdt_cct_BatchedLogRequest.\n */\nFOUNDATION_EXPORT\ngdt_cct_BatchedLogRequest GDTCCTConstructBatchedLogRequest(\n    NSDictionary<NSString *, NSSet<GDTCOREvent *> *> *logMappingIDToLogSet);\n\n/** Constructs a log request given a log source and a set of events.\n *\n * @note calloc is called in this method. Ensure that pb_release is called on this or the parent.\n * @param logSource The CCT log source to put into the log request.\n * @param logSet The set of events to send in this log request.\n */\nFOUNDATION_EXPORT\ngdt_cct_LogRequest GDTCCTConstructLogRequest(int32_t logSource, NSSet<GDTCOREvent *> *logSet);\n\n/** Constructs a gdt_cct_LogEvent given a GDTCOREvent*.\n *\n * @param event The GDTCOREvent to convert.\n * @return The new gdt_cct_LogEvent object.\n */\nFOUNDATION_EXPORT\ngdt_cct_LogEvent GDTCCTConstructLogEvent(GDTCOREvent *event);\n\n/** Constructs a gdt_cct_ClientInfo representing the client device.\n *\n * @return The new gdt_cct_ClientInfo object.\n */\nFOUNDATION_EXPORT\ngdt_cct_ClientInfo GDTCCTConstructClientInfo(void);\n\n/** Constructs a gdt_cct_IosClientInfo representing the client device.\n *\n * @return The new gdt_cct_IosClientInfo object.\n */\nFOUNDATION_EXPORT\ngdt_cct_IosClientInfo GDTCCTConstructiOSClientInfo(void);\n\n/** Constructs the data of a gdt_cct_NetworkConnectionInfo representing the client nework connection\n * information.\n *\n * @return The data of a gdt_cct_NetworkConnectionInfo object.\n */\nFOUNDATION_EXPORT\nNSData *GDTCCTConstructNetworkConnectionInfoData(void);\n\n/** Return a gdt_cct_NetworkConnectionInfo_MobileSubtype representing the client\n *\n * @return The gdt_cct_NetworkConnectionInfo_MobileSubtype.\n */\nFOUNDATION_EXPORT\ngdt_cct_NetworkConnectionInfo_MobileSubtype GDTCCTNetworkConnectionInfoNetworkMobileSubtype(void);\n\n#pragma mark - CCT object decoders\n\n/** Decodes a gdt_cct_LogResponse given proto bytes.\n *\n * @note calloc is called in this method. Ensure that pb_release is called on the return value.\n *\n * @param data The proto bytes of the gdt_cct_LogResponse.\n * @param error An error that will be populated if something went wrong during decoding.\n * @return A newly allocated gdt_cct_LogResponse from the data, if the bytes decoded properly.\n */\nFOUNDATION_EXPORT\ngdt_cct_LogResponse GDTCCTDecodeLogResponse(NSData *data, NSError **error);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploadOperation.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORUploader.h\"\n\n@protocol GDTCORStoragePromiseProtocol;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The protocol defines methods to retrieve/update data shared between different upload operations.\n@protocol GDTCCTUploadMetadataProvider <NSObject>\n\n/** Returns a GDTCORClock object representing time after which a next upload attempt is allowed for\n * the specified target. Upload is allowed now if `nil`. */\n- (nullable GDTCORClock *)nextUploadTimeForTarget:(GDTCORTarget)target;\n\n/** Stores or resets time after which  a next upload attempt is allowed for the specified target. */\n- (void)setNextUploadTime:(nullable GDTCORClock *)time forTarget:(GDTCORTarget)target;\n\n/** Returns an API key for the specified target. */\n- (nullable NSString *)APIKeyForTarget:(GDTCORTarget)target;\n\n@end\n\n/** Class capable of uploading events to the CCT backend. */\n@interface GDTCCTUploadOperation : NSOperation\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** The designated initializer.\n *  @param target The events target to upload.\n *  @param conditions A set of upload conditions. The conditions affect the set of events to be\n * uploaded, e.g. events with some QoS are not uploaded on a cellular network, etc.\n *  @param uploadURL The backend URL to upload the events.\n *  @param queue A queue to dispatch async upload steps.\n *  @param storage A storage object to fetch events for upload.\n *  @param metadataProvider An object to retrieve/update data shared between different upload\n * operations.\n *  @return An instance of GDTCCTUploadOperation ready to be added to an NSOperationQueue.\n */\n- (instancetype)initWithTarget:(GDTCORTarget)target\n                    conditions:(GDTCORUploadConditions)conditions\n                     uploadURL:(NSURL *)uploadURL\n                         queue:(dispatch_queue_t)queue\n                       storage:(id<GDTCORStoragePromiseProtocol>)storage\n              metadataProvider:(id<GDTCCTUploadMetadataProvider>)metadataProvider\n    NS_DESIGNATED_INITIALIZER;\n\n/** YES if a batch upload attempt was performed. NO otherwise. If NO for the finished operation,\n * then  there were no events suitable for upload. */\n@property(nonatomic, readonly) BOOL uploadAttempted;\n\n/** The queue on which all CCT uploading will occur. */\n@property(nonatomic, readonly) dispatch_queue_t uploaderQueue;\n\n/** The current upload task. */\n@property(nullable, nonatomic, readonly) NSURLSessionUploadTask *currentTask;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploader.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORUploader.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Class capable of uploading events to the CCT backend. */\n@interface GDTCCTUploader : NSObject <GDTCORUploader>\n\n/** Creates and/or returns the singleton instance of this class.\n *\n * @return The singleton instance of this class.\n */\n+ (instancetype)sharedInstance;\n\n#if !NDEBUG\n/** An upload URL used across all targets. For testing only. */\n@property(class, nullable, nonatomic) NSURL *testServerURL;\n\n/** Spins runloop until upload finishes or timeout.\n *  @return YES if upload finishes, NO in the case of timeout.\n */\n- (BOOL)waitForUploadFinishedWithTimeout:(NSTimeInterval)timeout;\n\n#endif  // !NDEBUG\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.c",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Automatically generated nanopb constant definitions */\n/* Generated by nanopb-0.3.9.7 */\n\n#include \"GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h\"\n\n/* @@protoc_insertion_point(includes) */\n#if PB_PROTO_HEADER_VERSION != 30\n#error Regenerate this file with the current version of nanopb generator.\n#endif\n\nconst gdt_cct_NetworkConnectionInfo_NetworkType gdt_cct_NetworkConnectionInfo_network_type_default = gdt_cct_NetworkConnectionInfo_NetworkType_NONE;\nconst gdt_cct_NetworkConnectionInfo_MobileSubtype gdt_cct_NetworkConnectionInfo_mobile_subtype_default = gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE;\nconst gdt_cct_QosTierConfiguration_QosTier gdt_cct_LogRequest_qos_tier_default = gdt_cct_QosTierConfiguration_QosTier_DEFAULT;\nconst int32_t gdt_cct_QosTierConfiguration_log_source_default = 0;\n\n\nconst pb_field_t gdt_cct_LogEvent_fields[7] = {\n    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, gdt_cct_LogEvent, event_time_ms, event_time_ms, 0),\n    PB_FIELD(  6, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_LogEvent, source_extension, event_time_ms, 0),\n    PB_FIELD( 11, INT32   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogEvent, event_code, source_extension, 0),\n    PB_FIELD( 15, SINT64  , OPTIONAL, STATIC  , OTHER, gdt_cct_LogEvent, timezone_offset_seconds, event_code, 0),\n    PB_FIELD( 17, INT64   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogEvent, event_uptime_ms, timezone_offset_seconds, 0),\n    PB_FIELD( 23, MESSAGE , OPTIONAL, STATIC  , OTHER, gdt_cct_LogEvent, network_connection_info, event_uptime_ms, &gdt_cct_NetworkConnectionInfo_fields),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_NetworkConnectionInfo_fields[3] = {\n    PB_FIELD(  1, ENUM    , OPTIONAL, STATIC  , FIRST, gdt_cct_NetworkConnectionInfo, network_type, network_type, &gdt_cct_NetworkConnectionInfo_network_type_default),\n    PB_FIELD(  2, UENUM   , OPTIONAL, STATIC  , OTHER, gdt_cct_NetworkConnectionInfo, mobile_subtype, network_type, &gdt_cct_NetworkConnectionInfo_mobile_subtype_default),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_IosClientInfo_fields[8] = {\n    PB_FIELD(  3, BYTES   , OPTIONAL, POINTER , FIRST, gdt_cct_IosClientInfo, os_major_version, os_major_version, 0),\n    PB_FIELD(  4, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, os_full_version, os_major_version, 0),\n    PB_FIELD(  5, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, application_build, os_full_version, 0),\n    PB_FIELD(  6, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, country, application_build, 0),\n    PB_FIELD(  7, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, model, country, 0),\n    PB_FIELD(  8, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, language_code, model, 0),\n    PB_FIELD( 11, BYTES   , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, application_bundle_id, language_code, 0),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_ClientInfo_fields[3] = {\n    PB_FIELD(  1, UENUM   , OPTIONAL, STATIC  , FIRST, gdt_cct_ClientInfo, client_type, client_type, 0),\n    PB_FIELD(  4, MESSAGE , OPTIONAL, STATIC  , OTHER, gdt_cct_ClientInfo, ios_client_info, client_type, &gdt_cct_IosClientInfo_fields),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_BatchedLogRequest_fields[2] = {\n    PB_FIELD(  1, MESSAGE , REPEATED, POINTER , FIRST, gdt_cct_BatchedLogRequest, log_request, log_request, &gdt_cct_LogRequest_fields),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_LogRequest_fields[7] = {\n    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, gdt_cct_LogRequest, client_info, client_info, &gdt_cct_ClientInfo_fields),\n    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogRequest, log_source, client_info, 0),\n    PB_FIELD(  3, MESSAGE , REPEATED, POINTER , OTHER, gdt_cct_LogRequest, log_event, log_source, &gdt_cct_LogEvent_fields),\n    PB_FIELD(  4, INT64   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogRequest, request_time_ms, log_event, 0),\n    PB_FIELD(  8, INT64   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogRequest, request_uptime_ms, request_time_ms, 0),\n    PB_FIELD(  9, UENUM   , OPTIONAL, STATIC  , OTHER, gdt_cct_LogRequest, qos_tier, request_uptime_ms, &gdt_cct_LogRequest_qos_tier_default),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_QosTierConfiguration_fields[3] = {\n    PB_FIELD(  2, UENUM   , OPTIONAL, STATIC  , FIRST, gdt_cct_QosTierConfiguration, qos_tier, qos_tier, 0),\n    PB_FIELD(  3, INT32   , OPTIONAL, STATIC  , OTHER, gdt_cct_QosTierConfiguration, log_source, qos_tier, &gdt_cct_QosTierConfiguration_log_source_default),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_QosTiersOverride_fields[3] = {\n    PB_FIELD(  1, MESSAGE , REPEATED, POINTER , FIRST, gdt_cct_QosTiersOverride, qos_tier_configuration, qos_tier_configuration, &gdt_cct_QosTierConfiguration_fields),\n    PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, gdt_cct_QosTiersOverride, qos_tier_fingerprint, qos_tier_configuration, 0),\n    PB_LAST_FIELD\n};\n\nconst pb_field_t gdt_cct_LogResponse_fields[3] = {\n    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, gdt_cct_LogResponse, next_request_wait_millis, next_request_wait_millis, 0),\n    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, gdt_cct_LogResponse, qos_tier, next_request_wait_millis, &gdt_cct_QosTiersOverride_fields),\n    PB_LAST_FIELD\n};\n\n\n\n\n\n\n/* Check that field information fits in pb_field_t */\n#if !defined(PB_FIELD_32BIT)\n/* If you get an error here, it means that you need to define PB_FIELD_32BIT\n * compile-time option. You can do that in pb.h or on compiler command line.\n * \n * The reason you need to do this is that some of your messages contain tag\n * numbers or field sizes that are larger than what can fit in 8 or 16 bit\n * field descriptors.\n */\nPB_STATIC_ASSERT((pb_membersize(gdt_cct_LogEvent, network_connection_info) < 65536 && pb_membersize(gdt_cct_ClientInfo, ios_client_info) < 65536 && pb_membersize(gdt_cct_LogRequest, client_info) < 65536 && pb_membersize(gdt_cct_LogResponse, qos_tier) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_gdt_cct_LogEvent_gdt_cct_NetworkConnectionInfo_gdt_cct_IosClientInfo_gdt_cct_ClientInfo_gdt_cct_BatchedLogRequest_gdt_cct_LogRequest_gdt_cct_QosTierConfiguration_gdt_cct_QosTiersOverride_gdt_cct_LogResponse)\n#endif\n\n#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n/* If you get an error here, it means that you need to define PB_FIELD_16BIT\n * compile-time option. You can do that in pb.h or on compiler command line.\n * \n * The reason you need to do this is that some of your messages contain tag\n * numbers or field sizes that are larger than what can fit in the default\n * 8 bit descriptors.\n */\nPB_STATIC_ASSERT((pb_membersize(gdt_cct_LogEvent, network_connection_info) < 256 && pb_membersize(gdt_cct_ClientInfo, ios_client_info) < 256 && pb_membersize(gdt_cct_LogRequest, client_info) < 256 && pb_membersize(gdt_cct_LogResponse, qos_tier) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_gdt_cct_LogEvent_gdt_cct_NetworkConnectionInfo_gdt_cct_IosClientInfo_gdt_cct_ClientInfo_gdt_cct_BatchedLogRequest_gdt_cct_LogRequest_gdt_cct_QosTierConfiguration_gdt_cct_QosTiersOverride_gdt_cct_LogResponse)\n#endif\n\n\n/* @@protoc_insertion_point(eof) */\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Automatically generated nanopb header */\n/* Generated by nanopb-0.3.9.7 */\n\n#ifndef PB_GDT_CCT_CCT_NANOPB_H_INCLUDED\n#define PB_GDT_CCT_CCT_NANOPB_H_INCLUDED\n#include <nanopb/pb.h>\n\n/* @@protoc_insertion_point(includes) */\n#if PB_PROTO_HEADER_VERSION != 30\n#error Regenerate this file with the current version of nanopb generator.\n#endif\n\n\n/* Enum definitions */\ntypedef enum _gdt_cct_NetworkConnectionInfo_NetworkType {\n    gdt_cct_NetworkConnectionInfo_NetworkType_NONE = -1,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE = 0,\n    gdt_cct_NetworkConnectionInfo_NetworkType_WIFI = 1,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_MMS = 2,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_SUPL = 3,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_DUN = 4,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_HIPRI = 5,\n    gdt_cct_NetworkConnectionInfo_NetworkType_WIMAX = 6,\n    gdt_cct_NetworkConnectionInfo_NetworkType_BLUETOOTH = 7,\n    gdt_cct_NetworkConnectionInfo_NetworkType_DUMMY = 8,\n    gdt_cct_NetworkConnectionInfo_NetworkType_ETHERNET = 9,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_FOTA = 10,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_IMS = 11,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_CBS = 12,\n    gdt_cct_NetworkConnectionInfo_NetworkType_WIFI_P2P = 13,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_IA = 14,\n    gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_EMERGENCY = 15,\n    gdt_cct_NetworkConnectionInfo_NetworkType_PROXY = 16,\n    gdt_cct_NetworkConnectionInfo_NetworkType_VPN = 17\n} gdt_cct_NetworkConnectionInfo_NetworkType;\n#define _gdt_cct_NetworkConnectionInfo_NetworkType_MIN gdt_cct_NetworkConnectionInfo_NetworkType_NONE\n#define _gdt_cct_NetworkConnectionInfo_NetworkType_MAX gdt_cct_NetworkConnectionInfo_NetworkType_VPN\n#define _gdt_cct_NetworkConnectionInfo_NetworkType_ARRAYSIZE ((gdt_cct_NetworkConnectionInfo_NetworkType)(gdt_cct_NetworkConnectionInfo_NetworkType_VPN+1))\n\ntypedef enum _gdt_cct_NetworkConnectionInfo_MobileSubtype {\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE = 0,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_GPRS = 1,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_EDGE = 2,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_UMTS = 3,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_CDMA = 4,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_0 = 5,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_A = 6,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_RTT = 7,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_HSDPA = 8,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_HSUPA = 9,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_HSPA = 10,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_IDEN = 11,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_B = 12,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_LTE = 13,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_EHRPD = 14,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_HSPAP = 15,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_GSM = 16,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_TD_SCDMA = 17,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_IWLAN = 18,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_LTE_CA = 19,\n    gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED = 100\n} gdt_cct_NetworkConnectionInfo_MobileSubtype;\n#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_MIN gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE\n#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_MAX gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED\n#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_ARRAYSIZE ((gdt_cct_NetworkConnectionInfo_MobileSubtype)(gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED+1))\n\ntypedef enum _gdt_cct_ClientInfo_ClientType {\n    gdt_cct_ClientInfo_ClientType_CLIENT_UNKNOWN = 0,\n    gdt_cct_ClientInfo_ClientType_IOS_FIREBASE = 15\n} gdt_cct_ClientInfo_ClientType;\n#define _gdt_cct_ClientInfo_ClientType_MIN gdt_cct_ClientInfo_ClientType_CLIENT_UNKNOWN\n#define _gdt_cct_ClientInfo_ClientType_MAX gdt_cct_ClientInfo_ClientType_IOS_FIREBASE\n#define _gdt_cct_ClientInfo_ClientType_ARRAYSIZE ((gdt_cct_ClientInfo_ClientType)(gdt_cct_ClientInfo_ClientType_IOS_FIREBASE+1))\n\ntypedef enum _gdt_cct_QosTierConfiguration_QosTier {\n    gdt_cct_QosTierConfiguration_QosTier_DEFAULT = 0,\n    gdt_cct_QosTierConfiguration_QosTier_UNMETERED_ONLY = 1,\n    gdt_cct_QosTierConfiguration_QosTier_UNMETERED_OR_DAILY = 2,\n    gdt_cct_QosTierConfiguration_QosTier_FAST_IF_RADIO_AWAKE = 3,\n    gdt_cct_QosTierConfiguration_QosTier_NEVER = 4\n} gdt_cct_QosTierConfiguration_QosTier;\n#define _gdt_cct_QosTierConfiguration_QosTier_MIN gdt_cct_QosTierConfiguration_QosTier_DEFAULT\n#define _gdt_cct_QosTierConfiguration_QosTier_MAX gdt_cct_QosTierConfiguration_QosTier_NEVER\n#define _gdt_cct_QosTierConfiguration_QosTier_ARRAYSIZE ((gdt_cct_QosTierConfiguration_QosTier)(gdt_cct_QosTierConfiguration_QosTier_NEVER+1))\n\n/* Struct definitions */\ntypedef struct _gdt_cct_BatchedLogRequest {\n    pb_size_t log_request_count;\n    struct _gdt_cct_LogRequest *log_request;\n/* @@protoc_insertion_point(struct:gdt_cct_BatchedLogRequest) */\n} gdt_cct_BatchedLogRequest;\n\ntypedef struct _gdt_cct_IosClientInfo {\n    pb_bytes_array_t *os_major_version;\n    pb_bytes_array_t *os_full_version;\n    pb_bytes_array_t *application_build;\n    pb_bytes_array_t *country;\n    pb_bytes_array_t *model;\n    pb_bytes_array_t *language_code;\n    pb_bytes_array_t *application_bundle_id;\n/* @@protoc_insertion_point(struct:gdt_cct_IosClientInfo) */\n} gdt_cct_IosClientInfo;\n\ntypedef struct _gdt_cct_ClientInfo {\n    bool has_client_type;\n    gdt_cct_ClientInfo_ClientType client_type;\n    bool has_ios_client_info;\n    gdt_cct_IosClientInfo ios_client_info;\n/* @@protoc_insertion_point(struct:gdt_cct_ClientInfo) */\n} gdt_cct_ClientInfo;\n\ntypedef struct _gdt_cct_NetworkConnectionInfo {\n    bool has_network_type;\n    gdt_cct_NetworkConnectionInfo_NetworkType network_type;\n    bool has_mobile_subtype;\n    gdt_cct_NetworkConnectionInfo_MobileSubtype mobile_subtype;\n/* @@protoc_insertion_point(struct:gdt_cct_NetworkConnectionInfo) */\n} gdt_cct_NetworkConnectionInfo;\n\ntypedef struct _gdt_cct_QosTierConfiguration {\n    bool has_qos_tier;\n    gdt_cct_QosTierConfiguration_QosTier qos_tier;\n    bool has_log_source;\n    int32_t log_source;\n/* @@protoc_insertion_point(struct:gdt_cct_QosTierConfiguration) */\n} gdt_cct_QosTierConfiguration;\n\ntypedef struct _gdt_cct_QosTiersOverride {\n    pb_size_t qos_tier_configuration_count;\n    struct _gdt_cct_QosTierConfiguration *qos_tier_configuration;\n    bool has_qos_tier_fingerprint;\n    int64_t qos_tier_fingerprint;\n/* @@protoc_insertion_point(struct:gdt_cct_QosTiersOverride) */\n} gdt_cct_QosTiersOverride;\n\ntypedef struct _gdt_cct_LogEvent {\n    bool has_event_time_ms;\n    int64_t event_time_ms;\n    pb_bytes_array_t *source_extension;\n    bool has_event_code;\n    int32_t event_code;\n    bool has_timezone_offset_seconds;\n    int64_t timezone_offset_seconds;\n    bool has_event_uptime_ms;\n    int64_t event_uptime_ms;\n    bool has_network_connection_info;\n    gdt_cct_NetworkConnectionInfo network_connection_info;\n/* @@protoc_insertion_point(struct:gdt_cct_LogEvent) */\n} gdt_cct_LogEvent;\n\ntypedef struct _gdt_cct_LogRequest {\n    bool has_client_info;\n    gdt_cct_ClientInfo client_info;\n    bool has_log_source;\n    int32_t log_source;\n    pb_size_t log_event_count;\n    struct _gdt_cct_LogEvent *log_event;\n    bool has_request_time_ms;\n    int64_t request_time_ms;\n    bool has_request_uptime_ms;\n    int64_t request_uptime_ms;\n    bool has_qos_tier;\n    gdt_cct_QosTierConfiguration_QosTier qos_tier;\n/* @@protoc_insertion_point(struct:gdt_cct_LogRequest) */\n} gdt_cct_LogRequest;\n\ntypedef struct _gdt_cct_LogResponse {\n    bool has_next_request_wait_millis;\n    int64_t next_request_wait_millis;\n    bool has_qos_tier;\n    gdt_cct_QosTiersOverride qos_tier;\n/* @@protoc_insertion_point(struct:gdt_cct_LogResponse) */\n} gdt_cct_LogResponse;\n\n/* Default values for struct fields */\nextern const gdt_cct_NetworkConnectionInfo_NetworkType gdt_cct_NetworkConnectionInfo_network_type_default;\nextern const gdt_cct_NetworkConnectionInfo_MobileSubtype gdt_cct_NetworkConnectionInfo_mobile_subtype_default;\nextern const gdt_cct_QosTierConfiguration_QosTier gdt_cct_LogRequest_qos_tier_default;\nextern const int32_t gdt_cct_QosTierConfiguration_log_source_default;\n\n/* Initializer values for message structs */\n#define gdt_cct_LogEvent_init_default            {false, 0, NULL, false, 0, false, 0, false, 0, false, gdt_cct_NetworkConnectionInfo_init_default}\n#define gdt_cct_NetworkConnectionInfo_init_default {false, gdt_cct_NetworkConnectionInfo_NetworkType_NONE, false, gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE}\n#define gdt_cct_IosClientInfo_init_default       {NULL, NULL, NULL, NULL, NULL, NULL, NULL}\n#define gdt_cct_ClientInfo_init_default          {false, _gdt_cct_ClientInfo_ClientType_MIN, false, gdt_cct_IosClientInfo_init_default}\n#define gdt_cct_BatchedLogRequest_init_default   {0, NULL}\n#define gdt_cct_LogRequest_init_default          {false, gdt_cct_ClientInfo_init_default, false, 0, 0, NULL, false, 0, false, 0, false, gdt_cct_QosTierConfiguration_QosTier_DEFAULT}\n#define gdt_cct_QosTierConfiguration_init_default {false, _gdt_cct_QosTierConfiguration_QosTier_MIN, false, 0}\n#define gdt_cct_QosTiersOverride_init_default    {0, NULL, false, 0}\n#define gdt_cct_LogResponse_init_default         {false, 0, false, gdt_cct_QosTiersOverride_init_default}\n#define gdt_cct_LogEvent_init_zero               {false, 0, NULL, false, 0, false, 0, false, 0, false, gdt_cct_NetworkConnectionInfo_init_zero}\n#define gdt_cct_NetworkConnectionInfo_init_zero  {false, _gdt_cct_NetworkConnectionInfo_NetworkType_MIN, false, _gdt_cct_NetworkConnectionInfo_MobileSubtype_MIN}\n#define gdt_cct_IosClientInfo_init_zero          {NULL, NULL, NULL, NULL, NULL, NULL, NULL}\n#define gdt_cct_ClientInfo_init_zero             {false, _gdt_cct_ClientInfo_ClientType_MIN, false, gdt_cct_IosClientInfo_init_zero}\n#define gdt_cct_BatchedLogRequest_init_zero      {0, NULL}\n#define gdt_cct_LogRequest_init_zero             {false, gdt_cct_ClientInfo_init_zero, false, 0, 0, NULL, false, 0, false, 0, false, _gdt_cct_QosTierConfiguration_QosTier_MIN}\n#define gdt_cct_QosTierConfiguration_init_zero   {false, _gdt_cct_QosTierConfiguration_QosTier_MIN, false, 0}\n#define gdt_cct_QosTiersOverride_init_zero       {0, NULL, false, 0}\n#define gdt_cct_LogResponse_init_zero            {false, 0, false, gdt_cct_QosTiersOverride_init_zero}\n\n/* Field tags (for use in manual encoding/decoding) */\n#define gdt_cct_BatchedLogRequest_log_request_tag 1\n#define gdt_cct_IosClientInfo_os_major_version_tag 3\n#define gdt_cct_IosClientInfo_os_full_version_tag 4\n#define gdt_cct_IosClientInfo_application_build_tag 5\n#define gdt_cct_IosClientInfo_country_tag        6\n#define gdt_cct_IosClientInfo_model_tag          7\n#define gdt_cct_IosClientInfo_language_code_tag  8\n#define gdt_cct_IosClientInfo_application_bundle_id_tag 11\n#define gdt_cct_ClientInfo_client_type_tag       1\n#define gdt_cct_ClientInfo_ios_client_info_tag   4\n#define gdt_cct_NetworkConnectionInfo_network_type_tag 1\n#define gdt_cct_NetworkConnectionInfo_mobile_subtype_tag 2\n#define gdt_cct_QosTierConfiguration_qos_tier_tag 2\n#define gdt_cct_QosTierConfiguration_log_source_tag 3\n#define gdt_cct_QosTiersOverride_qos_tier_configuration_tag 1\n#define gdt_cct_QosTiersOverride_qos_tier_fingerprint_tag 2\n#define gdt_cct_LogEvent_event_time_ms_tag       1\n#define gdt_cct_LogEvent_event_code_tag          11\n#define gdt_cct_LogEvent_event_uptime_ms_tag     17\n#define gdt_cct_LogEvent_source_extension_tag    6\n#define gdt_cct_LogEvent_timezone_offset_seconds_tag 15\n#define gdt_cct_LogEvent_network_connection_info_tag 23\n#define gdt_cct_LogRequest_request_time_ms_tag   4\n#define gdt_cct_LogRequest_request_uptime_ms_tag 8\n#define gdt_cct_LogRequest_client_info_tag       1\n#define gdt_cct_LogRequest_log_source_tag        2\n#define gdt_cct_LogRequest_log_event_tag         3\n#define gdt_cct_LogRequest_qos_tier_tag          9\n#define gdt_cct_LogResponse_next_request_wait_millis_tag 1\n#define gdt_cct_LogResponse_qos_tier_tag         3\n\n/* Struct field encoding specification for nanopb */\nextern const pb_field_t gdt_cct_LogEvent_fields[7];\nextern const pb_field_t gdt_cct_NetworkConnectionInfo_fields[3];\nextern const pb_field_t gdt_cct_IosClientInfo_fields[8];\nextern const pb_field_t gdt_cct_ClientInfo_fields[3];\nextern const pb_field_t gdt_cct_BatchedLogRequest_fields[2];\nextern const pb_field_t gdt_cct_LogRequest_fields[7];\nextern const pb_field_t gdt_cct_QosTierConfiguration_fields[3];\nextern const pb_field_t gdt_cct_QosTiersOverride_fields[3];\nextern const pb_field_t gdt_cct_LogResponse_fields[3];\n\n/* Maximum encoded size of messages (where known) */\n/* gdt_cct_LogEvent_size depends on runtime parameters */\n#define gdt_cct_NetworkConnectionInfo_size       13\n/* gdt_cct_IosClientInfo_size depends on runtime parameters */\n/* gdt_cct_ClientInfo_size depends on runtime parameters */\n/* gdt_cct_BatchedLogRequest_size depends on runtime parameters */\n/* gdt_cct_LogRequest_size depends on runtime parameters */\n#define gdt_cct_QosTierConfiguration_size        13\n/* gdt_cct_QosTiersOverride_size depends on runtime parameters */\n/* gdt_cct_LogResponse_size depends on runtime parameters */\n\n/* Message IDs (where set with \"msgid\" option) */\n#ifdef PB_MSGID\n\n#define CCT_MESSAGES \\\n\n\n#endif\n\n/* @@protoc_insertion_point(eof) */\n\n#endif\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A string sets in customBytes as a key paired to @YES if current event needs to\n * populate network connection info data, @NO otherwise.\n */\nFOUNDATION_EXPORT NSString *const GDTCCTNeedsNetworkConnectionInfo;\n\n/** A string sets in customBytes as a key paired to the network connection info data\n * of current event.\n */\nFOUNDATION_EXPORT NSString *const GDTCCTNetworkConnectionInfo;\n\n/** A category that uses the customBytes property of a GDTCOREvent to store network connection info.\n */\n@interface GDTCOREvent (GDTCCTSupport)\n\n/** If YES, needs the network connection info field set during prioritization.\n * @note Uses the GDTCOREvent customBytes property.\n */\n@property(nonatomic) BOOL needsNetworkConnectionInfoPopulated;\n\n/** The network connection info as collected at the time of the event.\n * @note Uses the GDTCOREvent customBytes property.\n */\n@property(nullable, nonatomic) NSData *networkConnectionInfoData;\n\n/** Code that identifies the event to be sent to the CCT backend.\n */\n@property(nullable, nonatomic) NSNumber *eventCode;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORAssert.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n\nGDTCORAssertionBlock GDTCORAssertionBlockToRunInstead(void) {\n  // This class is only compiled in by unit tests, and this should fail quickly in optimized builds.\n  Class GDTCORAssertClass = NSClassFromString(@\"GDTCORAssertHelper\");\n  if (__builtin_expect(!!GDTCORAssertClass, 0)) {\n    SEL assertionBlockSEL = NSSelectorFromString(@\"assertionBlock\");\n    if (assertionBlockSEL) {\n      IMP assertionBlockIMP = [GDTCORAssertClass methodForSelector:assertionBlockSEL];\n      if (assertionBlockIMP) {\n        GDTCORAssertionBlock assertionBlock =\n            ((GDTCORAssertionBlock(*)(id, SEL))assertionBlockIMP)(GDTCORAssertClass,\n                                                                  assertionBlockSEL);\n        if (assertionBlock) {\n          return assertionBlock;\n        }\n      }\n    }\n  }\n  return NULL;\n}\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORClock.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n\n#import <sys/sysctl.h>\n\n// Using a monotonic clock is necessary because CFAbsoluteTimeGetCurrent(), NSDate, and related all\n// are subject to drift. That it to say, multiple consecutive calls do not always result in a\n// time that is in the future. Clocks may be adjusted by the user, NTP, or any number of external\n// factors. This class attempts to determine the wall-clock time at the time of the event by\n// capturing the kernel start and time since boot to determine a wallclock time in UTC.\n//\n// Timezone offsets at the time of a snapshot are also captured in order to provide local-time\n// details. Other classes in this library depend on comparing times at some time in the future to\n// a time captured in the past, and this class needs to provide a mechanism to do that.\n//\n// TL;DR: This class attempts to accomplish two things: 1. Provide accurate event times. 2. Provide\n// a monotonic clock mechanism to accurately check if some clock snapshot was before or after\n// by using a shared reference point (kernel boot time).\n//\n// Note: Much of the mach time stuff doesn't work properly in the simulator. So this class can be\n// difficult to unit test.\n\n/** Returns the kernel boottime property from sysctl.\n *\n * Inspired by https://stackoverflow.com/a/40497811\n *\n * @return The KERN_BOOTTIME property from sysctl, in nanoseconds.\n */\nstatic int64_t KernelBootTimeInNanoseconds() {\n  // Caching the result is not possible because clock drift would not be accounted for.\n  struct timeval boottime;\n  int mib[2] = {CTL_KERN, KERN_BOOTTIME};\n  size_t size = sizeof(boottime);\n  int rc = sysctl(mib, 2, &boottime, &size, NULL, 0);\n  if (rc != 0) {\n    return 0;\n  }\n  return (int64_t)boottime.tv_sec * NSEC_PER_SEC + (int64_t)boottime.tv_usec * NSEC_PER_USEC;\n}\n\n/** Returns value of gettimeofday, in nanoseconds.\n *\n * Inspired by https://stackoverflow.com/a/40497811\n *\n * @return The value of gettimeofday, in nanoseconds.\n */\nstatic int64_t UptimeInNanoseconds() {\n  int64_t before_now_nsec;\n  int64_t after_now_nsec;\n  struct timeval now;\n\n  before_now_nsec = KernelBootTimeInNanoseconds();\n  // Addresses a race condition in which the system time has updated, but the boottime has not.\n  do {\n    gettimeofday(&now, NULL);\n    after_now_nsec = KernelBootTimeInNanoseconds();\n  } while (after_now_nsec != before_now_nsec);\n  return (int64_t)now.tv_sec * NSEC_PER_SEC + (int64_t)now.tv_usec * NSEC_PER_USEC -\n         before_now_nsec;\n}\n\n// TODO: Consider adding a 'trustedTime' property that can be populated by the response from a BE.\n@implementation GDTCORClock\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _kernelBootTimeNanoseconds = KernelBootTimeInNanoseconds();\n    _uptimeNanoseconds = UptimeInNanoseconds();\n    _timeMillis =\n        (int64_t)((CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) * NSEC_PER_USEC);\n    _timezoneOffsetSeconds = [[NSTimeZone systemTimeZone] secondsFromGMT];\n  }\n  return self;\n}\n\n+ (GDTCORClock *)snapshot {\n  return [[GDTCORClock alloc] init];\n}\n\n+ (instancetype)clockSnapshotInTheFuture:(uint64_t)millisInTheFuture {\n  GDTCORClock *snapshot = [self snapshot];\n  snapshot->_timeMillis += millisInTheFuture;\n  return snapshot;\n}\n\n- (BOOL)isAfter:(GDTCORClock *)otherClock {\n  // These clocks are trivially comparable when they share a kernel boot time.\n  if (_kernelBootTimeNanoseconds == otherClock->_kernelBootTimeNanoseconds) {\n    int64_t timeDiff = (_timeMillis + _timezoneOffsetSeconds) -\n                       (otherClock->_timeMillis + otherClock->_timezoneOffsetSeconds);\n    return timeDiff > 0;\n  } else {\n    int64_t kernelBootTimeDiff =\n        otherClock->_kernelBootTimeNanoseconds - _kernelBootTimeNanoseconds;\n    // This isn't a great solution, but essentially, if the other clock's boot time is 'later', NO\n    // is returned. This can be altered by changing the system time and rebooting.\n    return kernelBootTimeDiff < 0 ? YES : NO;\n  }\n}\n\n- (int64_t)uptimeMilliseconds {\n  return self.uptimeNanoseconds / NSEC_PER_MSEC;\n}\n\n- (NSUInteger)hash {\n  return [@(_kernelBootTimeNanoseconds) hash] ^ [@(_uptimeNanoseconds) hash] ^\n         [@(_timeMillis) hash] ^ [@(_timezoneOffsetSeconds) hash];\n}\n\n- (BOOL)isEqual:(id)object {\n  return [self hash] == [object hash];\n}\n\n#pragma mark - NSSecureCoding\n\n/** NSKeyedCoder key for timeMillis property. */\nstatic NSString *const kGDTCORClockTimeMillisKey = @\"GDTCORClockTimeMillis\";\n\n/** NSKeyedCoder key for timezoneOffsetMillis property. */\nstatic NSString *const kGDTCORClockTimezoneOffsetSeconds = @\"GDTCORClockTimezoneOffsetSeconds\";\n\n/** NSKeyedCoder key for _kernelBootTime ivar. */\nstatic NSString *const kGDTCORClockKernelBootTime = @\"GDTCORClockKernelBootTime\";\n\n/** NSKeyedCoder key for _uptimeNanoseconds ivar. */\nstatic NSString *const kGDTCORClockUptime = @\"GDTCORClockUptime\";\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n- (instancetype)initWithCoder:(NSCoder *)aDecoder {\n  self = [super init];\n  if (self) {\n    // TODO: If the kernelBootTimeNanoseconds is more recent, we need to change the kernel boot time\n    // and uptimeMillis ivars\n    _timeMillis = [aDecoder decodeInt64ForKey:kGDTCORClockTimeMillisKey];\n    _timezoneOffsetSeconds = [aDecoder decodeInt64ForKey:kGDTCORClockTimezoneOffsetSeconds];\n    _kernelBootTimeNanoseconds = [aDecoder decodeInt64ForKey:kGDTCORClockKernelBootTime];\n    _uptimeNanoseconds = [aDecoder decodeInt64ForKey:kGDTCORClockUptime];\n  }\n  return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)aCoder {\n  [aCoder encodeInt64:_timeMillis forKey:kGDTCORClockTimeMillisKey];\n  [aCoder encodeInt64:_timezoneOffsetSeconds forKey:kGDTCORClockTimezoneOffsetSeconds];\n  [aCoder encodeInt64:_kernelBootTimeNanoseconds forKey:kGDTCORClockKernelBootTime];\n  [aCoder encodeInt64:_uptimeNanoseconds forKey:kGDTCORClockUptime];\n}\n\n#pragma mark - Deprecated properties\n\n- (int64_t)kernelBootTime {\n  return self.kernelBootTimeNanoseconds;\n}\n\n- (int64_t)uptime {\n  return self.uptimeNanoseconds;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORConsoleLogger.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\nvolatile NSInteger GDTCORConsoleLoggerLoggingLevel = GDTCORLoggingLevelErrors;\n\n/** The console logger prefix. */\nstatic NSString *kGDTCORConsoleLogger = @\"[GoogleDataTransport]\";\n\nNSString *GDTCORMessageCodeEnumToString(GDTCORMessageCode code) {\n  return [[NSString alloc] initWithFormat:@\"I-GDTCOR%06ld\", (long)code];\n}\n\nvoid GDTCORLog(GDTCORMessageCode code, GDTCORLoggingLevel logLevel, NSString *format, ...) {\n// Don't log anything in not debug builds.\n#if !NDEBUG\n  if (logLevel >= GDTCORConsoleLoggerLoggingLevel) {\n    NSString *logFormat = [NSString stringWithFormat:@\"%@[%@] %@\", kGDTCORConsoleLogger,\n                                                     GDTCORMessageCodeEnumToString(code), format];\n    va_list args;\n    va_start(args, format);\n    NSLogv(logFormat, args);\n    va_end(args);\n  }\n#endif  // !NDEBUG\n}\n\nvoid GDTCORLogAssert(\n    BOOL wasFatal, NSString *_Nonnull file, NSInteger line, NSString *_Nullable format, ...) {\n// Don't log anything in not debug builds.\n#if !NDEBUG\n  GDTCORMessageCode code = wasFatal ? GDTCORMCEFatalAssertion : GDTCORMCEGeneralError;\n  NSString *logFormat =\n      [NSString stringWithFormat:@\"%@[%@] (%@:%ld) : %@\", kGDTCORConsoleLogger,\n                                 GDTCORMessageCodeEnumToString(code), file, (long)line, format];\n  va_list args;\n  va_start(args, format);\n  NSLogv(logFormat, args);\n  va_end(args);\n#endif  // !NDEBUG\n}\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORDirectorySizeTracker.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORDirectorySizeTracker.h\"\n\n@interface GDTCORDirectorySizeTracker ()\n\n/** The observed directory path. */\n@property(nonatomic, readonly) NSString *directoryPath;\n\n/** The cached content size of the observed directory. */\n@property(nonatomic, nullable) NSNumber *cachedSizeBytes;\n\n@end\n\n@implementation GDTCORDirectorySizeTracker\n\n- (instancetype)initWithDirectoryPath:(NSString *)path {\n  self = [super init];\n  if (self) {\n    _directoryPath = path;\n  }\n  return self;\n}\n\n- (GDTCORStorageSizeBytes)directoryContentSize {\n  if (self.cachedSizeBytes == nil) {\n    self.cachedSizeBytes = @([self calculateDirectoryContentSize]);\n  }\n\n  return self.cachedSizeBytes.unsignedLongLongValue;\n}\n\n- (void)fileWasAddedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize {\n  if (![path hasPrefix:self.directoryPath]) {\n    // Ignore because the file is not inside the directory.\n    return;\n  }\n\n  self.cachedSizeBytes = @([self directoryContentSize] + fileSize);\n}\n\n- (void)fileWasRemovedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize {\n  if (![path hasPrefix:self.directoryPath]) {\n    // Ignore because the file is not inside the directory.\n    return;\n  }\n\n  self.cachedSizeBytes = @([self directoryContentSize] - fileSize);\n}\n\n- (void)resetCachedSize {\n  self.cachedSizeBytes = nil;\n}\n\n- (GDTCORStorageSizeBytes)calculateDirectoryContentSize {\n  NSArray *prefetchedProperties = @[ NSURLIsRegularFileKey, NSURLFileSizeKey ];\n  uint64_t totalBytes = 0;\n  NSURL *directoryURL = [NSURL fileURLWithPath:self.directoryPath];\n\n  NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager]\n                 enumeratorAtURL:directoryURL\n      includingPropertiesForKeys:prefetchedProperties\n                         options:NSDirectoryEnumerationSkipsHiddenFiles\n                    errorHandler:^BOOL(NSURL *_Nonnull url, NSError *_Nonnull error) {\n                      return YES;\n                    }];\n\n  for (NSURL *fileURL in enumerator) {\n    @autoreleasepool {\n      NSNumber *isRegularFile;\n      [fileURL getResourceValue:&isRegularFile forKey:NSURLIsRegularFileKey error:nil];\n      if (isRegularFile.boolValue) {\n        totalBytes += [self fileSizeAtURL:fileURL];\n      }\n    }\n  }\n\n  return totalBytes;\n}\n\n- (GDTCORStorageSizeBytes)fileSizeAtURL:(NSURL *)fileURL {\n  NSNumber *fileSize;\n  [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil];\n  return fileSize.unsignedLongLongValue;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCOREndpoints.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREndpoints.h\"\n\nstatic NSString *const kINTServerURL =\n    @\"https://dummyapiverylong-dummy.dummy.com/dummy/api/very/long\";\n\n@implementation GDTCOREndpoints\n\n+ (NSDictionary<NSNumber *, NSURL *> *)uploadURLs {\n  // These strings should be interleaved to construct the real URL. This is just to (hopefully)\n  // fool github URL scanning bots.\n  static NSURL *CCTServerURL;\n  static dispatch_once_t CCTOnceToken;\n  dispatch_once(&CCTOnceToken, ^{\n    const char *p1 = \"hts/frbslgiggolai.o/0clgbth\";\n    const char *p2 = \"tp:/ieaeogn.ogepscmvc/o/ac\";\n    const char URL[54] = {p1[0],  p2[0],  p1[1],  p2[1],  p1[2],  p2[2],  p1[3],  p2[3],  p1[4],\n                          p2[4],  p1[5],  p2[5],  p1[6],  p2[6],  p1[7],  p2[7],  p1[8],  p2[8],\n                          p1[9],  p2[9],  p1[10], p2[10], p1[11], p2[11], p1[12], p2[12], p1[13],\n                          p2[13], p1[14], p2[14], p1[15], p2[15], p1[16], p2[16], p1[17], p2[17],\n                          p1[18], p2[18], p1[19], p2[19], p1[20], p2[20], p1[21], p2[21], p1[22],\n                          p2[22], p1[23], p2[23], p1[24], p2[24], p1[25], p2[25], p1[26], '\\0'};\n    CCTServerURL = [NSURL URLWithString:[NSString stringWithUTF8String:URL]];\n  });\n\n  static NSURL *FLLServerURL;\n  static dispatch_once_t FLLOnceToken;\n  dispatch_once(&FLLOnceToken, ^{\n    const char *p1 = \"hts/frbslgigp.ogepscmv/ieo/eaybtho\";\n    const char *p2 = \"tp:/ieaeogn-agolai.o/1frlglgc/aclg\";\n    const char URL[69] = {p1[0],  p2[0],  p1[1],  p2[1],  p1[2],  p2[2],  p1[3],  p2[3],  p1[4],\n                          p2[4],  p1[5],  p2[5],  p1[6],  p2[6],  p1[7],  p2[7],  p1[8],  p2[8],\n                          p1[9],  p2[9],  p1[10], p2[10], p1[11], p2[11], p1[12], p2[12], p1[13],\n                          p2[13], p1[14], p2[14], p1[15], p2[15], p1[16], p2[16], p1[17], p2[17],\n                          p1[18], p2[18], p1[19], p2[19], p1[20], p2[20], p1[21], p2[21], p1[22],\n                          p2[22], p1[23], p2[23], p1[24], p2[24], p1[25], p2[25], p1[26], p2[26],\n                          p1[27], p2[27], p1[28], p2[28], p1[29], p2[29], p1[30], p2[30], p1[31],\n                          p2[31], p1[32], p2[32], p1[33], p2[33], '\\0'};\n    FLLServerURL = [NSURL URLWithString:[NSString stringWithUTF8String:URL]];\n  });\n\n  static NSURL *CSHServerURL;\n  static dispatch_once_t CSHOnceToken;\n  dispatch_once(&CSHOnceToken, ^{\n    // These strings should be interleaved to construct the real URL. This is just to (hopefully)\n    // fool github URL scanning bots.\n    const char *p1 = \"hts/cahyiseot-agolai.o/1frlglgc/aclg\";\n    const char *p2 = \"tp:/rsltcrprsp.ogepscmv/ieo/eaybtho\";\n    const char URL[72] = {p1[0],  p2[0],  p1[1],  p2[1],  p1[2],  p2[2],  p1[3],  p2[3],  p1[4],\n                          p2[4],  p1[5],  p2[5],  p1[6],  p2[6],  p1[7],  p2[7],  p1[8],  p2[8],\n                          p1[9],  p2[9],  p1[10], p2[10], p1[11], p2[11], p1[12], p2[12], p1[13],\n                          p2[13], p1[14], p2[14], p1[15], p2[15], p1[16], p2[16], p1[17], p2[17],\n                          p1[18], p2[18], p1[19], p2[19], p1[20], p2[20], p1[21], p2[21], p1[22],\n                          p2[22], p1[23], p2[23], p1[24], p2[24], p1[25], p2[25], p1[26], p2[26],\n                          p1[27], p2[27], p1[28], p2[28], p1[29], p2[29], p1[30], p2[30], p1[31],\n                          p2[31], p1[32], p2[32], p1[33], p2[33], p1[34], p2[34], p1[35], '\\0'};\n    CSHServerURL = [NSURL URLWithString:[NSString stringWithUTF8String:URL]];\n  });\n  static NSDictionary<NSNumber *, NSURL *> *uploadURLs;\n  static dispatch_once_t URLOnceToken;\n  dispatch_once(&URLOnceToken, ^{\n    uploadURLs = @{\n      @(kGDTCORTargetCCT) : CCTServerURL,\n      @(kGDTCORTargetFLL) : FLLServerURL,\n      @(kGDTCORTargetCSH) : CSHServerURL,\n      @(kGDTCORTargetINT) : [NSURL URLWithString:kINTServerURL]\n    };\n  });\n  return uploadURLs;\n}\n\n+ (nullable NSURL *)uploadURLForTarget:(GDTCORTarget)target {\n  NSDictionary<NSNumber *, NSURL *> *URLs = [self uploadURLs];\n  return [URLs objectForKey:@(target)];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCOREvent.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h\"\n\n@implementation GDTCOREvent\n\n+ (NSString *)nextEventID {\n  // Replace special non-alphanumeric characters to avoid potential conflicts with storage logic.\n  return [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@\"-\" withString:@\"\"];\n}\n\n- (nullable instancetype)initWithMappingID:(NSString *)mappingID target:(GDTCORTarget)target {\n  GDTCORAssert(mappingID.length > 0, @\"Please give a valid mapping ID\");\n  GDTCORAssert(target > 0, @\"A target cannot be negative or 0\");\n  if (mappingID.length == 0 || target <= 0) {\n    return nil;\n  }\n  self = [super init];\n  if (self) {\n    _eventID = [GDTCOREvent nextEventID];\n    _mappingID = mappingID;\n    _target = target;\n    _qosTier = GDTCOREventQosDefault;\n    _expirationDate = [NSDate dateWithTimeIntervalSinceNow:604800];  // 7 days.\n\n    GDTCORLogDebug(@\"Event %@ created. ID:%@ mappingID: %@ target:%ld\", self, _eventID, mappingID,\n                   (long)target);\n  }\n\n  return self;\n}\n\n- (instancetype)copy {\n  GDTCOREvent *copy = [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];\n  copy->_eventID = _eventID;\n  copy.dataObject = _dataObject;\n  copy.qosTier = _qosTier;\n  copy.clockSnapshot = _clockSnapshot;\n  copy.customBytes = _customBytes;\n  GDTCORLogDebug(@\"Copying event %@ to event %@\", self, copy);\n  return copy;\n}\n\n- (NSUInteger)hash {\n  // This loses some precision, but it's probably fine.\n  NSUInteger eventIDHash = [_eventID hash];\n  NSUInteger mappingIDHash = [_mappingID hash];\n  NSUInteger timeHash = [_clockSnapshot hash];\n  NSInteger serializedBytesHash = [_serializedDataObjectBytes hash];\n\n  return eventIDHash ^ mappingIDHash ^ _target ^ _qosTier ^ timeHash ^ serializedBytesHash;\n}\n\n- (BOOL)isEqual:(id)object {\n  return [self hash] == [object hash];\n}\n\n#pragma mark - Property overrides\n\n- (void)setDataObject:(id<GDTCOREventDataObject>)dataObject {\n  // If you're looking here because of a performance issue in -transportBytes slowing the assignment\n  // of -dataObject, one way to address this is to add a queue to this class,\n  // dispatch_(barrier_ if concurrent)async here, and implement the getter with a dispatch_sync.\n  if (dataObject != _dataObject) {\n    _dataObject = dataObject;\n  }\n  self->_serializedDataObjectBytes = [dataObject transportBytes];\n}\n\n#pragma mark - NSSecureCoding and NSCoding Protocols\n\n/** NSCoding key for eventID property. */\nstatic NSString *kEventIDKey = @\"GDTCOREventEventIDKey\";\n\n/** NSCoding key for mappingID property. */\nstatic NSString *kMappingIDKey = @\"GDTCOREventMappingIDKey\";\n\n/** NSCoding key for target property. */\nstatic NSString *kTargetKey = @\"GDTCOREventTargetKey\";\n\n/** NSCoding key for qosTier property. */\nstatic NSString *kQoSTierKey = @\"GDTCOREventQoSTierKey\";\n\n/** NSCoding key for clockSnapshot property. */\nstatic NSString *kClockSnapshotKey = @\"GDTCOREventClockSnapshotKey\";\n\n/** NSCoding key for expirationDate property. */\nstatic NSString *kExpirationDateKey = @\"GDTCOREventExpirationDateKey\";\n\n/** NSCoding key for serializedDataObjectBytes property. */\nstatic NSString *kSerializedDataObjectBytes = @\"GDTCOREventSerializedDataObjectBytesKey\";\n\n/** NSCoding key for customData property. */\nstatic NSString *kCustomDataKey = @\"GDTCOREventCustomDataKey\";\n\n+ (BOOL)supportsSecureCoding {\n  return YES;\n}\n\n- (id)initWithCoder:(NSCoder *)aDecoder {\n  self = [self init];\n  if (self) {\n    _mappingID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kMappingIDKey];\n    _target = [aDecoder decodeIntegerForKey:kTargetKey];\n    _eventID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kEventIDKey]\n                   ?: [GDTCOREvent nextEventID];\n    _qosTier = [aDecoder decodeIntegerForKey:kQoSTierKey];\n    _clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:kClockSnapshotKey];\n    _customBytes = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCustomDataKey];\n    _expirationDate = [aDecoder decodeObjectOfClass:[NSDate class] forKey:kExpirationDateKey];\n    _serializedDataObjectBytes = [aDecoder decodeObjectOfClass:[NSData class]\n                                                        forKey:kSerializedDataObjectBytes];\n    if (!_serializedDataObjectBytes) {\n      return nil;\n    }\n  }\n  return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)aCoder {\n  [aCoder encodeObject:_eventID forKey:kEventIDKey];\n  [aCoder encodeObject:_mappingID forKey:kMappingIDKey];\n  [aCoder encodeInteger:_target forKey:kTargetKey];\n  [aCoder encodeInteger:_qosTier forKey:kQoSTierKey];\n  [aCoder encodeObject:_clockSnapshot forKey:kClockSnapshotKey];\n  [aCoder encodeObject:_customBytes forKey:kCustomDataKey];\n  [aCoder encodeObject:_expirationDate forKey:kExpirationDateKey];\n  [aCoder encodeObject:self.serializedDataObjectBytes forKey:kSerializedDataObjectBytes];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORFlatFileStorage+Promises.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage+Promises.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadBatch.h\"\n\n@implementation GDTCORFlatFileStorage (Promises)\n\n- (FBLPromise<NSSet<NSNumber *> *> *)batchIDsForTarget:(GDTCORTarget)target {\n  return [FBLPromise onQueue:self.storageQueue\n        wrapObjectCompletion:^(FBLPromiseObjectCompletion _Nonnull handler) {\n          [self batchIDsForTarget:target onComplete:handler];\n        }];\n}\n\n- (FBLPromise<NSNull *> *)removeBatchWithID:(NSNumber *)batchID deleteEvents:(BOOL)deleteEvents {\n  return [FBLPromise onQueue:self.storageQueue\n              wrapCompletion:^(FBLPromiseCompletion _Nonnull handler) {\n                [self removeBatchWithID:batchID deleteEvents:deleteEvents onComplete:handler];\n              }];\n}\n\n- (FBLPromise<NSNull *> *)removeBatchesWithIDs:(NSSet<NSNumber *> *)batchIDs\n                                  deleteEvents:(BOOL)deleteEvents {\n  NSMutableArray<FBLPromise *> *removeBatchPromises =\n      [NSMutableArray arrayWithCapacity:batchIDs.count];\n  for (NSNumber *batchID in batchIDs) {\n    [removeBatchPromises addObject:[self removeBatchWithID:batchID deleteEvents:deleteEvents]];\n  }\n\n  return [FBLPromise onQueue:self.storageQueue all:[removeBatchPromises copy]].thenOn(\n      self.storageQueue, ^id(id result) {\n        return [FBLPromise resolvedWith:[NSNull null]];\n      });\n}\n\n- (FBLPromise<NSNull *> *)removeAllBatchesForTarget:(GDTCORTarget)target\n                                       deleteEvents:(BOOL)deleteEvents {\n  return\n      [self batchIDsForTarget:target].thenOn(self.storageQueue, ^id(NSSet<NSNumber *> *batchIDs) {\n        if (batchIDs.count == 0) {\n          return [FBLPromise resolvedWith:[NSNull null]];\n        } else {\n          return [self removeBatchesWithIDs:batchIDs deleteEvents:NO];\n        }\n      });\n}\n\n- (FBLPromise<NSNumber *> *)hasEventsForTarget:(GDTCORTarget)target {\n  return [FBLPromise onQueue:self.storageQueue\n          wrapBoolCompletion:^(FBLPromiseBoolCompletion _Nonnull handler) {\n            [self hasEventsForTarget:target onComplete:handler];\n          }];\n}\n\n- (FBLPromise<GDTCORUploadBatch *> *)batchWithEventSelector:\n                                         (GDTCORStorageEventSelector *)eventSelector\n                                            batchExpiration:(NSDate *)expiration {\n  return [FBLPromise\n      onQueue:self.storageQueue\n        async:^(FBLPromiseFulfillBlock _Nonnull fulfill, FBLPromiseRejectBlock _Nonnull reject) {\n          [self batchWithEventSelector:eventSelector\n                       batchExpiration:expiration\n                            onComplete:^(NSNumber *_Nullable newBatchID,\n                                         NSSet<GDTCOREvent *> *_Nullable batchEvents) {\n                              if (newBatchID == nil || batchEvents == nil) {\n                                reject([self genericRejectedPromiseErrorWithReason:\n                                                 @\"There are no events for the selector.\"]);\n                              } else {\n                                fulfill([[GDTCORUploadBatch alloc] initWithBatchID:newBatchID\n                                                                            events:batchEvents]);\n                              }\n                            }];\n        }];\n}\n\n// TODO: Move to a separate class/extension when needed in more places.\n- (NSError *)genericRejectedPromiseErrorWithReason:(NSString *)reason {\n  return [NSError errorWithDomain:@\"GDTCORFlatFileStorage\"\n                             code:-1\n                         userInfo:@{NSLocalizedFailureReasonErrorKey : reason}];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORFlatFileStorage.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadCoordinator.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORDirectorySizeTracker.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A library data key this class uses to track batchIDs. */\nstatic NSString *const gBatchIDCounterKey = @\"GDTCORFlatFileStorageBatchIDCounter\";\n\n/** The separator used between metadata elements in filenames. */\nstatic NSString *const kMetadataSeparator = @\"-\";\n\nNSString *const kGDTCOREventComponentsEventIDKey = @\"GDTCOREventComponentsEventIDKey\";\n\nNSString *const kGDTCOREventComponentsQoSTierKey = @\"GDTCOREventComponentsQoSTierKey\";\n\nNSString *const kGDTCOREventComponentsMappingIDKey = @\"GDTCOREventComponentsMappingIDKey\";\n\nNSString *const kGDTCOREventComponentsExpirationKey = @\"GDTCOREventComponentsExpirationKey\";\n\nNSString *const kGDTCORBatchComponentsTargetKey = @\"GDTCORBatchComponentsTargetKey\";\n\nNSString *const kGDTCORBatchComponentsBatchIDKey = @\"GDTCORBatchComponentsBatchIDKey\";\n\nNSString *const kGDTCORBatchComponentsExpirationKey = @\"GDTCORBatchComponentsExpirationKey\";\n\nNSString *const GDTCORFlatFileStorageErrorDomain = @\"GDTCORFlatFileStorage\";\n\nconst uint64_t kGDTCORFlatFileStorageSizeLimit = 20 * 1000 * 1000;  // 20 MB.\n\n@interface GDTCORFlatFileStorage ()\n\n/** An instance of the size tracker to keep track of the disk space consumed by the storage. */\n@property(nonatomic, readonly) GDTCORDirectorySizeTracker *sizeTracker;\n\n@end\n\n@implementation GDTCORFlatFileStorage\n\n@synthesize sizeTracker = _sizeTracker;\n\n+ (void)load {\n#if !NDEBUG\n  [[GDTCORRegistrar sharedInstance] registerStorage:[self sharedInstance] target:kGDTCORTargetTest];\n#endif  // !NDEBUG\n  [[GDTCORRegistrar sharedInstance] registerStorage:[self sharedInstance] target:kGDTCORTargetCCT];\n  [[GDTCORRegistrar sharedInstance] registerStorage:[self sharedInstance] target:kGDTCORTargetFLL];\n  [[GDTCORRegistrar sharedInstance] registerStorage:[self sharedInstance] target:kGDTCORTargetCSH];\n  [[GDTCORRegistrar sharedInstance] registerStorage:[self sharedInstance] target:kGDTCORTargetINT];\n}\n\n+ (instancetype)sharedInstance {\n  static GDTCORFlatFileStorage *sharedStorage;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedStorage = [[GDTCORFlatFileStorage alloc] init];\n  });\n  return sharedStorage;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _storageQueue =\n        dispatch_queue_create(\"com.google.GDTCORFlatFileStorage\", DISPATCH_QUEUE_SERIAL);\n    _uploadCoordinator = [GDTCORUploadCoordinator sharedInstance];\n  }\n  return self;\n}\n\n- (GDTCORDirectorySizeTracker *)sizeTracker {\n  if (_sizeTracker == nil) {\n    _sizeTracker =\n        [[GDTCORDirectorySizeTracker alloc] initWithDirectoryPath:GDTCORRootDirectory().path];\n  }\n  return _sizeTracker;\n}\n\n#pragma mark - GDTCORStorageProtocol\n\n- (void)storeEvent:(GDTCOREvent *)event\n        onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {\n  GDTCORLogDebug(@\"Saving event: %@\", event);\n  if (event == nil || event.serializedDataObjectBytes == nil) {\n    GDTCORLogDebug(@\"%@\", @\"The event was nil, so it was not saved.\");\n    if (completion) {\n      completion(NO, [NSError errorWithDomain:NSInternalInconsistencyException\n                                         code:-1\n                                     userInfo:nil]);\n    }\n    return;\n  }\n  if (!completion) {\n    completion = ^(BOOL wasWritten, NSError *_Nullable error) {\n      GDTCORLogDebug(@\"event %@ stored. success:%@ error:%@\", event, wasWritten ? @\"YES\" : @\"NO\",\n                     error);\n    };\n  }\n\n  __block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;\n  bgID = [[GDTCORApplication sharedApplication]\n      beginBackgroundTaskWithName:@\"GDTStorage\"\n                expirationHandler:^{\n                  // End the background task if it's still valid.\n                  [[GDTCORApplication sharedApplication] endBackgroundTask:bgID];\n                  bgID = GDTCORBackgroundIdentifierInvalid;\n                }];\n\n  dispatch_async(_storageQueue, ^{\n    // Check that a backend implementation is available for this target.\n    GDTCORTarget target = event.target;\n    NSString *filePath = [GDTCORFlatFileStorage pathForTarget:target\n                                                      eventID:event.eventID\n                                                      qosTier:@(event.qosTier)\n                                               expirationDate:event.expirationDate\n                                                    mappingID:event.mappingID];\n    NSError *error;\n    NSData *encodedEvent = GDTCOREncodeArchive(event, nil, &error);\n    if (error) {\n      completion(NO, error);\n      return;\n    }\n\n    // Check storage size limit before storing the event.\n    uint64_t resultingStorageSize = self.sizeTracker.directoryContentSize + encodedEvent.length;\n    if (resultingStorageSize > kGDTCORFlatFileStorageSizeLimit) {\n      NSError *error = [NSError\n          errorWithDomain:GDTCORFlatFileStorageErrorDomain\n                     code:GDTCORFlatFileStorageErrorSizeLimitReached\n                 userInfo:@{\n                   NSLocalizedFailureReasonErrorKey : @\"Storage size limit has been reached.\"\n                 }];\n      completion(NO, error);\n      return;\n    }\n\n    // Write the encoded event to the file.\n    BOOL writeResult = GDTCORWriteDataToFile(encodedEvent, filePath, &error);\n    if (writeResult == NO || error) {\n      GDTCORLogDebug(@\"Attempt to write archive failed: path:%@ error:%@\", filePath, error);\n      completion(NO, error);\n      return;\n    } else {\n      GDTCORLogDebug(@\"Writing archive succeeded: %@\", filePath);\n      completion(YES, nil);\n    }\n\n    // Notify size tracker.\n    [self.sizeTracker fileWasAddedAtPath:filePath withSize:encodedEvent.length];\n\n    // Check the QoS, if it's high priority, notify the target that it has a high priority event.\n    if (event.qosTier == GDTCOREventQoSFast) {\n      // TODO: Remove a direct dependency on the upload coordinator.\n      [self.uploadCoordinator forceUploadForTarget:target];\n    }\n\n    // Cancel or end the associated background task if it's still valid.\n    [[GDTCORApplication sharedApplication] endBackgroundTask:bgID];\n    bgID = GDTCORBackgroundIdentifierInvalid;\n  });\n}\n\n- (void)batchWithEventSelector:(nonnull GDTCORStorageEventSelector *)eventSelector\n               batchExpiration:(nonnull NSDate *)expiration\n                    onComplete:\n                        (nonnull void (^)(NSNumber *_Nullable batchID,\n                                          NSSet<GDTCOREvent *> *_Nullable events))onComplete {\n  dispatch_queue_t queue = _storageQueue;\n  void (^onPathsForTargetComplete)(NSNumber *, NSSet<NSString *> *_Nonnull) = ^(\n      NSNumber *batchID, NSSet<NSString *> *_Nonnull paths) {\n    dispatch_async(queue, ^{\n      NSMutableSet<GDTCOREvent *> *events = [[NSMutableSet alloc] init];\n      for (NSString *eventPath in paths) {\n        NSError *error;\n        GDTCOREvent *event =\n            (GDTCOREvent *)GDTCORDecodeArchive([GDTCOREvent class], eventPath, nil, &error);\n        if (event == nil || error) {\n          GDTCORLogDebug(@\"Error deserializing event: %@\", error);\n          [[NSFileManager defaultManager] removeItemAtPath:eventPath error:nil];\n          continue;\n        } else {\n          NSString *fileName = [eventPath lastPathComponent];\n          NSString *batchPath =\n              [GDTCORFlatFileStorage batchPathForTarget:eventSelector.selectedTarget\n                                                batchID:batchID\n                                         expirationDate:expiration];\n          [[NSFileManager defaultManager] createDirectoryAtPath:batchPath\n                                    withIntermediateDirectories:YES\n                                                     attributes:nil\n                                                          error:nil];\n          NSString *destinationPath = [batchPath stringByAppendingPathComponent:fileName];\n          error = nil;\n          [[NSFileManager defaultManager] moveItemAtPath:eventPath\n                                                  toPath:destinationPath\n                                                   error:&error];\n          if (error) {\n            GDTCORLogDebug(@\"An event file wasn't moveable into the batch directory: %@\", error);\n          }\n          [events addObject:event];\n        }\n      }\n      if (onComplete) {\n        if (events.count == 0) {\n          onComplete(nil, nil);\n        } else {\n          onComplete(batchID, events);\n        }\n      }\n    });\n  };\n\n  void (^onBatchIDFetchComplete)(NSNumber *) = ^(NSNumber *batchID) {\n    dispatch_async(queue, ^{\n      if (batchID == nil) {\n        if (onComplete) {\n          onComplete(nil, nil);\n          return;\n        }\n      }\n      [self pathsForTarget:eventSelector.selectedTarget\n                  eventIDs:eventSelector.selectedEventIDs\n                  qosTiers:eventSelector.selectedQosTiers\n                mappingIDs:eventSelector.selectedMappingIDs\n                onComplete:^(NSSet<NSString *> *_Nonnull paths) {\n                  onPathsForTargetComplete(batchID, paths);\n                }];\n    });\n  };\n\n  [self nextBatchID:^(NSNumber *_Nullable batchID) {\n    if (batchID == nil) {\n      if (onComplete) {\n        onComplete(nil, nil);\n      }\n    } else {\n      onBatchIDFetchComplete(batchID);\n    }\n  }];\n}\n\n- (void)removeBatchWithID:(nonnull NSNumber *)batchID\n             deleteEvents:(BOOL)deleteEvents\n               onComplete:(void (^_Nullable)(void))onComplete {\n  dispatch_async(_storageQueue, ^{\n    [self syncThreadUnsafeRemoveBatchWithID:batchID deleteEvents:deleteEvents];\n\n    if (onComplete) {\n      onComplete();\n    }\n  });\n}\n\n- (void)batchIDsForTarget:(GDTCORTarget)target\n               onComplete:(nonnull void (^)(NSSet<NSNumber *> *_Nullable))onComplete {\n  dispatch_async(_storageQueue, ^{\n    NSFileManager *fileManager = [NSFileManager defaultManager];\n    NSError *error;\n    NSArray<NSString *> *batchPaths =\n        [fileManager contentsOfDirectoryAtPath:[GDTCORFlatFileStorage batchDataStoragePath]\n                                         error:&error];\n    if (error || batchPaths.count == 0) {\n      if (onComplete) {\n        onComplete(nil);\n      }\n      return;\n    }\n    NSMutableSet<NSNumber *> *batchIDs = [[NSMutableSet alloc] init];\n    for (NSString *path in batchPaths) {\n      NSDictionary<NSString *, id> *components = [self batchComponentsFromFilename:path];\n      NSNumber *targetNumber = components[kGDTCORBatchComponentsTargetKey];\n      NSNumber *batchID = components[kGDTCORBatchComponentsBatchIDKey];\n      if (batchID != nil && targetNumber.intValue == target) {\n        [batchIDs addObject:batchID];\n      }\n    }\n    if (onComplete) {\n      onComplete(batchIDs);\n    }\n  });\n}\n\n- (void)libraryDataForKey:(nonnull NSString *)key\n          onFetchComplete:(nonnull void (^)(NSData *_Nullable, NSError *_Nullable))onFetchComplete\n              setNewValue:(NSData *_Nullable (^_Nullable)(void))setValueBlock {\n  dispatch_async(_storageQueue, ^{\n    NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];\n    NSError *error;\n    NSData *data = [NSData dataWithContentsOfFile:dataPath options:0 error:&error];\n    if (onFetchComplete) {\n      onFetchComplete(data, error);\n    }\n    if (setValueBlock) {\n      NSData *newValue = setValueBlock();\n      // The -isKindOfClass check is necessary because without an explicit 'return nil' in the block\n      // the implicit return value will be the block itself. The compiler doesn't detect this.\n      if (newValue != nil && [newValue isKindOfClass:[NSData class]] && newValue.length) {\n        NSError *newValueError;\n        if ([newValue writeToFile:dataPath options:NSDataWritingAtomic error:&newValueError]) {\n          // Update storage size.\n          [self.sizeTracker fileWasRemovedAtPath:dataPath withSize:data.length];\n          [self.sizeTracker fileWasAddedAtPath:dataPath withSize:newValue.length];\n        } else {\n          GDTCORLogDebug(@\"Error writing new value in libraryDataForKey: %@\", newValueError);\n        }\n      }\n    }\n  });\n}\n\n- (void)storeLibraryData:(NSData *)data\n                  forKey:(nonnull NSString *)key\n              onComplete:(nullable void (^)(NSError *_Nullable error))onComplete {\n  if (!data || data.length <= 0) {\n    if (onComplete) {\n      onComplete([NSError errorWithDomain:NSInternalInconsistencyException code:-1 userInfo:nil]);\n    }\n    return;\n  }\n  dispatch_async(_storageQueue, ^{\n    NSError *error;\n    NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];\n    if ([data writeToFile:dataPath options:NSDataWritingAtomic error:&error]) {\n      [self.sizeTracker fileWasAddedAtPath:dataPath withSize:data.length];\n    }\n    if (onComplete) {\n      onComplete(error);\n    }\n  });\n}\n\n- (void)removeLibraryDataForKey:(nonnull NSString *)key\n                     onComplete:(nonnull void (^)(NSError *_Nullable error))onComplete {\n  dispatch_async(_storageQueue, ^{\n    NSError *error;\n    NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];\n    GDTCORStorageSizeBytes fileSize =\n        [self.sizeTracker fileSizeAtURL:[NSURL fileURLWithPath:dataPath]];\n\n    if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath]) {\n      if ([[NSFileManager defaultManager] removeItemAtPath:dataPath error:&error]) {\n        [self.sizeTracker fileWasRemovedAtPath:dataPath withSize:fileSize];\n      }\n      if (onComplete) {\n        onComplete(error);\n      }\n    }\n  });\n}\n\n- (void)hasEventsForTarget:(GDTCORTarget)target onComplete:(void (^)(BOOL hasEvents))onComplete {\n  dispatch_async(_storageQueue, ^{\n    NSFileManager *fileManager = [NSFileManager defaultManager];\n    NSString *targetPath = [NSString\n        stringWithFormat:@\"%@/%ld\", [GDTCORFlatFileStorage eventDataStoragePath], (long)target];\n    [fileManager createDirectoryAtPath:targetPath\n           withIntermediateDirectories:YES\n                            attributes:nil\n                                 error:nil];\n    NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:targetPath];\n    BOOL hasEventAtLeastOneEvent = [enumerator nextObject] != nil;\n    if (onComplete) {\n      onComplete(hasEventAtLeastOneEvent);\n    }\n  });\n}\n\n- (void)checkForExpirations {\n  dispatch_async(_storageQueue, ^{\n    GDTCORLogDebug(@\"%@\", @\"Checking for expired events and batches\");\n    NSTimeInterval now = [NSDate date].timeIntervalSince1970;\n    NSFileManager *fileManager = [NSFileManager defaultManager];\n\n    // TODO: Storage may not have enough context to remove batches because a batch may be being\n    // uploaded but the storage has not context of it.\n\n    // Find expired batches and move their events back to the main storage.\n    // If a batch contains expired events they are expected to be removed further in the method\n    // together with other expired events in the main storage.\n    NSString *batchDataPath = [GDTCORFlatFileStorage batchDataStoragePath];\n    NSArray<NSString *> *batchDataPaths = [fileManager contentsOfDirectoryAtPath:batchDataPath\n                                                                           error:nil];\n    for (NSString *path in batchDataPaths) {\n      @autoreleasepool {\n        NSString *fileName = [path lastPathComponent];\n        NSDictionary<NSString *, id> *batchComponents = [self batchComponentsFromFilename:fileName];\n        NSDate *expirationDate = batchComponents[kGDTCORBatchComponentsExpirationKey];\n        NSNumber *batchID = batchComponents[kGDTCORBatchComponentsBatchIDKey];\n        if (expirationDate != nil && expirationDate.timeIntervalSince1970 < now && batchID != nil) {\n          NSNumber *batchID = batchComponents[kGDTCORBatchComponentsBatchIDKey];\n          // Move all events from the expired batch back to the main storage.\n          [self syncThreadUnsafeRemoveBatchWithID:batchID deleteEvents:NO];\n        }\n      }\n    }\n\n    // Find expired events and remove them from the storage.\n    NSString *eventDataPath = [GDTCORFlatFileStorage eventDataStoragePath];\n    NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:eventDataPath];\n    NSString *path;\n\n    while (YES) {\n      @autoreleasepool {\n        // Call `[enumerator nextObject]` under autorelease pool to make sure all autoreleased\n        // objects created under the hood are released on each iteration end to avoid unnecessary\n        // memory growth.\n        path = [enumerator nextObject];\n        if (path == nil) {\n          break;\n        }\n\n        NSString *fileName = [path lastPathComponent];\n        NSDictionary<NSString *, id> *eventComponents = [self eventComponentsFromFilename:fileName];\n        NSDate *expirationDate = eventComponents[kGDTCOREventComponentsExpirationKey];\n        if (expirationDate != nil && expirationDate.timeIntervalSince1970 < now) {\n          NSString *pathToDelete = [eventDataPath stringByAppendingPathComponent:path];\n          NSError *error;\n          [fileManager removeItemAtPath:pathToDelete error:&error];\n          if (error != nil) {\n            GDTCORLogDebug(@\"There was an error deleting an expired item: %@\", error);\n          } else {\n            GDTCORLogDebug(@\"Item deleted because it expired: %@\", pathToDelete);\n          }\n        }\n      }\n    }\n\n    [self.sizeTracker resetCachedSize];\n  });\n}\n\n- (void)storageSizeWithCallback:(void (^)(uint64_t storageSize))onComplete {\n  if (!onComplete) {\n    return;\n  }\n\n  dispatch_async(_storageQueue, ^{\n    onComplete([self.sizeTracker directoryContentSize]);\n  });\n}\n\n#pragma mark - Private not thread safe methods\n/** Looks for directory paths containing events for a batch with the specified ID.\n * @param batchID A batch ID.\n * @param outError A pointer to `NSError *` to assign as possible error to.\n * @return An array of an array of paths to directories for event batches with a specified batch ID\n * or `nil` in the case of an error. Usually returns a single path but potentially return more in\n * cases when the app is terminated while uploading a batch.\n */\n- (nullable NSArray<NSString *> *)batchDirPathsForBatchID:(NSNumber *)batchID\n                                                    error:(NSError **_Nonnull)outError {\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n  NSError *error;\n  NSArray<NSString *> *batches =\n      [fileManager contentsOfDirectoryAtPath:[GDTCORFlatFileStorage batchDataStoragePath]\n                                       error:&error];\n  if (batches == nil) {\n    *outError = error;\n    GDTCORLogDebug(@\"Failed to find event file paths for batchID: %@, error: %@\", batchID, error);\n    return nil;\n  }\n\n  NSMutableArray<NSString *> *batchDirPaths = [NSMutableArray array];\n  for (NSString *path in batches) {\n    NSDictionary<NSString *, id> *components = [self batchComponentsFromFilename:path];\n    NSNumber *pathBatchID = components[kGDTCORBatchComponentsBatchIDKey];\n    if ([pathBatchID isEqual:batchID]) {\n      NSString *batchDirPath =\n          [[GDTCORFlatFileStorage batchDataStoragePath] stringByAppendingPathComponent:path];\n      [batchDirPaths addObject:batchDirPath];\n    }\n  }\n\n  return [batchDirPaths copy];\n}\n\n/** Makes a copy of the contents of a directory to a directory at the specified path.*/\n- (BOOL)moveContentsOfDirectoryAtPath:(NSString *)sourcePath\n                                   to:(NSString *)destinationPath\n                                error:(NSError **_Nonnull)outError {\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n\n  NSError *error;\n  NSArray<NSString *> *contentsPaths = [fileManager contentsOfDirectoryAtPath:sourcePath\n                                                                        error:&error];\n  if (contentsPaths == nil) {\n    *outError = error;\n    return NO;\n  }\n\n  NSMutableArray<NSError *> *errors = [NSMutableArray array];\n  for (NSString *path in contentsPaths) {\n    NSString *contentDestinationPath = [destinationPath stringByAppendingPathComponent:path];\n    NSString *contentSourcePath = [sourcePath stringByAppendingPathComponent:path];\n\n    NSError *moveError;\n    if (![fileManager moveItemAtPath:contentSourcePath\n                              toPath:contentDestinationPath\n                               error:&moveError] &&\n        moveError) {\n      [errors addObject:moveError];\n    }\n  }\n\n  if (errors.count == 0) {\n    return YES;\n  } else {\n    NSError *combinedError = [NSError errorWithDomain:@\"GDTCORFlatFileStorage\"\n                                                 code:-1\n                                             userInfo:@{NSUnderlyingErrorKey : errors}];\n    *outError = combinedError;\n    return NO;\n  }\n}\n\n- (void)syncThreadUnsafeRemoveBatchWithID:(nonnull NSNumber *)batchID\n                             deleteEvents:(BOOL)deleteEvents {\n  NSError *error;\n  NSArray<NSString *> *batchDirPaths = [self batchDirPathsForBatchID:batchID error:&error];\n\n  if (batchDirPaths == nil) {\n    return;\n  }\n\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n\n  void (^removeBatchDir)(NSString *batchDirPath) = ^(NSString *batchDirPath) {\n    NSError *error;\n    if ([fileManager removeItemAtPath:batchDirPath error:&error]) {\n      GDTCORLogDebug(@\"Batch removed at path: %@\", batchDirPath);\n    } else {\n      GDTCORLogDebug(@\"Failed to remove batch at path: %@\", batchDirPath);\n    }\n  };\n\n  for (NSString *batchDirPath in batchDirPaths) {\n    @autoreleasepool {\n      if (deleteEvents) {\n        removeBatchDir(batchDirPath);\n      } else {\n        NSString *batchDirName = [batchDirPath lastPathComponent];\n        NSDictionary<NSString *, id> *components = [self batchComponentsFromFilename:batchDirName];\n        NSString *targetValue = [components[kGDTCORBatchComponentsTargetKey] stringValue];\n        NSString *destinationPath;\n        if (targetValue) {\n          destinationPath = [[GDTCORFlatFileStorage eventDataStoragePath]\n              stringByAppendingPathComponent:targetValue];\n        }\n\n        // `- [NSFileManager moveItemAtPath:toPath:error:]` method fails if an item by the\n        // destination path already exists (which usually is the case for the current method). Move\n        // the events one by one instead.\n        if (destinationPath && [self moveContentsOfDirectoryAtPath:batchDirPath\n                                                                to:destinationPath\n                                                             error:&error]) {\n          GDTCORLogDebug(@\"Batched events at path: %@ moved back to the storage: %@\", batchDirPath,\n                         destinationPath);\n        } else {\n          GDTCORLogDebug(@\"Error encountered whilst moving events back: %@\", error);\n        }\n\n        // Even if not all events where moved back to the storage, there is not much can be done at\n        // this point, so cleanup batch directory now to avoid cluttering.\n        removeBatchDir(batchDirPath);\n      }\n    }\n  }\n\n  [self.sizeTracker resetCachedSize];\n}\n\n#pragma mark - Private helper methods\n\n+ (NSString *)eventDataStoragePath {\n  static NSString *eventDataPath;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    eventDataPath = [NSString stringWithFormat:@\"%@/%@/gdt_event_data\", GDTCORRootDirectory().path,\n                                               NSStringFromClass([self class])];\n  });\n  NSError *error;\n  [[NSFileManager defaultManager] createDirectoryAtPath:eventDataPath\n                            withIntermediateDirectories:YES\n                                             attributes:0\n                                                  error:&error];\n  GDTCORAssert(error == nil, @\"Creating the library data path failed: %@\", error);\n  return eventDataPath;\n}\n\n+ (NSString *)batchDataStoragePath {\n  static NSString *batchDataPath;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    batchDataPath = [NSString stringWithFormat:@\"%@/%@/gdt_batch_data\", GDTCORRootDirectory().path,\n                                               NSStringFromClass([self class])];\n  });\n  NSError *error;\n  [[NSFileManager defaultManager] createDirectoryAtPath:batchDataPath\n                            withIntermediateDirectories:YES\n                                             attributes:0\n                                                  error:&error];\n  GDTCORAssert(error == nil, @\"Creating the batch data path failed: %@\", error);\n  return batchDataPath;\n}\n\n+ (NSString *)libraryDataStoragePath {\n  static NSString *libraryDataPath;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    libraryDataPath =\n        [NSString stringWithFormat:@\"%@/%@/gdt_library_data\", GDTCORRootDirectory().path,\n                                   NSStringFromClass([self class])];\n  });\n  NSError *error;\n  [[NSFileManager defaultManager] createDirectoryAtPath:libraryDataPath\n                            withIntermediateDirectories:YES\n                                             attributes:0\n                                                  error:&error];\n  GDTCORAssert(error == nil, @\"Creating the library data path failed: %@\", error);\n  return libraryDataPath;\n}\n\n+ (NSString *)batchPathForTarget:(GDTCORTarget)target\n                         batchID:(NSNumber *)batchID\n                  expirationDate:(NSDate *)expirationDate {\n  return\n      [NSString stringWithFormat:@\"%@/%ld%@%@%@%llu\", [GDTCORFlatFileStorage batchDataStoragePath],\n                                 (long)target, kMetadataSeparator, batchID, kMetadataSeparator,\n                                 ((uint64_t)expirationDate.timeIntervalSince1970)];\n}\n\n+ (NSString *)pathForTarget:(GDTCORTarget)target\n                    eventID:(NSString *)eventID\n                    qosTier:(NSNumber *)qosTier\n             expirationDate:(NSDate *)expirationDate\n                  mappingID:(NSString *)mappingID {\n  NSMutableCharacterSet *allowedChars = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];\n  [allowedChars addCharactersInString:kMetadataSeparator];\n  mappingID = [mappingID stringByAddingPercentEncodingWithAllowedCharacters:allowedChars];\n  return [NSString stringWithFormat:@\"%@/%ld/%@%@%@%@%llu%@%@\",\n                                    [GDTCORFlatFileStorage eventDataStoragePath], (long)target,\n                                    eventID, kMetadataSeparator, qosTier, kMetadataSeparator,\n                                    ((uint64_t)expirationDate.timeIntervalSince1970),\n                                    kMetadataSeparator, mappingID];\n}\n\n- (void)pathsForTarget:(GDTCORTarget)target\n              eventIDs:(nullable NSSet<NSString *> *)eventIDs\n              qosTiers:(nullable NSSet<NSNumber *> *)qosTiers\n            mappingIDs:(nullable NSSet<NSString *> *)mappingIDs\n            onComplete:(void (^)(NSSet<NSString *> *paths))onComplete {\n  void (^completion)(NSSet<NSString *> *) = onComplete == nil ? ^(NSSet<NSString *> *paths){} : onComplete;\n  dispatch_async(_storageQueue, ^{\n    NSMutableSet<NSString *> *paths = [[NSMutableSet alloc] init];\n    NSFileManager *fileManager = [NSFileManager defaultManager];\n    NSString *targetPath = [NSString\n        stringWithFormat:@\"%@/%ld\", [GDTCORFlatFileStorage eventDataStoragePath], (long)target];\n    [fileManager createDirectoryAtPath:targetPath\n           withIntermediateDirectories:YES\n                            attributes:nil\n                                 error:nil];\n    NSError *error;\n    NSArray<NSString *> *dirPaths = [fileManager contentsOfDirectoryAtPath:targetPath error:&error];\n    if (error) {\n      GDTCORLogDebug(@\"There was an error reading the contents of the target path: %@\", error);\n      completion(paths);\n      return;\n    }\n    BOOL checkingIDs = eventIDs.count > 0;\n    BOOL checkingQosTiers = qosTiers.count > 0;\n    BOOL checkingMappingIDs = mappingIDs.count > 0;\n    BOOL checkingAnything = checkingIDs == NO && checkingQosTiers == NO && checkingMappingIDs == NO;\n    for (NSString *path in dirPaths) {\n      // Skip hidden files that are created as part of atomic file creation.\n      if ([path hasPrefix:@\".\"]) {\n        continue;\n      }\n      NSString *filePath = [targetPath stringByAppendingPathComponent:path];\n      if (checkingAnything) {\n        [paths addObject:filePath];\n        continue;\n      }\n      NSString *filename = [path lastPathComponent];\n      NSDictionary<NSString *, id> *eventComponents = [self eventComponentsFromFilename:filename];\n      if (!eventComponents) {\n        GDTCORLogDebug(@\"There was an error reading the filename components: %@\", eventComponents);\n        continue;\n      }\n      NSString *eventID = eventComponents[kGDTCOREventComponentsEventIDKey];\n      NSNumber *qosTier = eventComponents[kGDTCOREventComponentsQoSTierKey];\n      NSString *mappingID = eventComponents[kGDTCOREventComponentsMappingIDKey];\n\n      NSNumber *eventIDMatch = checkingIDs ? @([eventIDs containsObject:eventID]) : nil;\n      NSNumber *qosTierMatch = checkingQosTiers ? @([qosTiers containsObject:qosTier]) : nil;\n      NSNumber *mappingIDMatch =\n          checkingMappingIDs\n              ? @([mappingIDs containsObject:[mappingID stringByRemovingPercentEncoding]])\n              : nil;\n      if ((eventIDMatch == nil || eventIDMatch.boolValue) &&\n          (qosTierMatch == nil || qosTierMatch.boolValue) &&\n          (mappingIDMatch == nil || mappingIDMatch.boolValue)) {\n        [paths addObject:filePath];\n      }\n    }\n    completion(paths);\n  });\n}\n\n- (void)nextBatchID:(void (^)(NSNumber *_Nullable batchID))nextBatchID {\n  __block int32_t lastBatchID = -1;\n  [self libraryDataForKey:gBatchIDCounterKey\n      onFetchComplete:^(NSData *_Nullable data, NSError *_Nullable getValueError) {\n        if (!getValueError) {\n          [data getBytes:(void *)&lastBatchID length:sizeof(int32_t)];\n        }\n        if (data == nil) {\n          lastBatchID = 0;\n        }\n        if (nextBatchID) {\n          nextBatchID(@(lastBatchID));\n        }\n      }\n      setNewValue:^NSData *_Nullable(void) {\n        if (lastBatchID != -1) {\n          int32_t incrementedValue = lastBatchID + 1;\n          return [NSData dataWithBytes:&incrementedValue length:sizeof(int32_t)];\n        }\n        return nil;\n      }];\n}\n\n- (nullable NSDictionary<NSString *, id> *)eventComponentsFromFilename:(NSString *)fileName {\n  NSArray<NSString *> *components = [fileName componentsSeparatedByString:kMetadataSeparator];\n  if (components.count >= 4) {\n    NSString *eventID = components[0];\n    NSNumber *qosTier = @(components[1].integerValue);\n    NSDate *expirationDate = [NSDate dateWithTimeIntervalSince1970:components[2].longLongValue];\n    NSString *mappingID = [[components subarrayWithRange:NSMakeRange(3, components.count - 3)]\n        componentsJoinedByString:kMetadataSeparator];\n    if (eventID == nil || qosTier == nil || mappingID == nil || expirationDate == nil) {\n      GDTCORLogDebug(@\"There was an error parsing the event filename components: %@\", components);\n      return nil;\n    }\n    return @{\n      kGDTCOREventComponentsEventIDKey : eventID,\n      kGDTCOREventComponentsQoSTierKey : qosTier,\n      kGDTCOREventComponentsExpirationKey : expirationDate,\n      kGDTCOREventComponentsMappingIDKey : mappingID\n    };\n  }\n  GDTCORLogDebug(@\"The event filename could not be split: %@\", fileName);\n  return nil;\n}\n\n- (nullable NSDictionary<NSString *, id> *)batchComponentsFromFilename:(NSString *)fileName {\n  NSArray<NSString *> *components = [fileName componentsSeparatedByString:kMetadataSeparator];\n  if (components.count == 3) {\n    NSNumber *target = @(components[0].integerValue);\n    NSNumber *batchID = @(components[1].integerValue);\n    NSDate *expirationDate = [NSDate dateWithTimeIntervalSince1970:components[2].doubleValue];\n    if (target == nil || batchID == nil || expirationDate == nil) {\n      GDTCORLogDebug(@\"There was an error parsing the batch filename components: %@\", components);\n      return nil;\n    }\n    return @{\n      kGDTCORBatchComponentsTargetKey : target,\n      kGDTCORBatchComponentsBatchIDKey : batchID,\n      kGDTCORBatchComponentsExpirationKey : expirationDate\n    };\n  }\n  GDTCORLogDebug(@\"The batch filename could not be split: %@\", fileName);\n  return nil;\n}\n\n#pragma mark - GDTCORLifecycleProtocol\n\n- (void)appWillBackground:(GDTCORApplication *)app {\n  dispatch_async(_storageQueue, ^{\n    // Immediately request a background task to run until the end of the current queue of work,\n    // and cancel it once the work is done.\n    __block GDTCORBackgroundIdentifier bgID =\n        [app beginBackgroundTaskWithName:@\"GDTStorage\"\n                       expirationHandler:^{\n                         [app endBackgroundTask:bgID];\n                         bgID = GDTCORBackgroundIdentifierInvalid;\n                       }];\n    // End the background task if it's still valid.\n    [app endBackgroundTask:bgID];\n    bgID = GDTCORBackgroundIdentifierInvalid;\n  });\n}\n\n- (void)appWillTerminate:(GDTCORApplication *)application {\n  dispatch_sync(_storageQueue, ^{\n                });\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORLifecycle.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer_Private.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadCoordinator.h\"\n\n@implementation GDTCORLifecycle\n\n+ (void)load {\n  [self sharedInstance];\n}\n\n/** Creates/returns the singleton instance of this class.\n *\n * @return The singleton instance of this class.\n */\n+ (instancetype)sharedInstance {\n  static GDTCORLifecycle *sharedInstance;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[GDTCORLifecycle alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n    [notificationCenter addObserver:self\n                           selector:@selector(applicationDidEnterBackground:)\n                               name:kGDTCORApplicationDidEnterBackgroundNotification\n                             object:nil];\n    [notificationCenter addObserver:self\n                           selector:@selector(applicationWillEnterForeground:)\n                               name:kGDTCORApplicationWillEnterForegroundNotification\n                             object:nil];\n\n    NSString *name = kGDTCORApplicationWillTerminateNotification;\n    [notificationCenter addObserver:self\n                           selector:@selector(applicationWillTerminate:)\n                               name:name\n                             object:nil];\n  }\n  return self;\n}\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (void)applicationDidEnterBackground:(NSNotification *)notification {\n  GDTCORApplication *application = [GDTCORApplication sharedApplication];\n  if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORTransformer that the app is backgrounding.\");\n    [[GDTCORTransformer sharedInstance] appWillBackground:application];\n  }\n  if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORUploadCoordinator that the app is backgrounding.\");\n    [[GDTCORUploadCoordinator sharedInstance] appWillBackground:application];\n  }\n  if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORRegistrar that the app is backgrounding.\");\n    [[GDTCORRegistrar sharedInstance] appWillBackground:application];\n  }\n}\n\n- (void)applicationWillEnterForeground:(NSNotification *)notification {\n  GDTCORApplication *application = [GDTCORApplication sharedApplication];\n  if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORTransformer that the app is foregrounding.\");\n    [[GDTCORTransformer sharedInstance] appWillForeground:application];\n  }\n  if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORUploadCoordinator that the app is foregrounding.\");\n    [[GDTCORUploadCoordinator sharedInstance] appWillForeground:application];\n  }\n  if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORRegistrar that the app is foregrounding.\");\n    [[GDTCORRegistrar sharedInstance] appWillForeground:application];\n  }\n}\n\n- (void)applicationWillTerminate:(NSNotification *)notification {\n  GDTCORApplication *application = [GDTCORApplication sharedApplication];\n  if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORTransformer that the app is terminating.\");\n    [[GDTCORTransformer sharedInstance] appWillTerminate:application];\n  }\n  if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORUploadCoordinator that the app is terminating.\");\n    [[GDTCORUploadCoordinator sharedInstance] appWillTerminate:application];\n  }\n  if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {\n    GDTCORLogDebug(@\"%@\", @\"Signaling GDTCORRegistrar that the app is terminating.\");\n    [[GDTCORRegistrar sharedInstance] appWillTerminate:application];\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORPlatform.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n\n#import <sys/sysctl.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n\n#ifdef GDTCOR_VERSION\n#define STR(x) STR_EXPAND(x)\n#define STR_EXPAND(x) #x\nNSString *const kGDTCORVersion = @STR(GDTCOR_VERSION);\n#else\nNSString *const kGDTCORVersion = @\"Unknown\";\n#endif  // GDTCOR_VERSION\n\nconst GDTCORBackgroundIdentifier GDTCORBackgroundIdentifierInvalid = 0;\n\nNSString *const kGDTCORApplicationDidEnterBackgroundNotification =\n    @\"GDTCORApplicationDidEnterBackgroundNotification\";\n\nNSString *const kGDTCORApplicationWillEnterForegroundNotification =\n    @\"GDTCORApplicationWillEnterForegroundNotification\";\n\nNSString *const kGDTCORApplicationWillTerminateNotification =\n    @\"GDTCORApplicationWillTerminateNotification\";\n\nNSURL *GDTCORRootDirectory(void) {\n  static NSURL *GDTPath;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    NSString *cachePath =\n        NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];\n    GDTPath =\n        [NSURL fileURLWithPath:[NSString stringWithFormat:@\"%@/google-sdks-events\", cachePath]];\n    GDTCORLogDebug(@\"GDT's state will be saved to: %@\", GDTPath);\n  });\n  NSError *error;\n  [[NSFileManager defaultManager] createDirectoryAtPath:GDTPath.path\n                            withIntermediateDirectories:YES\n                                             attributes:nil\n                                                  error:&error];\n  GDTCORAssert(error == nil, @\"There was an error creating GDT's path\");\n  return GDTPath;\n}\n\nBOOL GDTCORReachabilityFlagsReachable(GDTCORNetworkReachabilityFlags flags) {\n#if !TARGET_OS_WATCH\n  BOOL reachable =\n      (flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable;\n  BOOL connectionRequired = (flags & kSCNetworkReachabilityFlagsConnectionRequired) ==\n                            kSCNetworkReachabilityFlagsConnectionRequired;\n  return reachable && !connectionRequired;\n#else\n  return (flags & kGDTCORNetworkReachabilityFlagsReachable) ==\n         kGDTCORNetworkReachabilityFlagsReachable;\n#endif\n}\n\nBOOL GDTCORReachabilityFlagsContainWWAN(GDTCORNetworkReachabilityFlags flags) {\n#if TARGET_OS_IOS\n  return (flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN;\n#else\n  // Assume network connection not WWAN on macOS, tvOS, watchOS.\n  return NO;\n#endif  // TARGET_OS_IOS\n}\n\nGDTCORNetworkType GDTCORNetworkTypeMessage() {\n#if !TARGET_OS_WATCH\n  SCNetworkReachabilityFlags reachabilityFlags = [GDTCORReachability currentFlags];\n  if ((reachabilityFlags & kSCNetworkReachabilityFlagsReachable) ==\n      kSCNetworkReachabilityFlagsReachable) {\n    if (GDTCORReachabilityFlagsContainWWAN(reachabilityFlags)) {\n      return GDTCORNetworkTypeMobile;\n    } else {\n      return GDTCORNetworkTypeWIFI;\n    }\n  }\n#endif\n  return GDTCORNetworkTypeUNKNOWN;\n}\n\nGDTCORNetworkMobileSubtype GDTCORNetworkMobileSubTypeMessage() {\n#if TARGET_OS_IOS\n  static NSDictionary<NSString *, NSNumber *> *CTRadioAccessTechnologyToNetworkSubTypeMessage;\n  static CTTelephonyNetworkInfo *networkInfo;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    CTRadioAccessTechnologyToNetworkSubTypeMessage = @{\n      CTRadioAccessTechnologyGPRS : @(GDTCORNetworkMobileSubtypeGPRS),\n      CTRadioAccessTechnologyEdge : @(GDTCORNetworkMobileSubtypeEdge),\n      CTRadioAccessTechnologyWCDMA : @(GDTCORNetworkMobileSubtypeWCDMA),\n      CTRadioAccessTechnologyHSDPA : @(GDTCORNetworkMobileSubtypeHSDPA),\n      CTRadioAccessTechnologyHSUPA : @(GDTCORNetworkMobileSubtypeHSUPA),\n      CTRadioAccessTechnologyCDMA1x : @(GDTCORNetworkMobileSubtypeCDMA1x),\n      CTRadioAccessTechnologyCDMAEVDORev0 : @(GDTCORNetworkMobileSubtypeCDMAEVDORev0),\n      CTRadioAccessTechnologyCDMAEVDORevA : @(GDTCORNetworkMobileSubtypeCDMAEVDORevA),\n      CTRadioAccessTechnologyCDMAEVDORevB : @(GDTCORNetworkMobileSubtypeCDMAEVDORevB),\n      CTRadioAccessTechnologyeHRPD : @(GDTCORNetworkMobileSubtypeHRPD),\n      CTRadioAccessTechnologyLTE : @(GDTCORNetworkMobileSubtypeLTE),\n    };\n    networkInfo = [[CTTelephonyNetworkInfo alloc] init];\n  });\n  NSString *networkCurrentRadioAccessTechnology;\n#if TARGET_OS_MACCATALYST\n  NSDictionary<NSString *, NSString *> *networkCurrentRadioAccessTechnologyDict =\n      networkInfo.serviceCurrentRadioAccessTechnology;\n  if (networkCurrentRadioAccessTechnologyDict.count) {\n    networkCurrentRadioAccessTechnology = networkCurrentRadioAccessTechnologyDict.allValues[0];\n  }\n#else  // TARGET_OS_MACCATALYST\n  if (@available(iOS 12.0, *)) {\n    NSDictionary<NSString *, NSString *> *networkCurrentRadioAccessTechnologyDict =\n        networkInfo.serviceCurrentRadioAccessTechnology;\n    if (networkCurrentRadioAccessTechnologyDict.count) {\n      // In iOS 12, multiple radio technologies can be captured. We prefer not particular radio\n      // tech to another, so we'll just return the first value in the dictionary.\n      networkCurrentRadioAccessTechnology = networkCurrentRadioAccessTechnologyDict.allValues[0];\n    }\n  } else {\n#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED < 120000\n    networkCurrentRadioAccessTechnology = networkInfo.currentRadioAccessTechnology;\n#endif  // TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED < 120000\n  }\n#endif  // TARGET_OS_MACCATALYST\n  if (networkCurrentRadioAccessTechnology) {\n    NSNumber *networkMobileSubtype =\n        CTRadioAccessTechnologyToNetworkSubTypeMessage[networkCurrentRadioAccessTechnology];\n    return networkMobileSubtype.intValue;\n  } else {\n    return GDTCORNetworkMobileSubtypeUNKNOWN;\n  }\n#else   // TARGET_OS_IOS\n  return GDTCORNetworkMobileSubtypeUNKNOWN;\n#endif  // TARGET_OS_IOS\n}\n\nNSString *_Nonnull GDTCORDeviceModel() {\n  static NSString *deviceModel = @\"Unknown\";\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    size_t size;\n    char *keyToExtract = \"hw.machine\";\n    sysctlbyname(keyToExtract, NULL, &size, NULL, 0);\n    if (size > 0) {\n      char *machine = calloc(1, size);\n      sysctlbyname(keyToExtract, machine, &size, NULL, 0);\n      deviceModel = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];\n      free(machine);\n    } else {\n      deviceModel = [UIDevice currentDevice].model;\n    }\n  });\n#endif\n\n  return deviceModel;\n}\n\nNSData *_Nullable GDTCOREncodeArchive(id<NSSecureCoding> obj,\n                                      NSString *filePath,\n                                      NSError *_Nullable *error) {\n  BOOL result = NO;\n  if (filePath.length > 0) {\n    result = [[NSFileManager defaultManager]\n              createDirectoryAtPath:[filePath stringByDeletingLastPathComponent]\n        withIntermediateDirectories:YES\n                         attributes:nil\n                              error:error];\n    if (result == NO || *error) {\n      GDTCORLogDebug(@\"Attempt to create directory failed: path:%@ error:%@\", filePath, *error);\n      return nil;\n    }\n  }\n  NSData *resultData;\n  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4, *)) {\n    resultData = [NSKeyedArchiver archivedDataWithRootObject:obj\n                                       requiringSecureCoding:YES\n                                                       error:error];\n    if (resultData == nil || (error != NULL && *error != nil)) {\n      GDTCORLogDebug(@\"Encoding an object failed: %@\", *error);\n      return nil;\n    }\n    if (filePath.length > 0) {\n      result = [resultData writeToFile:filePath options:NSDataWritingAtomic error:error];\n      if (result == NO || *error) {\n        GDTCORLogDebug(@\"Attempt to write archive failed: path:%@ error:%@\", filePath, *error);\n      } else {\n        GDTCORLogDebug(@\"Writing archive succeeded: %@\", filePath);\n      }\n    }\n  } else {\n    @try {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n      resultData = [NSKeyedArchiver archivedDataWithRootObject:obj];\n#pragma clang diagnostic pop\n      if (filePath.length > 0) {\n        result = [resultData writeToFile:filePath options:NSDataWritingAtomic error:error];\n        if (result == NO || *error) {\n          GDTCORLogDebug(@\"Attempt to write archive failed: URL:%@ error:%@\", filePath, *error);\n        } else {\n          GDTCORLogDebug(@\"Writing archive succeeded: %@\", filePath);\n        }\n      }\n    } @catch (NSException *exception) {\n      NSString *errorString =\n          [NSString stringWithFormat:@\"An exception was thrown during encoding: %@\", exception];\n      *error = [NSError errorWithDomain:NSCocoaErrorDomain\n                                   code:-1\n                               userInfo:@{NSLocalizedFailureReasonErrorKey : errorString}];\n    }\n    if (filePath.length > 0) {\n      GDTCORLogDebug(@\"Attempt to write archive. successful:%@ URL:%@ error:%@\",\n                     result ? @\"YES\" : @\"NO\", filePath, *error);\n    }\n  }\n  return resultData;\n}\n\nid<NSSecureCoding> _Nullable GDTCORDecodeArchive(Class archiveClass,\n                                                 NSString *_Nullable archivePath,\n                                                 NSData *_Nullable archiveData,\n                                                 NSError *_Nullable *error) {\n  id<NSSecureCoding> unarchivedObject = nil;\n  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4, *)) {\n    NSData *data = archiveData ? archiveData : [NSData dataWithContentsOfFile:archivePath];\n    if (data) {\n      unarchivedObject = [NSKeyedUnarchiver unarchivedObjectOfClass:archiveClass\n                                                           fromData:data\n                                                              error:error];\n    }\n  } else {\n    @try {\n      NSData *archivedData =\n          archiveData ? archiveData : [NSData dataWithContentsOfFile:archivePath];\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n      unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];\n#pragma clang diagnostic pop\n    } @catch (NSException *exception) {\n      NSString *errorString =\n          [NSString stringWithFormat:@\"An exception was thrown during encoding: %@\", exception];\n      *error = [NSError errorWithDomain:NSCocoaErrorDomain\n                                   code:-1\n                               userInfo:@{NSLocalizedFailureReasonErrorKey : errorString}];\n    }\n  }\n  return unarchivedObject;\n}\n\nBOOL GDTCORWriteDataToFile(NSData *data, NSString *filePath, NSError *_Nullable *outError) {\n  BOOL result = NO;\n  if (filePath.length > 0) {\n    result = [[NSFileManager defaultManager]\n              createDirectoryAtPath:[filePath stringByDeletingLastPathComponent]\n        withIntermediateDirectories:YES\n                         attributes:nil\n                              error:outError];\n    if (result == NO || *outError) {\n      GDTCORLogDebug(@\"Attempt to create directory failed: path:%@ error:%@\", filePath, *outError);\n      return result;\n    }\n  }\n\n  if (filePath.length > 0) {\n    result = [data writeToFile:filePath options:NSDataWritingAtomic error:outError];\n    if (result == NO || *outError) {\n      GDTCORLogDebug(@\"Attempt to write archive failed: path:%@ error:%@\", filePath, *outError);\n    } else {\n      GDTCORLogDebug(@\"Writing archive succeeded: %@\", filePath);\n    }\n  }\n\n  return result;\n}\n\n@interface GDTCORApplication ()\n/**\n Private flag to match the existing `readonly` public flag. This will be accurate for all platforms,\n since we handle each platform's lifecycle notifications separately.\n */\n@property(atomic, readwrite) BOOL isRunningInBackground;\n\n@end\n\n@implementation GDTCORApplication\n\n#if TARGET_OS_WATCH\n/** A dispatch queue on which all task semaphores will populate and remove from\n * gBackgroundIdentifierToSemaphoreMap.\n */\nstatic dispatch_queue_t gSemaphoreQueue;\n\n/** For mapping backgroundIdentifier to task semaphore. */\nstatic NSMutableDictionary<NSNumber *, dispatch_semaphore_t> *gBackgroundIdentifierToSemaphoreMap;\n#endif\n\n+ (void)load {\n  GDTCORLogDebug(\n      @\"%@\", @\"GDT is initializing. Please note that if you quit the app via the \"\n              \"debugger and not through a lifecycle event, event data will remain on disk but \"\n              \"storage won't have a reference to them since the singleton wasn't saved to disk.\");\n#if TARGET_OS_IOS || TARGET_OS_TV\n  // If this asserts, please file a bug at https://github.com/firebase/firebase-ios-sdk/issues.\n  GDTCORFatalAssert(\n      GDTCORBackgroundIdentifierInvalid == UIBackgroundTaskInvalid,\n      @\"GDTCORBackgroundIdentifierInvalid and UIBackgroundTaskInvalid should be the same.\");\n#endif\n  [self sharedApplication];\n}\n\n+ (void)initialize {\n#if TARGET_OS_WATCH\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    gSemaphoreQueue = dispatch_queue_create(\"com.google.GDTCORApplication\", DISPATCH_QUEUE_SERIAL);\n    GDTCORLogDebug(\n        @\"%@\",\n        @\"GDTCORApplication is initializing on watchOS, gSemaphoreQueue has been initialized.\");\n    gBackgroundIdentifierToSemaphoreMap = [[NSMutableDictionary alloc] init];\n    GDTCORLogDebug(@\"%@\", @\"GDTCORApplication is initializing on watchOS, \"\n                          @\"gBackgroundIdentifierToSemaphoreMap has been initialized.\");\n  });\n#endif\n}\n\n+ (nullable GDTCORApplication *)sharedApplication {\n  static GDTCORApplication *application;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    application = [[GDTCORApplication alloc] init];\n  });\n  return application;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    // This class will be instantiated in the foreground.\n    _isRunningInBackground = NO;\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationDidEnterBackground:)\n                               name:UIApplicationDidEnterBackgroundNotification\n                             object:nil];\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationWillEnterForeground:)\n                               name:UIApplicationWillEnterForegroundNotification\n                             object:nil];\n\n    NSString *name = UIApplicationWillTerminateNotification;\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationWillTerminate:)\n                               name:name\n                             object:nil];\n\n#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000\n    if (@available(iOS 13, tvOS 13.0, *)) {\n      [notificationCenter addObserver:self\n                             selector:@selector(iOSApplicationWillEnterForeground:)\n                                 name:UISceneWillEnterForegroundNotification\n                               object:nil];\n      [notificationCenter addObserver:self\n                             selector:@selector(iOSApplicationDidEnterBackground:)\n                                 name:UISceneWillDeactivateNotification\n                               object:nil];\n    }\n#endif  // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000\n\n#elif TARGET_OS_OSX\n    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n    [notificationCenter addObserver:self\n                           selector:@selector(macOSApplicationWillTerminate:)\n                               name:NSApplicationWillTerminateNotification\n                             object:nil];\n\n#elif TARGET_OS_WATCH\n    // TODO: Notification on watchOS platform is currently posted by strings which are frangible.\n    // TODO: Needs improvements here.\n    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationDidEnterBackground:)\n                               name:@\"UIApplicationDidEnterBackgroundNotification\"\n                             object:nil];\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationWillEnterForeground:)\n                               name:@\"UIApplicationWillEnterForegroundNotification\"\n                             object:nil];\n\n    // Adds observers for app extension on watchOS platform\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationDidEnterBackground:)\n                               name:NSExtensionHostDidEnterBackgroundNotification\n                             object:nil];\n    [notificationCenter addObserver:self\n                           selector:@selector(iOSApplicationWillEnterForeground:)\n                               name:NSExtensionHostWillEnterForegroundNotification\n                             object:nil];\n#endif\n  }\n  return self;\n}\n\n#if TARGET_OS_WATCH\n/** Generates and maps a unique background identifier to the given semaphore.\n *\n * @param semaphore The semaphore to map.\n * @return A unique GDTCORBackgroundIdentifier mapped to the given semaphore.\n */\n+ (GDTCORBackgroundIdentifier)createAndMapBackgroundIdentifierToSemaphore:\n    (dispatch_semaphore_t)semaphore {\n  __block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;\n  dispatch_queue_t queue = gSemaphoreQueue;\n  NSMutableDictionary<NSNumber *, dispatch_semaphore_t> *map = gBackgroundIdentifierToSemaphoreMap;\n  if (queue && map) {\n    dispatch_sync(queue, ^{\n      bgID = arc4random();\n      NSNumber *bgIDNumber = @(bgID);\n      while (bgID == GDTCORBackgroundIdentifierInvalid || map[bgIDNumber]) {\n        bgID = arc4random();\n        bgIDNumber = @(bgID);\n      }\n      map[bgIDNumber] = semaphore;\n    });\n  }\n  return bgID;\n}\n\n/** Returns the semaphore mapped to given bgID and removes the value from the map.\n *\n * @param bgID The unique NSUInteger as GDTCORBackgroundIdentifier.\n * @return The semaphore mapped by given bgID.\n */\n+ (dispatch_semaphore_t)semaphoreForBackgroundIdentifier:(GDTCORBackgroundIdentifier)bgID {\n  __block dispatch_semaphore_t semaphore;\n  dispatch_queue_t queue = gSemaphoreQueue;\n  NSMutableDictionary<NSNumber *, dispatch_semaphore_t> *map = gBackgroundIdentifierToSemaphoreMap;\n  NSNumber *bgIDNumber = @(bgID);\n  if (queue && map) {\n    dispatch_sync(queue, ^{\n      semaphore = map[bgIDNumber];\n      [map removeObjectForKey:bgIDNumber];\n    });\n  }\n  return semaphore;\n}\n#endif\n\n- (GDTCORBackgroundIdentifier)beginBackgroundTaskWithName:(NSString *)name\n                                        expirationHandler:(void (^)(void))handler {\n  __block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;\n#if !TARGET_OS_WATCH\n  bgID = [[self sharedApplicationForBackgroundTask] beginBackgroundTaskWithName:name\n                                                              expirationHandler:handler];\n#if !NDEBUG\n  if (bgID != GDTCORBackgroundIdentifierInvalid) {\n    GDTCORLogDebug(@\"Creating background task with name:%@ bgID:%ld\", name, (long)bgID);\n  }\n#endif  // !NDEBUG\n#elif TARGET_OS_WATCH\n  dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);\n  bgID = [GDTCORApplication createAndMapBackgroundIdentifierToSemaphore:semaphore];\n  if (bgID != GDTCORBackgroundIdentifierInvalid) {\n    GDTCORLogDebug(@\"Creating activity with name:%@ bgID:%ld on watchOS.\", name, (long)bgID);\n  }\n  [[self sharedNSProcessInfoForBackgroundTask]\n      performExpiringActivityWithReason:name\n                             usingBlock:^(BOOL expired) {\n                               if (expired) {\n                                 if (handler) {\n                                   handler();\n                                 }\n                                 dispatch_semaphore_signal(semaphore);\n                                 GDTCORLogDebug(\n                                     @\"Activity with name:%@ bgID:%ld on watchOS is expiring.\",\n                                     name, (long)bgID);\n                               } else {\n                                 dispatch_semaphore_wait(\n                                     semaphore,\n                                     dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC));\n                               }\n                             }];\n#endif\n  return bgID;\n}\n\n- (void)endBackgroundTask:(GDTCORBackgroundIdentifier)bgID {\n#if !TARGET_OS_WATCH\n  if (bgID != GDTCORBackgroundIdentifierInvalid) {\n    GDTCORLogDebug(@\"Ending background task with ID:%ld was successful\", (long)bgID);\n    [[self sharedApplicationForBackgroundTask] endBackgroundTask:bgID];\n    return;\n  }\n#elif TARGET_OS_WATCH\n  if (bgID != GDTCORBackgroundIdentifierInvalid) {\n    dispatch_semaphore_t semaphore = [GDTCORApplication semaphoreForBackgroundIdentifier:bgID];\n    GDTCORLogDebug(@\"Ending activity with bgID:%ld on watchOS.\", (long)bgID);\n    if (semaphore) {\n      dispatch_semaphore_signal(semaphore);\n      GDTCORLogDebug(@\"Signaling semaphore with bgID:%ld on watchOS.\", (long)bgID);\n    } else {\n      GDTCORLogDebug(@\"Semaphore with bgID:%ld is nil on watchOS.\", (long)bgID);\n    }\n  }\n#endif  // !TARGET_OS_WATCH\n}\n\n#pragma mark - App environment helpers\n\n- (BOOL)isAppExtension {\n  BOOL appExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@\".appex\"];\n  return appExtension;\n}\n\n/** Returns a UIApplication or NSProcessInfo instance if on the appropriate platform.\n *\n * @return The shared UIApplication or NSProcessInfo if on the appropriate platform.\n */\n#if TARGET_OS_IOS || TARGET_OS_TV\n- (nullable UIApplication *)sharedApplicationForBackgroundTask {\n#elif TARGET_OS_WATCH\n- (nullable NSProcessInfo *)sharedNSProcessInfoForBackgroundTask {\n#else\n- (nullable id)sharedApplicationForBackgroundTask {\n#endif\n  id sharedInstance = nil;\n#if TARGET_OS_IOS || TARGET_OS_TV\n  if (![self isAppExtension]) {\n    Class uiApplicationClass = NSClassFromString(@\"UIApplication\");\n    if (uiApplicationClass &&\n        [uiApplicationClass respondsToSelector:(NSSelectorFromString(@\"sharedApplication\"))]) {\n      sharedInstance = [uiApplicationClass sharedApplication];\n    }\n  }\n#elif TARGET_OS_WATCH\n  sharedInstance = [NSProcessInfo processInfo];\n#endif\n  return sharedInstance;\n}\n\n#pragma mark - UIApplicationDelegate and WKExtensionDelegate\n\n#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH\n- (void)iOSApplicationDidEnterBackground:(NSNotification *)notif {\n  _isRunningInBackground = YES;\n\n  NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];\n  GDTCORLogDebug(@\"%@\", @\"GDTCORPlatform is sending a notif that the app is backgrounding.\");\n  [notifCenter postNotificationName:kGDTCORApplicationDidEnterBackgroundNotification object:nil];\n}\n\n- (void)iOSApplicationWillEnterForeground:(NSNotification *)notif {\n  _isRunningInBackground = NO;\n\n  NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];\n  GDTCORLogDebug(@\"%@\", @\"GDTCORPlatform is sending a notif that the app is foregrounding.\");\n  [notifCenter postNotificationName:kGDTCORApplicationWillEnterForegroundNotification object:nil];\n}\n#endif  // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH\n\n#pragma mark - UIApplicationDelegate\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n- (void)iOSApplicationWillTerminate:(NSNotification *)notif {\n  NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];\n  GDTCORLogDebug(@\"%@\", @\"GDTCORPlatform is sending a notif that the app is terminating.\");\n  [notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];\n}\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#pragma mark - NSApplicationDelegate\n\n#if TARGET_OS_OSX\n- (void)macOSApplicationWillTerminate:(NSNotification *)notif {\n  NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];\n  GDTCORLogDebug(@\"%@\", @\"GDTCORPlatform is sending a notif that the app is terminating.\");\n  [notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];\n}\n#endif  // TARGET_OS_OSX\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORReachability.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORReachability_Private.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\n#import <netinet/in.h>\n\n/** Sets the _callbackFlag ivar whenever the network changes.\n *\n * @param reachability The reachability object calling back.\n * @param flags The new flag values.\n * @param info Any data that might be passed in by the callback.\n */\nstatic void GDTCORReachabilityCallback(GDTCORNetworkReachabilityRef reachability,\n                                       GDTCORNetworkReachabilityFlags flags,\n                                       void *info);\n\n@implementation GDTCORReachability {\n  /** The reachability object. */\n  GDTCORNetworkReachabilityRef _reachabilityRef;\n\n  /** The queue on which callbacks and all work will occur. */\n  dispatch_queue_t _reachabilityQueue;\n\n  /** Flags specified by reachability callbacks. */\n  GDTCORNetworkReachabilityFlags _callbackFlags;\n}\n\n+ (void)initialize {\n  [self sharedInstance];\n}\n\n+ (instancetype)sharedInstance {\n  static GDTCORReachability *sharedInstance;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[GDTCORReachability alloc] init];\n  });\n  return sharedInstance;\n}\n\n+ (GDTCORNetworkReachabilityFlags)currentFlags {\n  __block GDTCORNetworkReachabilityFlags currentFlags;\n#if !TARGET_OS_WATCH\n  dispatch_sync([GDTCORReachability sharedInstance] -> _reachabilityQueue, ^{\n    GDTCORReachability *reachability = [GDTCORReachability sharedInstance];\n    currentFlags =\n        reachability->_callbackFlags ? reachability->_callbackFlags : reachability->_flags;\n    GDTCORLogDebug(@\"Initial reachability flags determined: %d\", currentFlags);\n  });\n#else\n  currentFlags = kGDTCORNetworkReachabilityFlagsReachable;\n#endif\n  return currentFlags;\n}\n\n- (instancetype)init {\n  self = [super init];\n#if !TARGET_OS_WATCH\n  if (self) {\n    struct sockaddr_in zeroAddress;\n    bzero(&zeroAddress, sizeof(zeroAddress));\n    zeroAddress.sin_len = sizeof(zeroAddress);\n    zeroAddress.sin_family = AF_INET;\n\n    _reachabilityQueue =\n        dispatch_queue_create(\"com.google.GDTCORReachability\", DISPATCH_QUEUE_SERIAL);\n    _reachabilityRef = SCNetworkReachabilityCreateWithAddress(\n        kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress);\n    Boolean success = SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _reachabilityQueue);\n    if (!success) {\n      GDTCORLogWarning(GDTCORMCWReachabilityFailed, @\"%@\", @\"The reachability queue wasn't set.\");\n    }\n    success = SCNetworkReachabilitySetCallback(_reachabilityRef, GDTCORReachabilityCallback, NULL);\n    if (!success) {\n      GDTCORLogWarning(GDTCORMCWReachabilityFailed, @\"%@\",\n                       @\"The reachability callback wasn't set.\");\n    }\n\n    // Get the initial set of flags.\n    dispatch_async(_reachabilityQueue, ^{\n      Boolean valid = SCNetworkReachabilityGetFlags(self->_reachabilityRef, &self->_flags);\n      if (!valid) {\n        GDTCORLogDebug(@\"%@\", @\"Determining reachability failed.\");\n        self->_flags = 0;\n      }\n    });\n  }\n#endif\n  return self;\n}\n\n- (void)setCallbackFlags:(GDTCORNetworkReachabilityFlags)flags {\n  if (_callbackFlags != flags) {\n    self->_callbackFlags = flags;\n  }\n}\n\n@end\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunused-function\"\nstatic void GDTCORReachabilityCallback(GDTCORNetworkReachabilityRef reachability,\n                                       GDTCORNetworkReachabilityFlags flags,\n                                       void *info) {\n#pragma clang diagnostic pop\n  GDTCORLogDebug(@\"Reachability changed, new flags: %d\", flags);\n  [[GDTCORReachability sharedInstance] setCallbackFlags:flags];\n}\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORRegistrar.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\nid<GDTCORStorageProtocol> _Nullable GDTCORStorageInstanceForTarget(GDTCORTarget target) {\n  return [GDTCORRegistrar sharedInstance].targetToStorage[@(target)];\n}\n\nFOUNDATION_EXPORT\nid<GDTCORStoragePromiseProtocol> _Nullable GDTCORStoragePromiseInstanceForTarget(\n    GDTCORTarget target) {\n  id storage = [GDTCORRegistrar sharedInstance].targetToStorage[@(target)];\n  if ([storage conformsToProtocol:@protocol(GDTCORStoragePromiseProtocol)]) {\n    return storage;\n  } else {\n    return nil;\n  }\n}\n\n@implementation GDTCORRegistrar {\n  /** Backing ivar for targetToUploader property. */\n  NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *_targetToUploader;\n\n  /** Backing ivar for targetToStorage property. */\n  NSMutableDictionary<NSNumber *, id<GDTCORStorageProtocol>> *_targetToStorage;\n}\n\n+ (instancetype)sharedInstance {\n  static GDTCORRegistrar *sharedInstance;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedInstance = [[GDTCORRegistrar alloc] init];\n  });\n  return sharedInstance;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _registrarQueue = dispatch_queue_create(\"com.google.GDTCORRegistrar\", DISPATCH_QUEUE_SERIAL);\n    _targetToUploader = [[NSMutableDictionary alloc] init];\n    _targetToStorage = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n- (void)registerUploader:(id<GDTCORUploader>)backend target:(GDTCORTarget)target {\n  __weak GDTCORRegistrar *weakSelf = self;\n  dispatch_async(_registrarQueue, ^{\n    GDTCORRegistrar *strongSelf = weakSelf;\n    if (strongSelf) {\n      GDTCORLogDebug(@\"Registered an uploader: %@ for target:%ld\", backend, (long)target);\n      strongSelf->_targetToUploader[@(target)] = backend;\n    }\n  });\n}\n\n- (void)registerStorage:(id<GDTCORStorageProtocol>)storage target:(GDTCORTarget)target {\n  __weak GDTCORRegistrar *weakSelf = self;\n  dispatch_async(_registrarQueue, ^{\n    GDTCORRegistrar *strongSelf = weakSelf;\n    if (strongSelf) {\n      GDTCORLogDebug(@\"Registered storage: %@ for target:%ld\", storage, (long)target);\n      strongSelf->_targetToStorage[@(target)] = storage;\n    }\n  });\n}\n\n- (NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *)targetToUploader {\n  __block NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *targetToUploader;\n  __weak GDTCORRegistrar *weakSelf = self;\n  dispatch_sync(_registrarQueue, ^{\n    GDTCORRegistrar *strongSelf = weakSelf;\n    if (strongSelf) {\n      targetToUploader = strongSelf->_targetToUploader;\n    }\n  });\n  return targetToUploader;\n}\n\n- (NSMutableDictionary<NSNumber *, id<GDTCORStorageProtocol>> *)targetToStorage {\n  __block NSMutableDictionary<NSNumber *, id<GDTCORStorageProtocol>> *targetToStorage;\n  __weak GDTCORRegistrar *weakSelf = self;\n  dispatch_sync(_registrarQueue, ^{\n    GDTCORRegistrar *strongSelf = weakSelf;\n    if (strongSelf) {\n      targetToStorage = strongSelf->_targetToStorage;\n    }\n  });\n  return targetToStorage;\n}\n\n#pragma mark - GDTCORLifecycleProtocol\n\n- (void)appWillBackground:(nonnull GDTCORApplication *)app {\n  NSArray<id<GDTCORUploader>> *uploaders = [self.targetToUploader allValues];\n  for (id<GDTCORUploader> uploader in uploaders) {\n    if ([uploader respondsToSelector:@selector(appWillBackground:)]) {\n      [uploader appWillBackground:app];\n    }\n  }\n  NSArray<id<GDTCORStorageProtocol>> *storages = [self.targetToStorage allValues];\n  for (id<GDTCORStorageProtocol> storage in storages) {\n    if ([storage respondsToSelector:@selector(appWillBackground:)]) {\n      [storage appWillBackground:app];\n    }\n  }\n}\n\n- (void)appWillForeground:(nonnull GDTCORApplication *)app {\n  NSArray<id<GDTCORUploader>> *uploaders = [self.targetToUploader allValues];\n  for (id<GDTCORUploader> uploader in uploaders) {\n    if ([uploader respondsToSelector:@selector(appWillForeground:)]) {\n      [uploader appWillForeground:app];\n    }\n  }\n  NSArray<id<GDTCORStorageProtocol>> *storages = [self.targetToStorage allValues];\n  for (id<GDTCORStorageProtocol> storage in storages) {\n    if ([storage respondsToSelector:@selector(appWillForeground:)]) {\n      [storage appWillForeground:app];\n    }\n  }\n}\n\n- (void)appWillTerminate:(nonnull GDTCORApplication *)app {\n  NSArray<id<GDTCORUploader>> *uploaders = [self.targetToUploader allValues];\n  for (id<GDTCORUploader> uploader in uploaders) {\n    if ([uploader respondsToSelector:@selector(appWillTerminate:)]) {\n      [uploader appWillTerminate:app];\n    }\n  }\n  NSArray<id<GDTCORStorageProtocol>> *storages = [self.targetToStorage allValues];\n  for (id<GDTCORStorageProtocol> storage in storages) {\n    if ([storage respondsToSelector:@selector(appWillTerminate:)]) {\n      [storage appWillTerminate:app];\n    }\n  }\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORStorageEventSelector.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h\"\n\n@implementation GDTCORStorageEventSelector\n\n+ (instancetype)eventSelectorForTarget:(GDTCORTarget)target {\n  return [[self alloc] initWithTarget:target eventIDs:nil mappingIDs:nil qosTiers:nil];\n}\n\n- (instancetype)initWithTarget:(GDTCORTarget)target\n                      eventIDs:(nullable NSSet<NSString *> *)eventIDs\n                    mappingIDs:(nullable NSSet<NSString *> *)mappingIDs\n                      qosTiers:(nullable NSSet<NSNumber *> *)qosTiers {\n  self = [super init];\n  if (self) {\n    _selectedTarget = target;\n    _selectedEventIDs = eventIDs;\n    _selectedMappingIDs = mappingIDs;\n    _selectedQosTiers = qosTiers;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORTransformer.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer_Private.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventTransformer.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n\n@implementation GDTCORTransformer\n\n+ (instancetype)sharedInstance {\n  static GDTCORTransformer *eventTransformer;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    eventTransformer = [[self alloc] init];\n  });\n  return eventTransformer;\n}\n\n- (instancetype)init {\n  return [self initWithApplication:[GDTCORApplication sharedApplication]];\n}\n\n- (instancetype)initWithApplication:(id<GDTCORApplicationProtocol>)application {\n  self = [super init];\n  if (self) {\n    _eventWritingQueue =\n        dispatch_queue_create(\"com.google.GDTCORTransformer\", DISPATCH_QUEUE_SERIAL);\n    _application = application;\n  }\n  return self;\n}\n\n- (void)transformEvent:(GDTCOREvent *)event\n      withTransformers:(NSArray<id<GDTCOREventTransformer>> *)transformers\n            onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {\n  GDTCORAssert(event, @\"You can't write a nil event\");\n\n  __block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;\n  __auto_type __weak weakApplication = self.application;\n  bgID = [self.application beginBackgroundTaskWithName:@\"GDTTransformer\"\n                                     expirationHandler:^{\n                                       [weakApplication endBackgroundTask:bgID];\n                                       bgID = GDTCORBackgroundIdentifierInvalid;\n                                     }];\n\n  __auto_type completionWrapper = ^(BOOL wasWritten, NSError *_Nullable error) {\n    if (completion) {\n      completion(wasWritten, error);\n    }\n\n    // The work is done, cancel the background task if it's valid.\n    [weakApplication endBackgroundTask:bgID];\n    bgID = GDTCORBackgroundIdentifierInvalid;\n  };\n\n  dispatch_async(_eventWritingQueue, ^{\n    GDTCOREvent *transformedEvent = event;\n    for (id<GDTCOREventTransformer> transformer in transformers) {\n      if ([transformer respondsToSelector:@selector(transformGDTEvent:)]) {\n        GDTCORLogDebug(@\"Applying a transformer to event %@\", event);\n        transformedEvent = [transformer transformGDTEvent:event];\n        if (!transformedEvent) {\n          completionWrapper(NO, nil);\n          return;\n        }\n      } else {\n        GDTCORLogError(GDTCORMCETransformerDoesntImplementTransform,\n                       @\"Transformer doesn't implement transformGDTEvent: %@\", transformer);\n        completionWrapper(NO, nil);\n        return;\n      }\n    }\n\n    id<GDTCORStorageProtocol> storage =\n        [GDTCORRegistrar sharedInstance].targetToStorage[@(event.target)];\n\n    [storage storeEvent:transformedEvent onComplete:completionWrapper];\n  });\n}\n\n#pragma mark - GDTCORLifecycleProtocol\n\n- (void)appWillTerminate:(GDTCORApplication *)application {\n  // Flush the queue immediately.\n  dispatch_sync(_eventWritingQueue, ^{\n                });\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORTransport.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTransport.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h\"\n\n@implementation GDTCORTransport\n\n- (nullable instancetype)initWithMappingID:(NSString *)mappingID\n                              transformers:\n                                  (nullable NSArray<id<GDTCOREventTransformer>> *)transformers\n                                    target:(GDTCORTarget)target {\n  GDTCORAssert(mappingID.length > 0, @\"A mapping ID cannot be nil or empty\");\n  GDTCORAssert(target > 0, @\"A target cannot be negative or 0\");\n  if (mappingID == nil || mappingID.length == 0 || target <= 0) {\n    return nil;\n  }\n  self = [super init];\n  if (self) {\n    _mappingID = mappingID;\n    _transformers = transformers;\n    _target = target;\n    _transformerInstance = [GDTCORTransformer sharedInstance];\n  }\n  GDTCORLogDebug(@\"Transport object created. mappingID:%@ transformers:%@ target:%ld\", mappingID,\n                 transformers, (long)target);\n  return self;\n}\n\n- (void)sendTelemetryEvent:(GDTCOREvent *)event\n                onComplete:\n                    (void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {\n  event.qosTier = GDTCOREventQoSTelemetry;\n  [self sendEvent:event onComplete:completion];\n}\n\n- (void)sendDataEvent:(GDTCOREvent *)event\n           onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {\n  GDTCORAssert(event.qosTier != GDTCOREventQoSTelemetry, @\"Use -sendTelemetryEvent, please.\");\n  [self sendEvent:event onComplete:completion];\n}\n\n- (void)sendTelemetryEvent:(GDTCOREvent *)event {\n  [self sendTelemetryEvent:event onComplete:nil];\n}\n\n- (void)sendDataEvent:(GDTCOREvent *)event {\n  [self sendDataEvent:event onComplete:nil];\n}\n\n- (GDTCOREvent *)eventForTransport {\n  return [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];\n}\n\n#pragma mark - Private helper methods\n\n/** Sends the given event through the transport pipeline.\n *\n * @param event The event to send.\n * @param completion A block that will be called when the event has been written or dropped.\n */\n- (void)sendEvent:(GDTCOREvent *)event\n       onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {\n  // TODO: Determine if sending an event before registration is allowed.\n  GDTCORAssert(event, @\"You can't send a nil event\");\n  GDTCOREvent *copiedEvent = [event copy];\n  copiedEvent.clockSnapshot = [GDTCORClock snapshot];\n  [self.transformerInstance transformEvent:copiedEvent\n                          withTransformers:_transformers\n                                onComplete:completion];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORUploadBatch.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadBatch.h\"\n\n@implementation GDTCORUploadBatch\n\n- (instancetype)initWithBatchID:(NSNumber *)batchID events:(NSSet<GDTCOREvent *> *)events {\n  self = [super init];\n  if (self) {\n    _batchID = batchID;\n    _events = events;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/GDTCORUploadCoordinator.m",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadCoordinator.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h\"\n\n@implementation GDTCORUploadCoordinator\n\n+ (instancetype)sharedInstance {\n  static GDTCORUploadCoordinator *sharedUploader;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sharedUploader = [[GDTCORUploadCoordinator alloc] init];\n    [sharedUploader startTimer];\n  });\n  return sharedUploader;\n}\n\n- (instancetype)init {\n  self = [super init];\n  if (self) {\n    _coordinationQueue =\n        dispatch_queue_create(\"com.google.GDTCORUploadCoordinator\", DISPATCH_QUEUE_SERIAL);\n    _registrar = [GDTCORRegistrar sharedInstance];\n    _timerInterval = 30 * NSEC_PER_SEC;\n    _timerLeeway = 5 * NSEC_PER_SEC;\n  }\n  return self;\n}\n\n- (void)forceUploadForTarget:(GDTCORTarget)target {\n  dispatch_async(_coordinationQueue, ^{\n    GDTCORLogDebug(@\"Forcing an upload of target %ld\", (long)target);\n    GDTCORUploadConditions conditions = [self uploadConditions];\n    conditions |= GDTCORUploadConditionHighPriority;\n    [self uploadTargets:@[ @(target) ] conditions:conditions];\n  });\n}\n\n#pragma mark - Private helper methods\n\n/** Starts a timer that checks whether or not events can be uploaded at regular intervals. It will\n * check the next-upload clocks of all targets to determine if an upload attempt can be made.\n */\n- (void)startTimer {\n  dispatch_async(_coordinationQueue, ^{\n    if (self->_timer) {\n      // The timer has been already started.\n      return;\n    }\n\n    // Delay the timer slightly so it doesn't run while +load calls are still running.\n    dispatch_time_t deadline = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC / 2);\n\n    self->_timer =\n        dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self->_coordinationQueue);\n    dispatch_source_set_timer(self->_timer, deadline, self->_timerInterval, self->_timerLeeway);\n\n    dispatch_source_set_event_handler(self->_timer, ^{\n      if (![[GDTCORApplication sharedApplication] isRunningInBackground]) {\n        GDTCORUploadConditions conditions = [self uploadConditions];\n        GDTCORLogDebug(@\"%@\", @\"Upload timer fired\");\n        [self uploadTargets:[self.registrar.targetToUploader allKeys] conditions:conditions];\n      }\n    });\n    GDTCORLogDebug(@\"%@\", @\"Upload timer started\");\n    dispatch_resume(self->_timer);\n  });\n}\n\n/** Stops the currently running timer. */\n- (void)stopTimer {\n  if (_timer) {\n    dispatch_source_cancel(_timer);\n    _timer = nil;\n  }\n}\n\n/** Triggers the uploader implementations for the given targets to upload.\n *\n * @param targets An array of targets to trigger.\n * @param conditions The set of upload conditions.\n */\n- (void)uploadTargets:(NSArray<NSNumber *> *)targets conditions:(GDTCORUploadConditions)conditions {\n  dispatch_async(_coordinationQueue, ^{\n    // TODO: The reachability signal may be not reliable enough to prevent an upload attempt.\n    // See https://developer.apple.com/videos/play/wwdc2019/712/ (49:40) for more details.\n    if ((conditions & GDTCORUploadConditionNoNetwork) == GDTCORUploadConditionNoNetwork) {\n      return;\n    }\n    for (NSNumber *target in targets) {\n      id<GDTCORUploader> uploader = self->_registrar.targetToUploader[target];\n      [uploader uploadTarget:target.intValue withConditions:conditions];\n    }\n  });\n}\n\n- (void)signalToStoragesToCheckExpirations {\n  // The same storage may be associated with several targets. Make sure to check for expirations\n  // only once per storage.\n  NSSet<id<GDTCORStorageProtocol>> *storages =\n      [NSSet setWithArray:[_registrar.targetToStorage allValues]];\n  for (id<GDTCORStorageProtocol> storage in storages) {\n    [storage checkForExpirations];\n  }\n}\n\n/** Returns the registered storage for the given NSNumber wrapped GDTCORTarget.\n *\n * @param target The NSNumber wrapping of a GDTCORTarget to find the storage instance of.\n * @return The storage instance for the given target.\n */\n- (nullable id<GDTCORStorageProtocol>)storageForTarget:(NSNumber *)target {\n  id<GDTCORStorageProtocol> storage = [GDTCORRegistrar sharedInstance].targetToStorage[target];\n  GDTCORAssert(storage, @\"A storage must be registered for target %@\", target);\n  return storage;\n}\n\n/** Returns the current upload conditions after making determinations about the network connection.\n *\n * @return The current upload conditions.\n */\n- (GDTCORUploadConditions)uploadConditions {\n  GDTCORNetworkReachabilityFlags currentFlags = [GDTCORReachability currentFlags];\n  BOOL networkConnected = GDTCORReachabilityFlagsReachable(currentFlags);\n  if (!networkConnected) {\n    return GDTCORUploadConditionNoNetwork;\n  }\n  BOOL isWWAN = GDTCORReachabilityFlagsContainWWAN(currentFlags);\n  if (isWWAN) {\n    return GDTCORUploadConditionMobileData;\n  } else {\n    return GDTCORUploadConditionWifiData;\n  }\n}\n\n#pragma mark - GDTCORLifecycleProtocol\n\n- (void)appWillForeground:(GDTCORApplication *)app {\n  // -startTimer is thread-safe.\n  [self startTimer];\n  [self signalToStoragesToCheckExpirations];\n}\n\n- (void)appWillBackground:(GDTCORApplication *)app {\n  dispatch_async(_coordinationQueue, ^{\n    [self stopTimer];\n  });\n}\n\n- (void)appWillTerminate:(GDTCORApplication *)application {\n  dispatch_sync(_coordinationQueue, ^{\n    [self stopTimer];\n  });\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A block type that could be run instead of normal assertion logging. No return type, no params.\n */\ntypedef void (^GDTCORAssertionBlock)(void);\n\n/** Returns the result of executing a soft-linked method present in unit tests that allows a block\n * to be run instead of normal assertion logging. This helps ameliorate issues with catching\n * exceptions that occur on a dispatch_queue.\n *\n * @return A block that can be run instead of normal assert printing.\n */\nFOUNDATION_EXPORT GDTCORAssertionBlock _Nullable GDTCORAssertionBlockToRunInstead(void);\n\n#if defined(NS_BLOCK_ASSERTIONS)\n\n#define GDTCORAssert(condition, ...) \\\n  do {                               \\\n  } while (0);\n\n#define GDTCORFatalAssert(condition, ...) \\\n  do {                                    \\\n  } while (0);\n\n#else  // defined(NS_BLOCK_ASSERTIONS)\n\n/** Asserts using a console log, unless a block was specified to be run instead.\n *\n * @param condition The condition you'd expect to be YES.\n */\n#define GDTCORAssert(condition, format, ...)                                     \\\n  do {                                                                           \\\n    __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS                                          \\\n    if (__builtin_expect(!(condition), 0)) {                                     \\\n      GDTCORAssertionBlock assertionBlock = GDTCORAssertionBlockToRunInstead();  \\\n      if (assertionBlock) {                                                      \\\n        assertionBlock();                                                        \\\n      } else {                                                                   \\\n        NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__];    \\\n        __assert_file__ = __assert_file__ ? __assert_file__ : @\"<Unknown File>\"; \\\n        GDTCORLogAssert(NO, __assert_file__, __LINE__, format, ##__VA_ARGS__);   \\\n        __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS                                       \\\n      }                                                                          \\\n    }                                                                            \\\n  } while (0);\n\n/** Asserts by logging to the console and throwing an exception if NS_BLOCK_ASSERTIONS is not\n * defined.\n *\n * @param condition The condition you'd expect to be YES.\n */\n#define GDTCORFatalAssert(condition, format, ...)                                          \\\n  do {                                                                                     \\\n    __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS                                                    \\\n    if (__builtin_expect(!(condition), 0)) {                                               \\\n      GDTCORAssertionBlock assertionBlock = GDTCORAssertionBlockToRunInstead();            \\\n      if (assertionBlock) {                                                                \\\n        assertionBlock();                                                                  \\\n      } else {                                                                             \\\n        NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__];              \\\n        __assert_file__ = __assert_file__ ? __assert_file__ : @\"<Unknown File>\";           \\\n        GDTCORLogAssert(YES, __assert_file__, __LINE__, format, ##__VA_ARGS__);            \\\n        [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd                    \\\n                                                            object:self                    \\\n                                                              file:__assert_file__         \\\n                                                        lineNumber:__LINE__                \\\n                                                       description:format, ##__VA_ARGS__]; \\\n        __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS                                                 \\\n      }                                                                                    \\\n    }                                                                                      \\\n  } while (0);\n\n#endif  // defined(NS_BLOCK_ASSERTIONS)\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORDirectorySizeTracker.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The class calculates and caches the specified directory content size and uses add/remove signals\n *  from client the client to keep the size up to date without accessing file system.\n *  This is an internal class designed to be used by `GDTCORFlatFileStorage`.\n *  NOTE: The class is not thread-safe. The client must take care of synchronization.\n */\n@interface GDTCORDirectorySizeTracker : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** Initializes the object with a directory path.\n * @param path The directory path to track content size.\n */\n- (instancetype)initWithDirectoryPath:(NSString *)path;\n\n/** Returns a cached or calculates (if there is no cached) directory content size.\n * @return The directory content size in bytes calculated based on `NSURLFileSizeKey`.\n */\n- (GDTCORStorageSizeBytes)directoryContentSize;\n\n/** The client must call this method or `resetCachedSize` method each time a file or directory is\n * added to the tracked directory.\n *  @param path The path to the added file. If the path is outside the tracked directory then the\n *  @param fileSize The size of the added file.\n * method is no-op.\n */\n- (void)fileWasAddedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize;\n\n/** The client must call this method or `resetCachedSize` method each time a file or directory is\n * removed from the tracked directory.\n *  @param path The path to the removed file. If the path is outside the tracked directory then the\n *  @param fileSize The size of the removed file.\n * method is no-op.\n */\n- (void)fileWasRemovedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize;\n\n/** Invalidates cached directory size. */\n- (void)resetCachedSize;\n\n/** Returns URL resource value for `NSURLFileSizeKey` key for the specified URL. */\n- (GDTCORStorageSizeBytes)fileSizeAtURL:(NSURL *)fileURL;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n\n@class GDTCOREvent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** A protocol defining the lifecycle events objects in the library must respond to immediately. */\n@protocol GDTCORLifecycleProtocol <NSObject>\n\n@optional\n\n/** Indicates an imminent app termination in the rare occurrence when -applicationWillTerminate: has\n * been called.\n *\n * @param app The GDTCORApplication instance.\n */\n- (void)appWillTerminate:(GDTCORApplication *)app;\n\n/** Indicates that the app is moving to background and eventual suspension or the current UIScene is\n * deactivating.\n *\n * @param app The GDTCORApplication instance.\n */\n- (void)appWillBackground:(GDTCORApplication *)app;\n\n/** Indicates that the app is resuming operation or a UIScene is activating.\n *\n * @param app The GDTCORApplication instance.\n */\n- (void)appWillForeground:(GDTCORApplication *)app;\n\n@end\n\n/** This class manages the library's response to app lifecycle events.\n *\n * When backgrounding, the library doesn't stop processing events, it's just that several background\n * tasks will end up being created for every event that's sent, and the stateful objects of the\n * library (GDTCORStorage and GDTCORUploadCoordinator instances) will deserialize themselves from\n * and to disk before and after every operation, respectively.\n */\n@interface GDTCORLifecycle : NSObject <GDTCORApplicationDelegate>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#if !TARGET_OS_WATCH\n#import <SystemConfiguration/SystemConfiguration.h>\n#endif\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n#import <UIKit/UIKit.h>\n#elif TARGET_OS_OSX\n#import <AppKit/AppKit.h>\n#elif TARGET_OS_WATCH\n#import <WatchKit/WatchKit.h>\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#if TARGET_OS_IOS\n#import <CoreTelephony/CTTelephonyNetworkInfo.h>\n#endif\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The GoogleDataTransport library version. */\nFOUNDATION_EXPORT NSString *const kGDTCORVersion;\n\n/** A notification sent out if the app is backgrounding. */\nFOUNDATION_EXPORT NSString *const kGDTCORApplicationDidEnterBackgroundNotification;\n\n/** A notification sent out if the app is foregrounding. */\nFOUNDATION_EXPORT NSString *const kGDTCORApplicationWillEnterForegroundNotification;\n\n/** A notification sent out if the app is terminating. */\nFOUNDATION_EXPORT NSString *const kGDTCORApplicationWillTerminateNotification;\n\n/** The different possible network connection type. */\ntypedef NS_ENUM(NSInteger, GDTCORNetworkType) {\n  GDTCORNetworkTypeUNKNOWN = 0,\n  GDTCORNetworkTypeWIFI = 1,\n  GDTCORNetworkTypeMobile = 2,\n};\n\n/** The different possible network connection mobile subtype. */\ntypedef NS_ENUM(NSInteger, GDTCORNetworkMobileSubtype) {\n  GDTCORNetworkMobileSubtypeUNKNOWN = 0,\n  GDTCORNetworkMobileSubtypeGPRS = 1,\n  GDTCORNetworkMobileSubtypeEdge = 2,\n  GDTCORNetworkMobileSubtypeWCDMA = 3,\n  GDTCORNetworkMobileSubtypeHSDPA = 4,\n  GDTCORNetworkMobileSubtypeHSUPA = 5,\n  GDTCORNetworkMobileSubtypeCDMA1x = 6,\n  GDTCORNetworkMobileSubtypeCDMAEVDORev0 = 7,\n  GDTCORNetworkMobileSubtypeCDMAEVDORevA = 8,\n  GDTCORNetworkMobileSubtypeCDMAEVDORevB = 9,\n  GDTCORNetworkMobileSubtypeHRPD = 10,\n  GDTCORNetworkMobileSubtypeLTE = 11,\n};\n\n#if !TARGET_OS_WATCH\n/** Define SCNetworkReachabilityFlags as GDTCORNetworkReachabilityFlags on non-watchOS. */\ntypedef SCNetworkReachabilityFlags GDTCORNetworkReachabilityFlags;\n\n/** Define SCNetworkReachabilityRef as GDTCORNetworkReachabilityRef on non-watchOS. */\ntypedef SCNetworkReachabilityRef GDTCORNetworkReachabilityRef;\n\n#else\n/** The different possible reachabilityFlags option on watchOS. */\ntypedef NS_OPTIONS(uint32_t, GDTCORNetworkReachabilityFlags) {\n  kGDTCORNetworkReachabilityFlagsReachable = 1 << 1,\n  // TODO(doudounan): Add more options on watchOS if watchOS network connection information relative\n  // APIs available in the future.\n};\n\n/** Define a struct as GDTCORNetworkReachabilityRef on watchOS to store network connection\n * information. */\ntypedef struct {\n  // TODO(doudounan): Store network connection information on watchOS if watchOS network connection\n  // information relative APIs available in the future.\n} GDTCORNetworkReachabilityRef;\n#endif\n\n/** Returns a URL to the root directory under which all GDT-associated data must be saved.\n *\n * @return A URL to the root directory under which all GDT-associated data must be saved.\n */\nNSURL *GDTCORRootDirectory(void);\n\n/** Compares flags with the reachable flag (on non-watchos with both reachable and\n * connectionRequired flags), if available, and returns YES if network reachable.\n *\n * @param flags The set of reachability flags.\n * @return YES if the network is reachable, NO otherwise.\n */\nBOOL GDTCORReachabilityFlagsReachable(GDTCORNetworkReachabilityFlags flags);\n\n/** Compares flags with the WWAN reachability flag, if available, and returns YES if present.\n *\n * @param flags The set of reachability flags.\n * @return YES if the WWAN flag is set, NO otherwise.\n */\nBOOL GDTCORReachabilityFlagsContainWWAN(GDTCORNetworkReachabilityFlags flags);\n\n/** Generates an enum message GDTCORNetworkType representing network connection type.\n *\n * @return A GDTCORNetworkType representing network connection type.\n */\nGDTCORNetworkType GDTCORNetworkTypeMessage(void);\n\n/** Generates an enum message GDTCORNetworkMobileSubtype representing network connection mobile\n * subtype.\n *\n * @return A GDTCORNetworkMobileSubtype representing network connection mobile subtype.\n */\nGDTCORNetworkMobileSubtype GDTCORNetworkMobileSubTypeMessage(void);\n\n/** Identifies the model of the device on which the library is currently working on.\n *\n * @return A NSString representing the device model.\n */\nNSString *_Nonnull GDTCORDeviceModel(void);\n\n/** Writes the given object to the given fileURL and populates the given error if it fails.\n *\n * @param obj The object to encode.\n * @param filePath The path to write the object to. Can be nil if you just need the data.\n * @param error The error to populate if something goes wrong.\n * @return The data of the archive. If error is nil, it's been written to disk.\n */\nNSData *_Nullable GDTCOREncodeArchive(id<NSSecureCoding> obj,\n                                      NSString *_Nullable filePath,\n                                      NSError *_Nullable *error);\n\n/** Decodes an object of the given class from the given archive path or data and populates the given\n * error if it fails.\n *\n * @param archiveClass The class of the archive's root object.\n * @param archivePath The path to the archived data. Don't use with the archiveData param.\n * @param archiveData The data to decode. Don't use with the archivePath param.\n * @param error The error to populate if something goes wrong.\n */\nid<NSSecureCoding> _Nullable GDTCORDecodeArchive(Class archiveClass,\n                                                 NSString *_Nullable archivePath,\n                                                 NSData *_Nullable archiveData,\n                                                 NSError *_Nullable *error);\n\n/** Writes the provided data to a file at the provided  path. Intermediate directories will be\n * created as needed.\n *  @param data The file content.\n *  @param filePath The path to the file to write the provided data.\n *  @param outError The error to populate if something goes wrong.\n *  @return `YES` in the case of success, `NO` otherwise.\n */\nBOOL GDTCORWriteDataToFile(NSData *data, NSString *filePath, NSError *_Nullable *outError);\n\n/** A typedef identify background identifiers. */\ntypedef volatile NSUInteger GDTCORBackgroundIdentifier;\n\n/** A background task's invalid sentinel value. */\nFOUNDATION_EXPORT const GDTCORBackgroundIdentifier GDTCORBackgroundIdentifierInvalid;\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n/** A protocol that wraps UIApplicationDelegate, WKExtensionDelegate or NSObject protocol, depending\n * on the platform.\n */\n@protocol GDTCORApplicationDelegate <UIApplicationDelegate>\n#elif TARGET_OS_OSX\n@protocol GDTCORApplicationDelegate <NSApplicationDelegate>\n#elif TARGET_OS_WATCH\n@protocol GDTCORApplicationDelegate <WKExtensionDelegate>\n#else\n@protocol GDTCORApplicationDelegate <NSObject>\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n@end\n\n@protocol GDTCORApplicationProtocol <NSObject>\n\n@required\n\n/** Flag to determine if the application is running in the background. */\n@property(atomic, readonly) BOOL isRunningInBackground;\n\n/** Creates a background task with the returned identifier if on a suitable platform.\n *\n * @name name The name of the task, useful for debugging which background tasks are running.\n * @param handler The handler block that is called if the background task expires.\n * @return An identifier for the background task, or GDTCORBackgroundIdentifierInvalid if one\n * couldn't be created.\n */\n- (GDTCORBackgroundIdentifier)beginBackgroundTaskWithName:(NSString *)name\n                                        expirationHandler:(void (^__nullable)(void))handler;\n\n/** Ends the background task if the identifier is valid.\n *\n * @param bgID The background task to end.\n */\n- (void)endBackgroundTask:(GDTCORBackgroundIdentifier)bgID;\n\n@end\n\n/** A cross-platform application class. */\n@interface GDTCORApplication : NSObject <GDTCORApplicationProtocol, GDTCORApplicationDelegate>\n\n/** Creates and/or returns the shared application instance.\n *\n * @return The shared application instance.\n */\n+ (nullable GDTCORApplication *)sharedApplication;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class helps determine upload conditions by determining connectivity. */\n@interface GDTCORReachability : NSObject\n\n/** The current set flags indicating network conditions */\n+ (GDTCORNetworkReachabilityFlags)currentFlags;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORUploader.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Manages the registration of targets with the transport SDK. */\n@interface GDTCORRegistrar : NSObject <GDTCORLifecycleProtocol>\n\n/** Creates and/or returns the singleton instance.\n *\n * @return The singleton instance of this class.\n */\n+ (instancetype)sharedInstance;\n\n/** Registers a backend implementation with the GoogleDataTransport infrastructure.\n *\n * @param backend The backend object to register.\n * @param target The target this backend object will be responsible for.\n */\n- (void)registerUploader:(id<GDTCORUploader>)backend target:(GDTCORTarget)target;\n\n/** Registers a storage implementation with the GoogleDataTransport infrastructure.\n *\n * @param storage The storage instance to be associated with this uploader and target.\n * @param target The target this backend object will be responsible for.\n */\n- (void)registerStorage:(id<GDTCORStorageProtocol>)storage target:(GDTCORTarget)target;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class enables the finding of events by matching events with the properties of this class.\n */\n@interface GDTCORStorageEventSelector : NSObject\n\n/** The target to find events for. Required. */\n@property(readonly, nonatomic) GDTCORTarget selectedTarget;\n\n/** Finds a specific event. */\n@property(nullable, readonly, nonatomic) NSSet<NSString *> *selectedEventIDs;\n\n/** Finds all events of a mappingID. */\n@property(nullable, readonly, nonatomic) NSSet<NSString *> *selectedMappingIDs;\n\n/** Finds all events matching the qosTiers in this list. */\n@property(nullable, readonly, nonatomic) NSSet<NSNumber *> *selectedQosTiers;\n\n/** Initializes an event selector that will find all events for the given target.\n *\n * @param target The selected target.\n * @return An immutable event selector instance.\n */\n+ (instancetype)eventSelectorForTarget:(GDTCORTarget)target;\n\n/** Instantiates an event selector.\n *\n * @param target The selected target.\n * @param eventIDs Optional param to find an event matching this eventID.\n * @param mappingIDs Optional param to find events matching this mappingID.\n * @param qosTiers Optional param to find events matching the given QoS tiers.\n * @return An immutable event selector instance.\n */\n- (instancetype)initWithTarget:(GDTCORTarget)target\n                      eventIDs:(nullable NSSet<NSString *> *)eventIDs\n                    mappingIDs:(nullable NSSet<NSString *> *)mappingIDs\n                      qosTiers:(nullable NSSet<NSNumber *> *)qosTiers;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h\"\n\n@class GDTCOREvent;\n@class GDTCORClock;\n@class GDTCORUploadBatch;\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The data type to represent storage size. */\ntypedef uint64_t GDTCORStorageSizeBytes;\n\ntypedef void (^GDTCORStorageBatchBlock)(NSNumber *_Nullable newBatchID,\n                                        NSSet<GDTCOREvent *> *_Nullable batchEvents);\n\n/** Defines the interface a storage subsystem is expected to implement. */\n@protocol GDTCORStorageProtocol <NSObject, GDTCORLifecycleProtocol>\n\n@required\n\n/** Stores an event and calls onComplete with a non-nil error if anything went wrong.\n *\n * @param event The event to store\n * @param completion The completion block to call after an attempt to store the event has been made.\n */\n- (void)storeEvent:(GDTCOREvent *)event\n        onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion;\n\n/** Returns YES if some events have been stored for the given target, NO otherwise.\n *\n * @param onComplete The completion block to invoke when determining if there are events is done.\n */\n- (void)hasEventsForTarget:(GDTCORTarget)target onComplete:(void (^)(BOOL hasEvents))onComplete;\n\n/** Constructs an event batch with the given event selector. Events in this batch will not be\n * returned in any queries or other batches until the batch is removed.\n *\n * @param eventSelector The event selector used to find the events.\n * @param expiration The expiration time of the batch. If removeBatchWithID:deleteEvents:onComplete:\n * is not called within this time frame, the batch will be removed with its events deleted.\n * @param onComplete The completion handler to be called when the events have been fetched.\n */\n- (void)batchWithEventSelector:(nonnull GDTCORStorageEventSelector *)eventSelector\n               batchExpiration:(nonnull NSDate *)expiration\n                    onComplete:(nonnull GDTCORStorageBatchBlock)onComplete;\n\n/** Removes the event batch.\n *\n * @param batchID The batchID to remove.\n * @param deleteEvents If YES, the events in this batch are deleted.\n * @param onComplete The completion handler to call when the batch removal process has completed.\n */\n- (void)removeBatchWithID:(NSNumber *)batchID\n             deleteEvents:(BOOL)deleteEvents\n               onComplete:(void (^_Nullable)(void))onComplete;\n\n/** Finds the batchIDs for the given target and calls the callback block.\n *\n * @param target The target.\n * @param onComplete The block to invoke with the set of current batchIDs.\n */\n- (void)batchIDsForTarget:(GDTCORTarget)target\n               onComplete:(void (^)(NSSet<NSNumber *> *_Nullable batchIDs))onComplete;\n\n/** Checks the storage for expired events and batches, deletes them if they're expired. */\n- (void)checkForExpirations;\n\n/** Persists the given data with the given key.\n *\n * @param data The data to store.\n * @param key The unique key to store it to.\n * @param onComplete An block to be run when storage of the data is complete.\n */\n- (void)storeLibraryData:(NSData *)data\n                  forKey:(NSString *)key\n              onComplete:(nullable void (^)(NSError *_Nullable error))onComplete;\n\n/** Retrieves the stored data for the given key and optionally sets a new value.\n *\n * @param key The key corresponding to the desired data.\n * @param onFetchComplete The callback to invoke with the data once it's retrieved.\n * @param setValueBlock This optional block can provide a new value to set.\n */\n- (void)libraryDataForKey:(nonnull NSString *)key\n          onFetchComplete:(nonnull void (^)(NSData *_Nullable data,\n                                            NSError *_Nullable error))onFetchComplete\n              setNewValue:(NSData *_Nullable (^_Nullable)(void))setValueBlock;\n\n/** Removes data from storage and calls the callback when complete.\n *\n * @param key The key of the data to remove.\n * @param onComplete The callback that will be invoked when removing the data is complete.\n */\n- (void)removeLibraryDataForKey:(NSString *)key\n                     onComplete:(void (^)(NSError *_Nullable error))onComplete;\n\n/** Calculates and returns the total disk size that this storage consumes.\n *\n * @param onComplete The callback that will be invoked once storage size calculation is complete.\n */\n- (void)storageSizeWithCallback:(void (^)(GDTCORStorageSizeBytes storageSize))onComplete;\n\n@end\n\n// TODO: Consider complete replacing block based API by promise API.\n\n/** Promise based version of API defined in GDTCORStorageProtocol. See API docs for corresponding\n * methods in GDTCORStorageProtocol. */\n@protocol GDTCORStoragePromiseProtocol <GDTCORStorageProtocol>\n\n- (FBLPromise<NSSet<NSNumber *> *> *)batchIDsForTarget:(GDTCORTarget)target;\n\n- (FBLPromise<NSNull *> *)removeBatchWithID:(NSNumber *)batchID deleteEvents:(BOOL)deleteEvents;\n\n- (FBLPromise<NSNull *> *)removeBatchesWithIDs:(NSSet<NSNumber *> *)batchIDs\n                                  deleteEvents:(BOOL)deleteEvents;\n\n- (FBLPromise<NSNull *> *)removeAllBatchesForTarget:(GDTCORTarget)target\n                                       deleteEvents:(BOOL)deleteEvents;\n\n/** See `hasEventsForTarget:onComplete:`.\n *  @return A promise object that is resolved with @YES if there are events for the specified target\n * and @NO otherwise.\n */\n- (FBLPromise<NSNumber *> *)hasEventsForTarget:(GDTCORTarget)target;\n\n/** See `batchWithEventSelector:batchExpiration:onComplete:`\n *  The promise is rejected when there are no events for the specified selector.\n */\n- (FBLPromise<GDTCORUploadBatch *> *)batchWithEventSelector:\n                                         (GDTCORStorageEventSelector *)eventSelector\n                                            batchExpiration:(NSDate *)expiration;\n\n@end\n\n/** Retrieves the storage instance for the given target.\n *\n * @param target The target.\n * * @return The storage instance registered for the target, or nil if there is none.\n */\nFOUNDATION_EXPORT\nid<GDTCORStorageProtocol> _Nullable GDTCORStorageInstanceForTarget(GDTCORTarget target);\n\n// TODO: Ideally we should remove completion-based API and use promise-based one. Need to double\n// check if it's ok.\nFOUNDATION_EXPORT\nid<GDTCORStoragePromiseProtocol> _Nullable GDTCORStoragePromiseInstanceForTarget(\n    GDTCORTarget target);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Internal/GDTCORUploader.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Options that define a set of upload conditions. This is used to help minimize end user data\n * consumption impact.\n */\ntypedef NS_OPTIONS(NSInteger, GDTCORUploadConditions) {\n\n  /** An upload shouldn't be attempted, because there's no network. */\n  GDTCORUploadConditionNoNetwork = 1 << 0,\n\n  /** An upload would likely use mobile data. */\n  GDTCORUploadConditionMobileData = 1 << 1,\n\n  /** An upload would likely use wifi data. */\n  GDTCORUploadConditionWifiData = 1 << 2,\n\n  /** An upload uses some sort of network connection, but it's unclear which. */\n  GDTCORUploadConditionUnclearConnection = 1 << 3,\n\n  /** A high priority event has occurred. */\n  GDTCORUploadConditionHighPriority = 1 << 4,\n};\n\n/** This protocol defines the common interface for uploader implementations. */\n@protocol GDTCORUploader <NSObject, GDTCORLifecycleProtocol>\n\n@required\n\n/** Uploads events to the backend using this specific backend's chosen format.\n *\n * @param conditions The conditions that the upload attempt is likely to occur under.\n */\n- (void)uploadTarget:(GDTCORTarget)target withConditions:(GDTCORUploadConditions)conditions;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCOREndpoints_Private.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREndpoints.h\"\n\n@interface GDTCOREndpoints ()\n\n/** Returns the list of all the upload URLs used by the transport library.\n *\n *  @return Map of the transport target and the URL used for uploading the events for that target.\n */\n+ (NSDictionary<NSNumber *, NSURL *> *)uploadURLs;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h\"\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GDTCOREvent ()\n\n/** The unique ID of the event. This property is for testing only. */\n@property(nonatomic, readwrite) NSString *eventID;\n\n/** Generates a unique event ID. */\n+ (NSString *)nextEventID;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage+Promises.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage.h\"\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The category extends `GDTCORFlatFileStorage` API with `GDTCORStoragePromiseProtocol` methods.\n@interface GDTCORFlatFileStorage (Promises) <GDTCORStoragePromiseProtocol>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h\"\n\n@class GDTCOREvent;\n@class GDTCORUploadCoordinator;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The event components eventID dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCOREventComponentsEventIDKey;\n\n/** The event components qosTier dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCOREventComponentsQoSTierKey;\n\n/** The event components mappingID dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCOREventComponentsMappingIDKey;\n\n/** The event components expirationDate dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCOREventComponentsExpirationKey;\n\n/** The batch components target dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCORBatchComponentsTargetKey;\n\n/** The batch components batchID dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCORBatchComponentsBatchIDKey;\n\n/** The batch components expiration dictionary key. */\nFOUNDATION_EXPORT NSString *const kGDTCORBatchComponentsExpirationKey;\n\n/** The maximum allowed disk space taken by the stored data. */\nFOUNDATION_EXPORT const uint64_t kGDTCORFlatFileStorageSizeLimit;\n\nFOUNDATION_EXPORT NSString *const GDTCORFlatFileStorageErrorDomain;\n\ntypedef NS_ENUM(NSInteger, GDTCORFlatFileStorageError) {\n  GDTCORFlatFileStorageErrorSizeLimitReached = 0\n};\n\n/** Manages the storage of events. This class is thread-safe.\n *\n * Event files will be stored as follows:\n * <app cache>/google-sdk-events/<classname>/gdt_event_data/<target>/<eventID>.<qosTier>.<mappingID>\n *\n * Library data will be stored as follows:\n * <app cache>/google-sdk-events/<classname>/gdt_library_data/<libraryDataKey>\n *\n * Batch data will be stored as follows:\n * <app\n * cache>/google-sdk-events/<classname>/gdt_batch_data/<target>.<batchID>/<eventID>.<qosTier>.<mappingID>\n */\n@interface GDTCORFlatFileStorage : NSObject <GDTCORStorageProtocol, GDTCORLifecycleProtocol>\n\n/** The queue on which all storage work will occur. */\n@property(nonatomic) dispatch_queue_t storageQueue;\n\n/** The upload coordinator instance used by this storage instance. */\n@property(nonatomic) GDTCORUploadCoordinator *uploadCoordinator;\n\n/** Creates and/or returns the storage singleton.\n *\n * @return The storage singleton.\n */\n+ (instancetype)sharedInstance;\n\n/** Returns the base directory under which all events will be stored.\n *\n * @return The base directory under which all events will be stored.\n */\n+ (NSString *)eventDataStoragePath;\n\n/** Returns the base directory under which all library data will be stored.\n *\n * @return The base directory under which all library data will be stored.\n */\n+ (NSString *)libraryDataStoragePath;\n\n/** Returns the base directory under which all batch data will be stored.\n *\n * @return The base directory under which all batch data will be stored.\n */\n+ (NSString *)batchDataStoragePath;\n\n/** */\n+ (NSString *)batchPathForTarget:(GDTCORTarget)target\n                         batchID:(NSNumber *)batchID\n                  expirationDate:(NSDate *)expirationDate;\n\n/** Returns a constructed storage path based on the given values. This path may not exist.\n *\n * @param target The target, which is necessary to be given a path.\n * @param eventID The eventID.\n * @param qosTier The qosTier.\n * @param expirationDate The expirationDate as a 1970-relative time interval.\n * @param mappingID The mappingID.\n * @return The path representing the combination of the given parameters.\n */\n+ (NSString *)pathForTarget:(GDTCORTarget)target\n                    eventID:(NSString *)eventID\n                    qosTier:(NSNumber *)qosTier\n             expirationDate:(NSDate *)expirationDate\n                  mappingID:(NSString *)mappingID;\n\n/** Returns extant paths that match all of the given parameters.\n *\n * @param eventIDs The list of eventIDs to look for, or nil for any.\n * @param qosTiers The list of qosTiers to look for, or nil for any.\n * @param mappingIDs The list of mappingIDs to look for, or nil for any.\n * @param onComplete The completion to call once the paths have been discovered.\n */\n- (void)pathsForTarget:(GDTCORTarget)target\n              eventIDs:(nullable NSSet<NSString *> *)eventIDs\n              qosTiers:(nullable NSSet<NSNumber *> *)qosTiers\n            mappingIDs:(nullable NSSet<NSString *> *)mappingIDs\n            onComplete:(void (^)(NSSet<NSString *> *paths))onComplete;\n\n/** Fetches the current batchID counter value from library storage, increments it, and sets the new\n * value. Returns nil if a batchID was not able to be created for some reason.\n *\n * @param onComplete A block to execute when creating the next batchID is complete.\n */\n- (void)nextBatchID:(void (^)(NSNumber *_Nullable batchID))onComplete;\n\n/** Constructs a dictionary of event filename components.\n *\n * @param fileName The event filename to split.\n * @return The dictionary of event component keys to their values.\n */\n- (nullable NSDictionary<NSString *, id> *)eventComponentsFromFilename:(NSString *)fileName;\n\n/** Constructs a dictionary of batch filename components.\n *\n * @param fileName The batch folder name to split.\n * @return The dictionary of batch component keys to their values.\n */\n- (nullable NSDictionary<NSString *, id> *)batchComponentsFromFilename:(NSString *)fileName;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORReachability_Private.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h\"\n\n@interface GDTCORReachability ()\n\n/** Allows manually setting the flags for testing purposes. */\n@property(nonatomic, readwrite) GDTCORNetworkReachabilityFlags flags;\n\n/** Creates/returns the singleton instance of this class.\n *\n * @return The singleton instance of this class.\n */\n+ (instancetype)sharedInstance;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h\"\n\n@interface GDTCORRegistrar ()\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The concurrent queue on which all registration occurs. */\n@property(nonatomic, readonly) dispatch_queue_t registrarQueue;\n\n/** A map of targets to backend implementations. */\n@property(atomic, readonly) NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *targetToUploader;\n\n/** A map of targets to storage instances. */\n@property(atomic, readonly)\n    NSMutableDictionary<NSNumber *, id<GDTCORStorageProtocol>> *targetToStorage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n\n@class GDTCOREvent;\n\n@protocol GDTCOREventTransformer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Manages the transforming of events. It's desirable for this to be its own class\n * because running all events through a single instance ensures that transformers are thread-safe.\n * Having a per-transport queue to run on isn't sufficient because transformer objects could\n * maintain state (or at least, there's nothing to stop them from doing that) and the same instances\n * may be used across multiple instances.\n */\n@interface GDTCORTransformer : NSObject <GDTCORLifecycleProtocol>\n\n/** Instantiates or returns the event transformer singleton.\n *\n * @return The singleton instance of the event transformer.\n */\n+ (instancetype)sharedInstance;\n\n/** Writes the result of applying the given transformers' `transformGDTEvent:` method on the given\n * event.\n *\n * @note If the app is suspended, a background task will be created to complete work in-progress,\n * but this method will not send any further events until the app is resumed.\n *\n * @param event The event to apply transformers on.\n * @param transformers The list of transformers to apply.\n * @param completion A block to run when an event was written to disk or dropped.\n */\n- (void)transformEvent:(GDTCOREvent *)event\n      withTransformers:(nullable NSArray<id<GDTCOREventTransformer>> *)transformers\n            onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer_Private.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h\"\n\n@protocol GDTCORApplicationProtocol;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GDTCORTransformer ()\n\n/** The queue on which all work will occur. */\n@property(nonatomic) dispatch_queue_t eventWritingQueue;\n\n/** The application instance that is used to begin/end background tasks.  */\n@property(nonatomic, readonly) id<GDTCORApplicationProtocol> application;\n\n/** The internal initializer. Should be used in tests only to create an instance with a\n * particular(fake) application instance. */\n- (instancetype)initWithApplication:(id<GDTCORApplicationProtocol>)application;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTransport.h\"\n\n@class GDTCORTransformer;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GDTCORTransport ()\n\n/** The mapping identifier that the target backend will use to map the transport bytes to proto. */\n@property(nonatomic) NSString *mappingID;\n\n/** The transformers that will operate on events sent by this transport. */\n@property(nonatomic) NSArray<id<GDTCOREventTransformer>> *transformers;\n\n/** The target backend of this transport. */\n@property(nonatomic) NSInteger target;\n\n/** The transformer instance to used to transform events. Allows injecting a fake during testing. */\n@property(nonatomic) GDTCORTransformer *transformerInstance;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadBatch.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class GDTCOREvent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A data object representing a batch of events scheduled for upload.\n@interface GDTCORUploadBatch : NSObject\n\n/// An ID used to identify the batch in the storage.\n@property(nonatomic, readonly) NSNumber *batchID;\n\n/// The collection of the events in the batch.\n@property(nonatomic, readonly) NSSet<GDTCOREvent *> *events;\n\n/// The default initializer. See also docs for the corresponding properties.\n- (instancetype)initWithBatchID:(NSNumber *)batchID events:(NSSet<GDTCOREvent *> *)events;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadCoordinator.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h\"\n#import \"GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h\"\n\n@class GDTCORClock;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class connects storage and uploader implementations, providing events to an uploader\n * and informing the storage what events were successfully uploaded or not.\n */\n@interface GDTCORUploadCoordinator : NSObject <GDTCORLifecycleProtocol>\n\n/** The queue on which all upload coordination will occur. Also used by a dispatch timer. */\n/** Creates and/or returrns the singleton.\n *\n * @return The singleton instance of this class.\n */\n+ (instancetype)sharedInstance;\n\n/** The queue on which all upload coordination will occur. */\n@property(nonatomic, readonly) dispatch_queue_t coordinationQueue;\n\n/** A timer that will causes regular checks for events to upload. */\n@property(nonatomic, readonly, nullable) dispatch_source_t timer;\n\n/** The interval the timer will fire. */\n@property(nonatomic, readonly) uint64_t timerInterval;\n\n/** Some leeway given to libdispatch for the timer interval event. */\n@property(nonatomic, readonly) uint64_t timerLeeway;\n\n/** The registrar object the coordinator will use. Generally used for testing. */\n@property(nonatomic) GDTCORRegistrar *registrar;\n\n/** Forces the backend specified by the target to upload the provided set of events. This should\n * only ever happen when the QoS tier of an event requires it.\n *\n * @param target The target that should force an upload.\n */\n- (void)forceUploadForTarget:(GDTCORTarget)target;\n\n/** Starts the upload timer. */\n- (void)startTimer;\n\n/** Stops the upload timer from running. */\n- (void)stopTimer;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class manages the device clock and produces snapshots of the current time. */\n@interface GDTCORClock : NSObject <NSSecureCoding>\n\n/** The wallclock time, UTC, in milliseconds. */\n@property(nonatomic, readonly) int64_t timeMillis;\n\n/** The offset from UTC in seconds. */\n@property(nonatomic, readonly) int64_t timezoneOffsetSeconds;\n\n/** The kernel boot time when this clock was created in nanoseconds. */\n@property(nonatomic, readonly) int64_t kernelBootTimeNanoseconds;\n\n/** The device uptime when this clock was created in nanoseconds. */\n@property(nonatomic, readonly) int64_t uptimeNanoseconds;\n\n@property(nonatomic, readonly) int64_t kernelBootTime DEPRECATED_MSG_ATTRIBUTE(\n    \"Please use `kernelBootTimeNanoseconds` instead\");\n\n@property(nonatomic, readonly)\n    int64_t uptime DEPRECATED_MSG_ATTRIBUTE(\"Please use `uptimeNanoseconds` instead\");\n\n/** Creates a GDTCORClock object using the current time and offsets.\n *\n * @return A new GDTCORClock object representing the current time state.\n */\n+ (instancetype)snapshot;\n\n/** Creates a GDTCORClock object representing a time in the future, relative to now.\n *\n * @param millisInTheFuture The millis in the future from now this clock should represent.\n * @return An instance representing a future time.\n */\n+ (instancetype)clockSnapshotInTheFuture:(uint64_t)millisInTheFuture;\n\n/** Compares one clock with another, returns YES if the caller is after the parameter.\n *\n * @return YES if the calling clock's time is after the given clock's time.\n */\n- (BOOL)isAfter:(GDTCORClock *)otherClock;\n\n/** Returns value of `uptime` property in milliseconds. */\n- (int64_t)uptimeMilliseconds;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/** The current logging level. This value and higher will be printed. Declared as volatile to make\n * getting and setting atomic.\n */\nFOUNDATION_EXPORT volatile NSInteger GDTCORConsoleLoggerLoggingLevel;\n\n/** A  list of logging levels that GDT supports. */\ntypedef NS_ENUM(NSInteger, GDTCORLoggingLevel) {\n\n  /** Causes all logs to be printed. */\n  GDTCORLoggingLevelDebug = 1,\n\n  /** Causes all non-debug logs to be printed. */\n  GDTCORLoggingLevelVerbose = 2,\n\n  /** Causes warnings and errors to be printed. */\n  GDTCORLoggingLevelWarnings = 3,\n\n  /** Causes errors to be printed. This is the default value. */\n  GDTCORLoggingLevelErrors = 4\n};\n\n/** A list of message codes to print in the logger that help to correspond printed messages with\n * code locations.\n *\n * Prefixes:\n * - MCD => MessageCodeDebug\n * - MCW => MessageCodeWarning\n * - MCE => MessageCodeError\n */\ntypedef NS_ENUM(NSInteger, GDTCORMessageCode) {\n\n  /** For debug logs. */\n  GDTCORMCDDebugLog = 0,\n\n  /** For warning messages concerning transportBytes: not being implemented by a data object. */\n  GDTCORMCWDataObjectMissingBytesImpl = 1,\n\n  /** For warning messages concerning a failed event upload. */\n  GDTCORMCWUploadFailed = 2,\n\n  /** For warning messages concerning a forced event upload. */\n  GDTCORMCWForcedUpload = 3,\n\n  /** For warning messages concerning a failed reachability call. */\n  GDTCORMCWReachabilityFailed = 4,\n\n  /** For warning messages concerning a database warning. */\n  GDTCORMCWDatabaseWarning = 5,\n\n  /** For warning messages concerning the reading of a event file. */\n  GDTCORMCWFileReadError = 6,\n\n  /** For error messages concerning transformGDTEvent: not being implemented by an event\n     transformer. */\n  GDTCORMCETransformerDoesntImplementTransform = 1000,\n\n  /** For error messages concerning the creation of a directory failing. */\n  GDTCORMCEDirectoryCreationError = 1001,\n\n  /** For error messages concerning the writing of a event file. */\n  GDTCORMCEFileWriteError = 1002,\n\n  /** For error messages concerning the lack of a prioritizer for a given backend. */\n  GDTCORMCEPrioritizerError = 1003,\n\n  /** For error messages concerning a package delivery API violation. */\n  GDTCORMCEDeliverTwice = 1004,\n\n  /** For error messages concerning an error in an implementation of -transportBytes. */\n  GDTCORMCETransportBytesError = 1005,\n\n  /** For general purpose error messages in a dependency. */\n  GDTCORMCEGeneralError = 1006,\n\n  /** For fatal errors. Please go to https://github.com/firebase/firebase-ios-sdk/issues and open\n   * an issue if you encounter an error with this code.\n   */\n  GDTCORMCEFatalAssertion = 1007,\n\n  /** For error messages concerning the reading of a event file. */\n  GDTCORMCEFileReadError = 1008,\n\n  /** For errors related to running sqlite. */\n  GDTCORMCEDatabaseError = 1009,\n};\n\n/** Prints the given code and format string to the console.\n *\n * @param code The message code describing the nature of the log.\n * @param logLevel The log level of this log.\n * @param format The format string.\n */\nFOUNDATION_EXPORT\nvoid GDTCORLog(GDTCORMessageCode code, GDTCORLoggingLevel logLevel, NSString *_Nonnull format, ...)\n    NS_FORMAT_FUNCTION(3, 4);\n\n/** Prints an assert log to the console.\n *\n * @param wasFatal Send YES if the assertion should be fatal, NO otherwise.\n * @param file The file in which the failure occurred.\n * @param line The line number of the failure.\n * @param format The format string.\n */\nFOUNDATION_EXPORT void GDTCORLogAssert(BOOL wasFatal,\n                                       NSString *_Nonnull file,\n                                       NSInteger line,\n                                       NSString *_Nullable format,\n                                       ...) NS_FORMAT_FUNCTION(4, 5);\n\n/** Returns the string that represents some message code.\n *\n * @param code The code to convert to a string.\n * @return The string representing the message code.\n */\nFOUNDATION_EXPORT NSString *_Nonnull GDTCORMessageCodeEnumToString(GDTCORMessageCode code);\n\n#define GDTCORLogDebug(MESSAGE_FORMAT, ...) \\\n  GDTCORLog(GDTCORMCDDebugLog, GDTCORLoggingLevelDebug, MESSAGE_FORMAT, __VA_ARGS__);\n\n// A define to wrap GULLogWarning with slightly more convenient usage.\n#define GDTCORLogWarning(MESSAGE_CODE, MESSAGE_FORMAT, ...) \\\n  GDTCORLog(MESSAGE_CODE, GDTCORLoggingLevelWarnings, MESSAGE_FORMAT, __VA_ARGS__);\n\n// A define to wrap GULLogError with slightly more convenient usage and a failing assert.\n#define GDTCORLogError(MESSAGE_CODE, MESSAGE_FORMAT, ...) \\\n  GDTCORLog(MESSAGE_CODE, GDTCORLoggingLevelErrors, MESSAGE_FORMAT, __VA_ARGS__);\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREndpoints.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import \"GDTCORTargets.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/* Class that manages the endpoints used by Google data transport library. */\n@interface GDTCOREndpoints : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** Returns the upload URL for a target specified. If the target is not available, returns nil.\n *\n *  @param target GoogleDataTransport target for which the upload URL is being looked up for.\n *  @return URL that will be used for uploading the events for the provided target.\n */\n+ (nullable NSURL *)uploadURLForTarget:(GDTCORTarget)target;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GDTCOREventDataObject.h\"\n#import \"GDTCORTargets.h\"\n\n@class GDTCORClock;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The different possible quality of service specifiers. High values indicate high priority. */\ntypedef NS_ENUM(NSInteger, GDTCOREventQoS) {\n  /** The QoS tier wasn't set, and won't ever be sent. */\n  GDTCOREventQoSUnknown = 0,\n\n  /** This event is internal telemetry data that should not be sent on its own if possible. */\n  GDTCOREventQoSTelemetry = 1,\n\n  /** This event should be sent, but in a batch only roughly once per day. */\n  GDTCOREventQoSDaily = 2,\n\n  /** This event should be sent when requested by the uploader. */\n  GDTCOREventQosDefault = 3,\n\n  /** This event should be sent immediately along with any other data that can be batched. */\n  GDTCOREventQoSFast = 4,\n\n  /** This event should only be uploaded on wifi. */\n  GDTCOREventQoSWifiOnly = 5,\n};\n\n@interface GDTCOREvent : NSObject <NSSecureCoding>\n\n/** The unique ID of the event. */\n@property(readonly, nonatomic) NSString *eventID;\n\n/** The mapping identifier, to allow backends to map the transport bytes to a proto. */\n@property(nullable, readonly, nonatomic) NSString *mappingID;\n\n/** The identifier for the backend this event will eventually be sent to. */\n@property(readonly, nonatomic) GDTCORTarget target;\n\n/** The data object encapsulated in the transport of your choice, as long as it implements\n * the GDTCOREventDataObject protocol. */\n@property(nullable, nonatomic) id<GDTCOREventDataObject> dataObject;\n\n/** The serialized bytes from calling [dataObject transportBytes]. */\n@property(nullable, readonly, nonatomic) NSData *serializedDataObjectBytes;\n\n/** The quality of service tier this event belongs to. */\n@property(nonatomic) GDTCOREventQoS qosTier;\n\n/** The clock snapshot at the time of the event. */\n@property(nonatomic) GDTCORClock *clockSnapshot;\n\n/** The expiration date of the event. Default is 604800 seconds (7 days) from creation. */\n@property(nonatomic) NSDate *expirationDate;\n\n/** Bytes that can be used by an uploader later on. */\n@property(nullable, nonatomic) NSData *customBytes;\n\n/** Initializes an instance using the given mappingID.\n *\n * @param mappingID The mapping identifier.\n * @param target The event's target identifier.\n * @return An instance of this class.\n */\n- (nullable instancetype)initWithMappingID:(NSString *)mappingID target:(GDTCORTarget)target;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventDataObject.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This protocol defines the common interface that event protos should implement regardless of the\n * underlying transport technology (protobuf, nanopb, etc).\n */\n@protocol GDTCOREventDataObject <NSObject>\n\n@required\n\n/** Returns the serialized proto bytes of the implementing event proto.\n *\n * @return the serialized proto bytes of the implementing event proto.\n */\n- (NSData *)transportBytes;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventTransformer.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class GDTCOREvent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Defines the API that event transformers must adopt. */\n@protocol GDTCOREventTransformer <NSObject>\n\n@required\n\n/** Transforms an event by applying some logic to it. Events returned can be nil, for example, in\n *  instances where the event should be sampled.\n *\n * @param event The event to transform.\n * @return A transformed event, or nil if the transformation dropped the event.\n */\n- (nullable GDTCOREvent *)transformGDTEvent:(GDTCOREvent *)event;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/** The list of targets supported by the shared transport infrastructure. If adding a new target,\n * please use the previous value +1.\n */\ntypedef NS_ENUM(NSInteger, GDTCORTarget) {\n\n  /** A target only used in testing. */\n  kGDTCORTargetTest = 999,\n\n  /** The CCT target. */\n  kGDTCORTargetCCT = 1000,\n\n  /** The FLL target. */\n  kGDTCORTargetFLL = 1001,\n\n  /** The CSH target. The CSH target is a special-purpose backend. Please do not use it without\n   * permission.\n   */\n  kGDTCORTargetCSH = 1002,\n\n  /** The INT target. */\n  kGDTCORTargetINT = 1003,\n};\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTransport.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GDTCOREventTransformer.h\"\n#import \"GDTCORTargets.h\"\n\n@class GDTCOREvent;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GDTCORTransport : NSObject\n\n// Please use the designated initializer.\n- (instancetype)init NS_UNAVAILABLE;\n\n/** Initializes a new transport that will send events to the given target backend.\n *\n * @param mappingID The mapping identifier used by the backend to map the data object transport\n * bytes to a proto.\n * @param transformers A list of transformers to be applied to events that are sent.\n * @param target The target backend of this transport.\n * @return A transport that will send events.\n */\n- (nullable instancetype)initWithMappingID:(NSString *)mappingID\n                              transformers:\n                                  (nullable NSArray<id<GDTCOREventTransformer>> *)transformers\n                                    target:(GDTCORTarget)target NS_DESIGNATED_INITIALIZER;\n\n/** Copies and sends an internal telemetry event. Events sent using this API are lower in priority,\n * and sometimes won't be sent on their own.\n *\n * @note This will convert the event's data object to data and release the original event.\n *\n * @param event The event to send.\n * @param completion A block that will be called when the event has been written or dropped.\n */\n- (void)sendTelemetryEvent:(GDTCOREvent *)event\n                onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion;\n\n/** Copies and sends an internal telemetry event. Events sent using this API are lower in priority,\n * and sometimes won't be sent on their own.\n *\n * @note This will convert the event's data object to data and release the original event.\n *\n * @param event The event to send.\n */\n- (void)sendTelemetryEvent:(GDTCOREvent *)event;\n\n/** Copies and sends an SDK service data event. Events send using this API are higher in priority,\n * and will cause a network request at some point in the relative near future.\n *\n * @note This will convert the event's data object to data and release the original event.\n *\n * @param event The event to send.\n * @param completion A block that will be called when the event has been written or dropped.\n */\n- (void)sendDataEvent:(GDTCOREvent *)event\n           onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion;\n\n/** Copies and sends an SDK service data event. Events send using this API are higher in priority,\n * and will cause a network request at some point in the relative near future.\n *\n * @note This will convert the event's data object to data and release the original event.\n *\n * @param event The event to send.\n */\n- (void)sendDataEvent:(GDTCOREvent *)event;\n\n/** Creates an event for use by this transport.\n *\n * @return An event that is suited for use by this transport.\n */\n- (GDTCOREvent *)eventForTransport;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleDataTransport/GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GoogleDataTransport.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GDTCORClock.h\"\n#import \"GDTCORConsoleLogger.h\"\n#import \"GDTCOREndpoints.h\"\n#import \"GDTCOREvent.h\"\n#import \"GDTCOREventDataObject.h\"\n#import \"GDTCOREventTransformer.h\"\n#import \"GDTCORTargets.h\"\n#import \"GDTCORTransport.h\"\n"
  },
  {
    "path": "Pods/GoogleDataTransport/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/GoogleDataTransport/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/GoogleDataTransport.svg?style=flat)](https://cocoapods.org/pods/GoogleDataTransport)\n[![License](https://img.shields.io/cocoapods/l/GoogleDataTransport.svg?style=flat)](https://cocoapods.org/pods/GoogleDataTransport)\n[![Platform](https://img.shields.io/cocoapods/p/GoogleDataTransport.svg?style=flat)](https://cocoapods.org/pods/GoogleDataTransport)\n\n[![Actions Status][gh-datatransport-badge]][gh-actions]\n\n# GoogleDataTransport\n\nThis library is for internal Google use only. It allows the logging of data and\ntelemetry from Google SDKs.\n\n## Integration Testing\nThese instructions apply to minor and patch version updates. Major versions need\na customized adaptation.\n\nAfter the CI is green:\n* Determine the next version for release by checking the\n  [tagged releases](https://github.com/google/GoogleDataTransport/tags).\n  Ensure that the next release version keeps the Swift PM and CocoaPods versions in sync.\n* Verify that the releasing version is the latest entry in the [CHANGELOG.md](CHANGELOG.md),\n  updating it if necessary.\n* Update the version in the podspec to match the latest entry in the [CHANGELOG.md](CHANGELOG.md)\n* Checkout the `main` branch and ensure it is up to date.\n  ```console\n  git checkout main\n  git pull\n  ```\n* Add the CocoaPods tag (`{version}` will be the latest version in the [podspec](GoogleDataTransport.podspec#L3))\n  ```console\n  git tag CocoaPods-{version}\n  git push origin CocoaPods-{version}\n  ```\n* Push the podspec to the designated repo\n  * If this version of GDT is intended to launch **before or with** the next Firebase release:\n    <details>\n    <summary>Push to <b>SpecsStaging</b></summary>\n\n    ```console\n    pod repo push --skip-tests staging GoogleDataTransport.podspec\n    ```\n\n    If the command fails with `Unable to find the 'staging' repo.`, add the staging repo with:\n    ```console\n    pod repo add staging git@github.com:firebase/SpecsStaging.git\n    ```\n    </details>\n  * Otherwise:\n    <details>\n    <summary>Push to <b>SpecsDev</b></summary>\n\n    ```console\n    pod repo push --skip-tests dev GoogleDataTransport.podspec\n    ```\n\n    If the command fails with `Unable to find the 'dev' repo.`, add the dev repo with:\n    ```console\n    pod repo add dev git@github.com:firebase/SpecsDev.git\n    ```\n    </details>\n* Run Firebase CI by waiting until next nightly or adding a PR that touches `Gemfile`.\n* On google3, create a workspace and new CL. Then copybara and run a global TAP.\n  <pre>\n  /google/data/ro/teams/copybara/copybara third_party/firebase/ios/Releases/GoogleDataTransport/copy.bara.sky \\\n  --piper-description-behavior=OVERWRITE \\\n  --destination-cl=<b>YOUR_CL</b> gdt\n  </pre>\n\n## Publishing\nThe release process is as follows:\n1. [Tag and release for Swift PM](#swift-package-manager)\n2. [Publish to CocoaPods](#cocoapods)\n3. [Create GitHub Release](#create-github-release)\n4. [Perform post release cleanup](#post-release-cleanup)\n\n### Swift Package Manager\n  By creating and [pushing a tag](https://github.com/google/GoogleDataTransport/tags)\n  for Swift PM, the newly tagged version will be immediately released for public use.\n  Given this, please verify the intended time of release for Swift PM.\n  * Add a version tag for Swift PM\n  ```console\n  git tag {version}\n  git push origin {version}\n  ```\n  *Note: Ensure that any inflight PRs that depend on the new `GoogleDataTransport` version are updated to point to the\n  newly tagged version rather than a checksum.*\n\n### CocoaPods\n* Publish the newly versioned pod to CocoaPods\n\n  It's recommended to point to the `GoogleDataTransport.podspec` in `staging` to make sure the correct spec is being published.\n  ```console\n  pod trunk push ~/.cocoapods/repos/staging/GoogleDataTransport.podspec --skip-tests\n  ```\n\n  The pod push was successful if the above command logs: `🚀  GoogleDataTransport ({version}) successfully published`.\n  In addition, a new commit that publishes the new version (co-authored by [CocoaPodsAtGoogle](https://github.com/CocoaPodsAtGoogle))\n  should appear in the [CocoaPods specs repo](https://github.com/CocoaPods/Specs). Last, the latest version should be displayed\n  on [GoogleDataTransport's CocoaPods page](https://cocoapods.org/pods/GoogleDataTransport).\n\n### [Create GitHub Release](https://github.com/google/GoogleDataTransport/releases/new/)\n  Update the [release template](https://github.com/google/GoogleDataTransport/releases/new/)'s **Tag version** and **Release title**\n  fields with the latest version. In addition, reference the [Release Notes](./CHANGELOG.md) in the release's description.\n\n  See [this release](https://github.com/google/GoogleDataTransport/releases/edit/9.0.1) for an example.\n\n  *Don't forget to perform the [post release cleanup](#post-release-cleanup)!*\n\n### Post Release Cleanup\n  <details>\n  <summary>Clean up <b>SpecsStaging</b></summary>\n\n  ```console\n  pwd=$(pwd)\n  mkdir -p /tmp/release-cleanup && cd $_\n  git clone git@github.com:firebase/SpecsStaging.git\n  cd SpecsStaging/\n  git rm -rf GoogleDataTransport/\n  git commit -m \"Post publish cleanup\"\n  git push origin master\n  rm -rf /tmp/release-cleanup\n  cd $pwd\n  ```\n  </details>\n\n## Set logging level\n\n### Swift\n\n- Import `GoogleDataTransport` module:\n    ```swift\n    import GoogleDataTransport\n    ```\n- Set logging level global variable to the desired value before calling `FirebaseApp.configure()`:\n    ```swift\n    GDTCORConsoleLoggerLoggingLevel = GDTCORLoggingLevel.debug.rawValue\n    ```\n### Objective-C\n\n- Import `GoogleDataTransport`:\n    ```objective-c\n    #import <GoogleDataTransport/GoogleDataTransport.h>\n    ```\n- Set logging level global variable to the desired value before calling `-[FIRApp configure]`:\n    ```objective-c\n    GDTCORConsoleLoggerLoggingLevel = GDTCORLoggingLevelDebug;\n    ```\n\n## Prereqs\n\n- `gem install --user cocoapods cocoapods-generate`\n- `brew install protobuf nanopb-generator`\n- `easy_install --user protobuf`\n\n## To develop\n\n- Run `./GoogleDataTransport/generate_project.sh` after installing the prereqs\n\n## When adding new logging endpoint\n\n- Use commands similar to:\n    - `python -c \"line='https://www.firebase.com'; print line[0::2]\" `\n    - `python -c \"line='https://www.firebase.com'; print line[1::2]\" `\n\n## When adding internal code that shouldn't be easily usable on github\n\n- Consider using go/copybara-library/scrubbing#cc_scrub\n\n## Development\n\nEnsure that you have at least the following software:\n\n  * Xcode 12.0 (or later)\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n`pod gen GoogleDataTransport.podspec --local-sources=./ --auto-open --platforms=ios`\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\n### Development for Catalyst\n* `pod gen GoogleDataTransport.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase\niOS SDK.\n\n## License\n\nThe contents of this repository is licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <TargetConditionals.h>\n\n#import \"GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h\"\n#import \"GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h\"\n#import \"GoogleUtilities/Common/GULLoggerCodes.h\"\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h\"\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n\n#import <dispatch/group.h>\n#import <objc/runtime.h>\n\n// Implementations need to be typed before calling the implementation directly to cast the\n// arguments and the return types correctly. Otherwise, it will crash the app.\ntypedef BOOL (*GULRealOpenURLSourceApplicationAnnotationIMP)(\n    id, SEL, GULApplication *, NSURL *, NSString *, id);\n\ntypedef BOOL (*GULRealOpenURLOptionsIMP)(\n    id, SEL, GULApplication *, NSURL *, NSDictionary<NSString *, id> *);\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wstrict-prototypes\"\ntypedef void (*GULRealHandleEventsForBackgroundURLSessionIMP)(\n    id, SEL, GULApplication *, NSString *, void (^)());\n#pragma clang diagnostic pop\n\ntypedef BOOL (*GULRealContinueUserActivityIMP)(\n    id, SEL, GULApplication *, NSUserActivity *, void (^)(NSArray *restorableObjects));\n\ntypedef void (*GULRealDidRegisterForRemoteNotificationsIMP)(id, SEL, GULApplication *, NSData *);\n\ntypedef void (*GULRealDidFailToRegisterForRemoteNotificationsIMP)(id,\n                                                                  SEL,\n                                                                  GULApplication *,\n                                                                  NSError *);\n\ntypedef void (*GULRealDidReceiveRemoteNotificationIMP)(id, SEL, GULApplication *, NSDictionary *);\n\n#if !TARGET_OS_WATCH && !TARGET_OS_OSX\ntypedef void (*GULRealDidReceiveRemoteNotificationWithCompletionIMP)(\n    id, SEL, GULApplication *, NSDictionary *, void (^)(UIBackgroundFetchResult));\n#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX\n\ntypedef void (^GULAppDelegateInterceptorCallback)(id<GULApplicationDelegate>);\n\n// The strings below are the keys for associated objects.\nstatic char const *const kGULRealIMPBySelectorKey = \"GUL_realIMPBySelector\";\nstatic char const *const kGULRealClassKey = \"GUL_realClass\";\n\nstatic NSString *const kGULAppDelegateKeyPath = @\"delegate\";\n\nstatic GULLoggerService kGULLoggerSwizzler = @\"[GoogleUtilities/AppDelegateSwizzler]\";\n\n// Since Firebase SDKs also use this for app delegate proxying, in order to not be a breaking change\n// we disable App Delegate proxying when either of these two flags are set to NO.\n\n/** Plist key that allows Firebase developers to disable App and Scene Delegate Proxying. */\nstatic NSString *const kGULFirebaseAppDelegateProxyEnabledPlistKey =\n    @\"FirebaseAppDelegateProxyEnabled\";\n\n/** Plist key that allows developers not using Firebase to disable App and Scene Delegate Proxying.\n */\nstatic NSString *const kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey =\n    @\"GoogleUtilitiesAppDelegateProxyEnabled\";\n\n/** The prefix of the App Delegate. */\nstatic NSString *const kGULAppDelegatePrefix = @\"GUL_\";\n\n/** The original instance of App Delegate. */\nstatic id<GULApplicationDelegate> gOriginalAppDelegate;\n\n/** The original App Delegate class */\nstatic Class gOriginalAppDelegateClass;\n\n/** The subclass of the original App Delegate. */\nstatic Class gAppDelegateSubclass;\n\n/** Remote notification methods selectors\n *\n *  We have to opt out of referencing APNS related App Delegate methods directly to prevent\n *  an Apple review warning email about missing Push Notification Entitlement\n *  (like here: https://github.com/firebase/firebase-ios-sdk/issues/2807). From our experience, the\n *  warning is triggered when any of the symbols is present in the application sent to review, even\n *  if the code is never executed. Because GULAppDelegateSwizzler may be used by applications that\n *  are not using APNS we have to refer to the methods indirectly using selector constructed from\n *  string.\n *\n *  NOTE: None of the methods is proxied unless it is explicitly requested by calling the method\n *  +[GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods]\n */\nstatic NSString *const kGULDidRegisterForRemoteNotificationsSEL =\n    @\"application:didRegisterForRemoteNotificationsWithDeviceToken:\";\nstatic NSString *const kGULDidFailToRegisterForRemoteNotificationsSEL =\n    @\"application:didFailToRegisterForRemoteNotificationsWithError:\";\nstatic NSString *const kGULDidReceiveRemoteNotificationSEL =\n    @\"application:didReceiveRemoteNotification:\";\nstatic NSString *const kGULDidReceiveRemoteNotificationWithCompletionSEL =\n    @\"application:didReceiveRemoteNotification:fetchCompletionHandler:\";\n\n/**\n * This class is necessary to store the delegates in an NSArray without retaining them.\n * [NSValue valueWithNonRetainedObject] also provides this functionality, but does not provide a\n * zeroing pointer. This will cause EXC_BAD_ACCESS when trying to access the object after it is\n * dealloced. Instead, this container stores a weak, zeroing reference to the object, which\n * automatically is set to nil by the runtime when the object is dealloced.\n */\n@interface GULZeroingWeakContainer : NSObject\n\n/** Stores a weak object. */\n@property(nonatomic, weak) id object;\n\n@end\n\n@implementation GULZeroingWeakContainer\n@end\n\n@interface GULAppDelegateObserver : NSObject\n@end\n\n@implementation GULAppDelegateObserver {\n  BOOL _isObserving;\n}\n\n+ (GULAppDelegateObserver *)sharedInstance {\n  static GULAppDelegateObserver *instance;\n  static dispatch_once_t once;\n  dispatch_once(&once, ^{\n    instance = [[GULAppDelegateObserver alloc] init];\n  });\n  return instance;\n}\n\n- (void)observeUIApplication {\n  if (_isObserving) {\n    return;\n  }\n  [[GULAppDelegateSwizzler sharedApplication]\n    addObserver:self\n     forKeyPath:kGULAppDelegateKeyPath\n        options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld\n        context:nil];\n  _isObserving = YES;\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath\n                      ofObject:(id)object\n                        change:(NSDictionary *)change\n                       context:(void *)context {\n  if ([keyPath isEqual:kGULAppDelegateKeyPath]) {\n    id newValue = change[NSKeyValueChangeNewKey];\n    id oldValue = change[NSKeyValueChangeOldKey];\n    if ([newValue isEqual:oldValue]) {\n      return;\n    }\n    // Free the stored app delegate instance because it has been changed to a different instance to\n    // avoid keeping it alive forever.\n    if ([oldValue isEqual:gOriginalAppDelegate]) {\n      gOriginalAppDelegate = nil;\n      // Remove the observer. Parse it to NSObject to avoid warning.\n      [[GULAppDelegateSwizzler sharedApplication] removeObserver:self\n                                                      forKeyPath:kGULAppDelegateKeyPath];\n      _isObserving = NO;\n    }\n  }\n}\n\n@end\n\n@implementation GULAppDelegateSwizzler\n\nstatic dispatch_once_t sProxyAppDelegateOnceToken;\nstatic dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken;\n\n#pragma mark - Public methods\n\n+ (BOOL)isAppDelegateProxyEnabled {\n  NSDictionary *infoDictionary = [NSBundle mainBundle].infoDictionary;\n\n  id isFirebaseProxyEnabledPlistValue = infoDictionary[kGULFirebaseAppDelegateProxyEnabledPlistKey];\n  id isGoogleProxyEnabledPlistValue =\n      infoDictionary[kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey];\n\n  // Enabled by default.\n  BOOL isFirebaseAppDelegateProxyEnabled = YES;\n  BOOL isGoogleUtilitiesAppDelegateProxyEnabled = YES;\n\n  if ([isFirebaseProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) {\n    isFirebaseAppDelegateProxyEnabled = [isFirebaseProxyEnabledPlistValue boolValue];\n  }\n\n  if ([isGoogleProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) {\n    isGoogleUtilitiesAppDelegateProxyEnabled = [isGoogleProxyEnabledPlistValue boolValue];\n  }\n\n  // Only deactivate the proxy if it is explicitly disabled by app developers using either one of\n  // the plist flags.\n  return isFirebaseAppDelegateProxyEnabled && isGoogleUtilitiesAppDelegateProxyEnabled;\n}\n\n+ (GULAppDelegateInterceptorID)registerAppDelegateInterceptor:\n    (id<GULApplicationDelegate>)interceptor {\n  NSAssert(interceptor, @\"AppDelegateProxy cannot add nil interceptor\");\n  NSAssert([interceptor conformsToProtocol:@protocol(GULApplicationDelegate)],\n           @\"AppDelegateProxy interceptor does not conform to UIApplicationDelegate\");\n\n  if (!interceptor) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling000],\n                @\"AppDelegateProxy cannot add nil interceptor.\");\n    return nil;\n  }\n  if (![interceptor conformsToProtocol:@protocol(GULApplicationDelegate)]) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling001],\n                @\"AppDelegateProxy interceptor does not conform to UIApplicationDelegate\");\n    return nil;\n  }\n\n  // The ID should be the same given the same interceptor object.\n  NSString *interceptorID = [NSString stringWithFormat:@\"%@%p\", kGULAppDelegatePrefix, interceptor];\n  if (!interceptorID.length) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling002],\n                @\"AppDelegateProxy cannot create Interceptor ID.\");\n    return nil;\n  }\n  GULZeroingWeakContainer *weakObject = [[GULZeroingWeakContainer alloc] init];\n  weakObject.object = interceptor;\n  [GULAppDelegateSwizzler interceptors][interceptorID] = weakObject;\n  return interceptorID;\n}\n\n+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID {\n  NSAssert(interceptorID, @\"AppDelegateProxy cannot unregister nil interceptor ID.\");\n  NSAssert(((NSString *)interceptorID).length != 0,\n           @\"AppDelegateProxy cannot unregister empty interceptor ID.\");\n\n  if (!interceptorID) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling003],\n                @\"AppDelegateProxy cannot unregister empty interceptor ID.\");\n    return;\n  }\n\n  GULZeroingWeakContainer *weakContainer = [GULAppDelegateSwizzler interceptors][interceptorID];\n  if (!weakContainer.object) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling004],\n                @\"AppDelegateProxy cannot unregister interceptor that was not registered. \"\n                 \"Interceptor ID %@\",\n                interceptorID);\n    return;\n  }\n\n  [[GULAppDelegateSwizzler interceptors] removeObjectForKey:interceptorID];\n}\n\n+ (void)proxyOriginalDelegate {\n  if ([GULAppEnvironmentUtil isAppExtension]) {\n    return;\n  }\n\n  dispatch_once(&sProxyAppDelegateOnceToken, ^{\n    id<GULApplicationDelegate> originalDelegate =\n        [GULAppDelegateSwizzler sharedApplication].delegate;\n    [GULAppDelegateSwizzler proxyAppDelegate:originalDelegate];\n  });\n}\n\n+ (void)proxyOriginalDelegateIncludingAPNSMethods {\n  if ([GULAppEnvironmentUtil isAppExtension]) {\n    return;\n  }\n\n  [self proxyOriginalDelegate];\n\n  dispatch_once(&sProxyAppDelegateRemoteNotificationOnceToken, ^{\n    id<GULApplicationDelegate> appDelegate = [GULAppDelegateSwizzler sharedApplication].delegate;\n\n    NSMutableDictionary *realImplementationsBySelector =\n        [objc_getAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey) mutableCopy];\n\n    [self proxyRemoteNotificationsMethodsWithAppDelegateSubClass:gAppDelegateSubclass\n                                                       realClass:gOriginalAppDelegateClass\n                                                     appDelegate:appDelegate\n                                   realImplementationsBySelector:realImplementationsBySelector];\n\n    objc_setAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey,\n                             [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN);\n    [self reassignAppDelegate];\n  });\n}\n\n#pragma mark - Create proxy\n\n+ (GULApplication *)sharedApplication {\n  if ([GULAppEnvironmentUtil isAppExtension]) {\n    return nil;\n  }\n  id sharedApplication = nil;\n  Class uiApplicationClass = NSClassFromString(kGULApplicationClassName);\n  if (uiApplicationClass &&\n      [uiApplicationClass respondsToSelector:(NSSelectorFromString(@\"sharedApplication\"))]) {\n    sharedApplication = [uiApplicationClass sharedApplication];\n  }\n  return sharedApplication;\n}\n\n#pragma mark - Override default methods\n\n/** Creates a new subclass of the class of the given object and sets the isa value of the given\n *  object to the new subclass. Additionally this copies methods to that new subclass that allow us\n *  to intercept UIApplicationDelegate methods. This is better known as isa swizzling.\n *\n *  @param appDelegate The object to which you want to isa swizzle. This has to conform to the\n *      UIApplicationDelegate subclass.\n *  @return Returns the new subclass.\n */\n+ (nullable Class)createSubclassWithObject:(id<GULApplicationDelegate>)appDelegate {\n  Class realClass = [appDelegate class];\n\n  // Create GUL_<RealAppDelegate>_<UUID>\n  NSString *classNameWithPrefix =\n      [kGULAppDelegatePrefix stringByAppendingString:NSStringFromClass(realClass)];\n  NSString *newClassName =\n      [NSString stringWithFormat:@\"%@-%@\", classNameWithPrefix, [NSUUID UUID].UUIDString];\n\n  if (NSClassFromString(newClassName)) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling005],\n                @\"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: \"\n                @\"%@, subclass: %@\",\n                NSStringFromClass(realClass), newClassName);\n    return nil;\n  }\n\n  // Register the new class as subclass of the real one. Do not allocate more than the real class\n  // size.\n  Class appDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0);\n  if (appDelegateSubClass == Nil) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling006],\n                @\"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: \"\n                @\"%@, subclass: Nil\",\n                NSStringFromClass(realClass));\n    return nil;\n  }\n\n  NSMutableDictionary<NSString *, NSValue *> *realImplementationsBySelector =\n      [[NSMutableDictionary alloc] init];\n\n  // For application:continueUserActivity:restorationHandler:\n  SEL continueUserActivitySEL = @selector(application:continueUserActivity:restorationHandler:);\n  [self proxyDestinationSelector:continueUserActivitySEL\n      implementationsFromSourceSelector:continueUserActivitySEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n  // Add the following methods from GULAppDelegate class, and store the real implementation so it\n  // can forward to the real one.\n  // For application:openURL:options:\n  SEL applicationOpenURLOptionsSEL = @selector(application:openURL:options:);\n  if ([appDelegate respondsToSelector:applicationOpenURLOptionsSEL]) {\n    // Only add the application:openURL:options: method if the original AppDelegate implements it.\n    // This fixes a bug if an app only implements application:openURL:sourceApplication:annotation:\n    // (if we add the `options` method, iOS sees that one exists and does not call the\n    // `sourceApplication` method, which in this case is the only one the app implements).\n\n    [self proxyDestinationSelector:applicationOpenURLOptionsSEL\n        implementationsFromSourceSelector:applicationOpenURLOptionsSEL\n                                fromClass:[GULAppDelegateSwizzler class]\n                                  toClass:appDelegateSubClass\n                                realClass:realClass\n         storeDestinationImplementationTo:realImplementationsBySelector];\n  }\n\n  // For application:handleEventsForBackgroundURLSession:completionHandler:\n  SEL handleEventsForBackgroundURLSessionSEL = @selector(application:\n                                 handleEventsForBackgroundURLSession:completionHandler:);\n  [self proxyDestinationSelector:handleEventsForBackgroundURLSessionSEL\n      implementationsFromSourceSelector:handleEventsForBackgroundURLSessionSEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#if TARGET_OS_IOS\n  // For application:openURL:sourceApplication:annotation:\n  SEL openURLSourceApplicationAnnotationSEL = @selector(application:\n                                                            openURL:sourceApplication:annotation:);\n\n  [self proxyDestinationSelector:openURLSourceApplicationAnnotationSEL\n      implementationsFromSourceSelector:openURLSourceApplicationAnnotationSEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n#endif  // TARGET_OS_IOS\n\n  // Override the description too so the custom class name will not show up.\n  [GULAppDelegateSwizzler addInstanceMethodWithDestinationSelector:@selector(description)\n                              withImplementationFromSourceSelector:@selector(fakeDescription)\n                                                         fromClass:[self class]\n                                                           toClass:appDelegateSubClass];\n\n  // Store original implementations to a fake property of the original delegate.\n  objc_setAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey,\n                           [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n  objc_setAssociatedObject(appDelegate, &kGULRealClassKey, realClass,\n                           OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n\n  // The subclass size has to be exactly the same size with the original class size. The subclass\n  // cannot have more ivars/properties than its superclass since it will cause an offset in memory\n  // that can lead to overwriting the isa of an object in the next frame.\n  if (class_getInstanceSize(realClass) != class_getInstanceSize(appDelegateSubClass)) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling007],\n                @\"Cannot create subclass of App Delegate, because the created subclass is not the \"\n                @\"same size. %@\",\n                NSStringFromClass(realClass));\n    NSAssert(NO, @\"Classes must be the same size to swizzle isa\");\n    return nil;\n  }\n\n  // Make the newly created class to be the subclass of the real App Delegate class.\n  objc_registerClassPair(appDelegateSubClass);\n  if (object_setClass(appDelegate, appDelegateSubClass)) {\n    GULLogDebug(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling008],\n                @\"Successfully created App Delegate Proxy automatically. To disable the \"\n                @\"proxy, set the flag %@ to NO (Boolean) in the Info.plist\",\n                [GULAppDelegateSwizzler correctAppDelegateProxyKey]);\n  }\n\n  return appDelegateSubClass;\n}\n\n+ (void)proxyRemoteNotificationsMethodsWithAppDelegateSubClass:(Class)appDelegateSubClass\n                                                     realClass:(Class)realClass\n                                                   appDelegate:(id)appDelegate\n                                 realImplementationsBySelector:\n                                     (NSMutableDictionary *)realImplementationsBySelector {\n  if (realClass == nil || appDelegateSubClass == nil || appDelegate == nil ||\n      realImplementationsBySelector == nil) {\n    // The App Delegate has not been swizzled.\n    return;\n  }\n\n  // For application:didRegisterForRemoteNotificationsWithDeviceToken:\n  SEL didRegisterForRemoteNotificationsSEL =\n      NSSelectorFromString(kGULDidRegisterForRemoteNotificationsSEL);\n  SEL didRegisterForRemoteNotificationsDonorSEL = @selector(application:\n                 donor_didRegisterForRemoteNotificationsWithDeviceToken:);\n\n  [self proxyDestinationSelector:didRegisterForRemoteNotificationsSEL\n      implementationsFromSourceSelector:didRegisterForRemoteNotificationsDonorSEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n\n  // For application:didFailToRegisterForRemoteNotificationsWithError:\n  SEL didFailToRegisterForRemoteNotificationsSEL =\n      NSSelectorFromString(kGULDidFailToRegisterForRemoteNotificationsSEL);\n  SEL didFailToRegisterForRemoteNotificationsDonorSEL = @selector(application:\n                       donor_didFailToRegisterForRemoteNotificationsWithError:);\n\n  [self proxyDestinationSelector:didFailToRegisterForRemoteNotificationsSEL\n      implementationsFromSourceSelector:didFailToRegisterForRemoteNotificationsDonorSEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n\n  // For application:didReceiveRemoteNotification:\n  SEL didReceiveRemoteNotificationSEL = NSSelectorFromString(kGULDidReceiveRemoteNotificationSEL);\n  SEL didReceiveRemoteNotificationDonotSEL = @selector(application:\n                                donor_didReceiveRemoteNotification:);\n\n  [self proxyDestinationSelector:didReceiveRemoteNotificationSEL\n      implementationsFromSourceSelector:didReceiveRemoteNotificationDonotSEL\n                              fromClass:[GULAppDelegateSwizzler class]\n                                toClass:appDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n\n  // For application:didReceiveRemoteNotification:fetchCompletionHandler:\n#if !TARGET_OS_WATCH && !TARGET_OS_OSX\n  SEL didReceiveRemoteNotificationWithCompletionSEL =\n      NSSelectorFromString(kGULDidReceiveRemoteNotificationWithCompletionSEL);\n  SEL didReceiveRemoteNotificationWithCompletionDonorSEL =\n      @selector(application:donor_didReceiveRemoteNotification:fetchCompletionHandler:);\n  if ([appDelegate respondsToSelector:didReceiveRemoteNotificationWithCompletionSEL]) {\n    // Only add the application:didReceiveRemoteNotification:fetchCompletionHandler: method if\n    // the original AppDelegate implements it.\n    // This fixes a bug if an app only implements application:didReceiveRemoteNotification:\n    // (if we add the method with completion, iOS sees that one exists and does not call\n    // the method without the completion, which in this case is the only one the app implements).\n\n    [self proxyDestinationSelector:didReceiveRemoteNotificationWithCompletionSEL\n        implementationsFromSourceSelector:didReceiveRemoteNotificationWithCompletionDonorSEL\n                                fromClass:[GULAppDelegateSwizzler class]\n                                  toClass:appDelegateSubClass\n                                realClass:realClass\n         storeDestinationImplementationTo:realImplementationsBySelector];\n  }\n#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX\n}\n\n/// We have to do this to invalidate the cache that caches the original respondsToSelector of\n/// openURL handlers. Without this, it won't call the default implementations because the system\n/// checks and caches them.\n/// Register KVO only once. Otherwise, the observing method will be called as many times as\n/// being registered.\n+ (void)reassignAppDelegate {\n#if !TARGET_OS_WATCH\n  id<GULApplicationDelegate> delegate = [self sharedApplication].delegate;\n  [self sharedApplication].delegate = nil;\n  [self sharedApplication].delegate = delegate;\n  gOriginalAppDelegate = delegate;\n  [[GULAppDelegateObserver sharedInstance] observeUIApplication];\n#endif\n}\n\n#pragma mark - Helper methods\n\n+ (GULMutableDictionary *)interceptors {\n  static dispatch_once_t onceToken;\n  static GULMutableDictionary *sInterceptors;\n  dispatch_once(&onceToken, ^{\n    sInterceptors = [[GULMutableDictionary alloc] init];\n  });\n  return sInterceptors;\n}\n\n+ (nullable NSValue *)originalImplementationForSelector:(SEL)selector object:(id)object {\n  NSDictionary *realImplementationBySelector =\n      objc_getAssociatedObject(object, &kGULRealIMPBySelectorKey);\n  return realImplementationBySelector[NSStringFromSelector(selector)];\n}\n\n+ (void)proxyDestinationSelector:(SEL)destinationSelector\n    implementationsFromSourceSelector:(SEL)sourceSelector\n                            fromClass:(Class)sourceClass\n                              toClass:(Class)destinationClass\n                            realClass:(Class)realClass\n     storeDestinationImplementationTo:\n         (NSMutableDictionary<NSString *, NSValue *> *)destinationImplementationsBySelector {\n  [self addInstanceMethodWithDestinationSelector:destinationSelector\n            withImplementationFromSourceSelector:sourceSelector\n                                       fromClass:sourceClass\n                                         toClass:destinationClass];\n  IMP sourceImplementation =\n      [GULAppDelegateSwizzler implementationOfMethodSelector:destinationSelector\n                                                   fromClass:realClass];\n  NSValue *sourceImplementationPointer = [NSValue valueWithPointer:sourceImplementation];\n\n  NSString *destinationSelectorString = NSStringFromSelector(destinationSelector);\n  destinationImplementationsBySelector[destinationSelectorString] = sourceImplementationPointer;\n}\n\n/** Copies a method identified by the methodSelector from one class to the other. After this method\n *  is called, performing [toClassInstance methodSelector] will be similar to calling\n *  [fromClassInstance methodSelector]. This method does nothing if toClass already has a method\n *  identified by methodSelector.\n *\n *  @param methodSelector The SEL that identifies both the method on the fromClass as well as the\n *      one on the toClass.\n *  @param fromClass The class from which a method is sourced.\n *  @param toClass The class to which the method is added. If the class already has a method with\n *      the same selector, this has no effect.\n */\n+ (void)addInstanceMethodWithSelector:(SEL)methodSelector\n                            fromClass:(Class)fromClass\n                              toClass:(Class)toClass {\n  [self addInstanceMethodWithDestinationSelector:methodSelector\n            withImplementationFromSourceSelector:methodSelector\n                                       fromClass:fromClass\n                                         toClass:toClass];\n}\n\n/** Copies a method identified by the sourceSelector from the fromClass as a method for the\n *  destinationSelector on the toClass. After this method is called, performing\n *  [toClassInstance destinationSelector] will be similar to calling\n *  [fromClassInstance sourceSelector]. This method does nothing if toClass already has a method\n *  identified by destinationSelector.\n *\n *  @param destinationSelector The SEL that identifies the method on the toClass.\n *  @param sourceSelector The SEL that identifies the method on the fromClass.\n *  @param fromClass The class from which a method is sourced.\n *  @param toClass The class to which the method is added. If the class already has a method with\n *      the same selector, this has no effect.\n */\n+ (void)addInstanceMethodWithDestinationSelector:(SEL)destinationSelector\n            withImplementationFromSourceSelector:(SEL)sourceSelector\n                                       fromClass:(Class)fromClass\n                                         toClass:(Class)toClass {\n  Method method = class_getInstanceMethod(fromClass, sourceSelector);\n  IMP methodIMP = method_getImplementation(method);\n  const char *types = method_getTypeEncoding(method);\n  if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) {\n    GULLogWarning(kGULLoggerSwizzler, NO,\n                  [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                             (long)kGULSwizzlerMessageCodeAppDelegateSwizzling009],\n                  @\"Cannot copy method to destination selector %@ as it already exists\",\n                  NSStringFromSelector(destinationSelector));\n  }\n}\n\n/** Gets the IMP of the instance method on the class identified by the selector.\n *\n *  @param selector The selector of which the IMP is to be fetched.\n *  @param aClass The class from which the IMP is to be fetched.\n *  @return The IMP of the instance method identified by selector and aClass.\n */\n+ (IMP)implementationOfMethodSelector:(SEL)selector fromClass:(Class)aClass {\n  Method aMethod = class_getInstanceMethod(aClass, selector);\n  return method_getImplementation(aMethod);\n}\n\n/** Enumerates through all the interceptors and if they respond to a given selector, executes a\n *  GULAppDelegateInterceptorCallback with the interceptor.\n *\n *  @param methodSelector The SEL to check if an interceptor responds to.\n *  @param callback the GULAppDelegateInterceptorCallback.\n */\n+ (void)notifyInterceptorsWithMethodSelector:(SEL)methodSelector\n                                    callback:(GULAppDelegateInterceptorCallback)callback {\n  if (!callback) {\n    return;\n  }\n\n  NSDictionary *interceptors = [GULAppDelegateSwizzler interceptors].dictionary;\n  [interceptors enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {\n    GULZeroingWeakContainer *interceptorContainer = obj;\n    id interceptor = interceptorContainer.object;\n    if (!interceptor) {\n      GULLogWarning(\n          kGULLoggerSwizzler, NO,\n          [NSString\n              stringWithFormat:@\"I-SWZ%06ld\", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling010],\n          @\"AppDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.\", key);\n      [[GULAppDelegateSwizzler interceptors] removeObjectForKey:key];\n      return;\n    }\n    if ([interceptor respondsToSelector:methodSelector]) {\n      callback(interceptor);\n    }\n  }];\n}\n\n// The methods below are donor methods which are added to the dynamic subclass of the App Delegate.\n// They are called within the scope of the real App Delegate so |self| does not refer to the\n// GULAppDelegateSwizzler instance but the real App Delegate instance.\n\n#pragma mark - [Donor Methods] Overridden instance description method\n\n- (NSString *)fakeDescription {\n  Class realClass = objc_getAssociatedObject(self, &kGULRealClassKey);\n  return [NSString stringWithFormat:@\"<%@: %p>\", realClass, self];\n}\n\n#pragma mark - [Donor Methods] URL overridden handler methods\n#if TARGET_OS_IOS || TARGET_OS_TV\n\n- (BOOL)application:(GULApplication *)application\n            openURL:(NSURL *)url\n            options:(NSDictionary<NSString *, id> *)options {\n  SEL methodSelector = @selector(application:openURL:options:);\n  // Call the real implementation if the real App Delegate has any.\n  NSValue *openURLIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealOpenURLOptionsIMP openURLOptionsIMP = [openURLIMPPointer pointerValue];\n\n  __block BOOL returnedValue = NO;\n\n// This is needed to for the library to be warning free on iOS versions < 9.\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    returnedValue |= [interceptor application:application\n                                                                      openURL:url\n                                                                      options:options];\n                                  }];\n#pragma clang diagnostic pop\n  if (openURLOptionsIMP) {\n    returnedValue |= openURLOptionsIMP(self, methodSelector, application, url, options);\n  }\n  return returnedValue;\n}\n\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#if TARGET_OS_IOS\n\n- (BOOL)application:(GULApplication *)application\n              openURL:(NSURL *)url\n    sourceApplication:(NSString *)sourceApplication\n           annotation:(id)annotation {\n  SEL methodSelector = @selector(application:openURL:sourceApplication:annotation:);\n\n  // Call the real implementation if the real App Delegate has any.\n  NSValue *openURLSourceAppAnnotationIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealOpenURLSourceApplicationAnnotationIMP openURLSourceApplicationAnnotationIMP =\n      [openURLSourceAppAnnotationIMPPointer pointerValue];\n\n  __block BOOL returnedValue = NO;\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n                                    returnedValue |= [interceptor application:application\n                                                                      openURL:url\n                                                            sourceApplication:sourceApplication\n                                                                   annotation:annotation];\n#pragma clang diagnostic pop\n                                  }];\n  if (openURLSourceApplicationAnnotationIMP) {\n    returnedValue |= openURLSourceApplicationAnnotationIMP(self, methodSelector, application, url,\n                                                           sourceApplication, annotation);\n  }\n  return returnedValue;\n}\n\n#endif  // TARGET_OS_IOS\n\n#pragma mark - [Donor Methods] Network overridden handler methods\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wstrict-prototypes\"\n- (void)application:(GULApplication *)application\n    handleEventsForBackgroundURLSession:(NSString *)identifier\n                      completionHandler:(void (^)())completionHandler API_AVAILABLE(ios(7.0)) {\n#pragma clang diagnostic pop\n  SEL methodSelector = @selector(application:\n         handleEventsForBackgroundURLSession:completionHandler:);\n  NSValue *handleBackgroundSessionPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealHandleEventsForBackgroundURLSessionIMP handleBackgroundSessionIMP =\n      [handleBackgroundSessionPointer pointerValue];\n\n  // Notify interceptors.\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    [interceptor application:application\n                                        handleEventsForBackgroundURLSession:identifier\n                                                          completionHandler:completionHandler];\n                                  }];\n  // Call the real implementation if the real App Delegate has any.\n  if (handleBackgroundSessionIMP) {\n    handleBackgroundSessionIMP(self, methodSelector, application, identifier, completionHandler);\n  }\n}\n\n#endif  // TARGET_OS_IOS || TARGET_OS_TV\n\n#pragma mark - [Donor Methods] User Activities overridden handler methods\n\n- (BOOL)application:(GULApplication *)application\n    continueUserActivity:(NSUserActivity *)userActivity\n      restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {\n  SEL methodSelector = @selector(application:continueUserActivity:restorationHandler:);\n  NSValue *continueUserActivityIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealContinueUserActivityIMP continueUserActivityIMP =\n      continueUserActivityIMPPointer.pointerValue;\n\n  __block BOOL returnedValue = NO;\n#if !TARGET_OS_WATCH\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    returnedValue |= [interceptor application:application\n                                                         continueUserActivity:userActivity\n                                                           restorationHandler:restorationHandler];\n                                  }];\n#endif\n  // Call the real implementation if the real App Delegate has any.\n  if (continueUserActivityIMP) {\n    returnedValue |= continueUserActivityIMP(self, methodSelector, application, userActivity,\n                                             restorationHandler);\n  }\n  return returnedValue;\n}\n\n#pragma mark - [Donor Methods] Remote Notifications\n\n- (void)application:(GULApplication *)application\n    donor_didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {\n  SEL methodSelector = NSSelectorFromString(kGULDidRegisterForRemoteNotificationsSEL);\n\n  NSValue *didRegisterForRemoteNotificationsIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealDidRegisterForRemoteNotificationsIMP didRegisterForRemoteNotificationsIMP =\n      [didRegisterForRemoteNotificationsIMPPointer pointerValue];\n\n  // Notify interceptors.\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    NSInvocation *invocation = [GULAppDelegateSwizzler\n                                        appDelegateInvocationForSelector:methodSelector];\n                                    [invocation setTarget:interceptor];\n                                    [invocation setSelector:methodSelector];\n                                    [invocation setArgument:(void *)(&application) atIndex:2];\n                                    [invocation setArgument:(void *)(&deviceToken) atIndex:3];\n                                    [invocation invoke];\n                                  }];\n  // Call the real implementation if the real App Delegate has any.\n  if (didRegisterForRemoteNotificationsIMP) {\n    didRegisterForRemoteNotificationsIMP(self, methodSelector, application, deviceToken);\n  }\n}\n\n- (void)application:(GULApplication *)application\n    donor_didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {\n  SEL methodSelector = NSSelectorFromString(kGULDidFailToRegisterForRemoteNotificationsSEL);\n  NSValue *didFailToRegisterForRemoteNotificationsIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealDidFailToRegisterForRemoteNotificationsIMP didFailToRegisterForRemoteNotificationsIMP =\n      [didFailToRegisterForRemoteNotificationsIMPPointer pointerValue];\n\n  // Notify interceptors.\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    NSInvocation *invocation = [GULAppDelegateSwizzler\n                                        appDelegateInvocationForSelector:methodSelector];\n                                    [invocation setTarget:interceptor];\n                                    [invocation setSelector:methodSelector];\n                                    [invocation setArgument:(void *)(&application) atIndex:2];\n                                    [invocation setArgument:(void *)(&error) atIndex:3];\n                                    [invocation invoke];\n                                  }];\n  // Call the real implementation if the real App Delegate has any.\n  if (didFailToRegisterForRemoteNotificationsIMP) {\n    didFailToRegisterForRemoteNotificationsIMP(self, methodSelector, application, error);\n  }\n}\n\n#if !TARGET_OS_WATCH && !TARGET_OS_OSX\n- (void)application:(GULApplication *)application\n    donor_didReceiveRemoteNotification:(NSDictionary *)userInfo\n                fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {\n  SEL methodSelector = NSSelectorFromString(kGULDidReceiveRemoteNotificationWithCompletionSEL);\n  NSValue *didReceiveRemoteNotificationWithCompletionIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealDidReceiveRemoteNotificationWithCompletionIMP\n      didReceiveRemoteNotificationWithCompletionIMP =\n          [didReceiveRemoteNotificationWithCompletionIMPPointer pointerValue];\n\n  dispatch_group_t __block callbackGroup = dispatch_group_create();\n  NSMutableArray<NSNumber *> *__block fetchResults = [NSMutableArray array];\n\n  void (^localCompletionHandler)(UIBackgroundFetchResult) =\n      ^void(UIBackgroundFetchResult fetchResult) {\n        [fetchResults addObject:[NSNumber numberWithInt:(int)fetchResult]];\n        dispatch_group_leave(callbackGroup);\n      };\n\n  // Notify interceptors.\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    dispatch_group_enter(callbackGroup);\n\n                                    NSInvocation *invocation = [GULAppDelegateSwizzler\n                                        appDelegateInvocationForSelector:methodSelector];\n                                    [invocation setTarget:interceptor];\n                                    [invocation setSelector:methodSelector];\n                                    [invocation setArgument:(void *)(&application) atIndex:2];\n                                    [invocation setArgument:(void *)(&userInfo) atIndex:3];\n                                    [invocation setArgument:(void *)(&localCompletionHandler)\n                                                    atIndex:4];\n                                    [invocation invoke];\n                                  }];\n  // Call the real implementation if the real App Delegate has any.\n  if (didReceiveRemoteNotificationWithCompletionIMP) {\n    dispatch_group_enter(callbackGroup);\n\n    didReceiveRemoteNotificationWithCompletionIMP(self, methodSelector, application, userInfo,\n                                                  localCompletionHandler);\n  }\n\n  dispatch_group_notify(callbackGroup, dispatch_get_main_queue(), ^() {\n    BOOL allFetchesFailed = YES;\n    BOOL anyFetchHasNewData = NO;\n\n    for (NSNumber *oneResult in fetchResults) {\n      UIBackgroundFetchResult result = oneResult.intValue;\n\n      switch (result) {\n        case UIBackgroundFetchResultNoData:\n          allFetchesFailed = NO;\n          break;\n        case UIBackgroundFetchResultNewData:\n          allFetchesFailed = NO;\n          anyFetchHasNewData = YES;\n          break;\n        case UIBackgroundFetchResultFailed:\n\n          break;\n      }\n    }\n\n    UIBackgroundFetchResult finalFetchResult = UIBackgroundFetchResultNoData;\n\n    if (allFetchesFailed) {\n      finalFetchResult = UIBackgroundFetchResultFailed;\n    } else if (anyFetchHasNewData) {\n      finalFetchResult = UIBackgroundFetchResultNewData;\n    } else {\n      finalFetchResult = UIBackgroundFetchResultNoData;\n    }\n\n    completionHandler(finalFetchResult);\n  });\n}\n#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX\n\n- (void)application:(GULApplication *)application\n    donor_didReceiveRemoteNotification:(NSDictionary *)userInfo {\n  SEL methodSelector = NSSelectorFromString(kGULDidReceiveRemoteNotificationSEL);\n  NSValue *didReceiveRemoteNotificationIMPPointer =\n      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n  GULRealDidReceiveRemoteNotificationIMP didReceiveRemoteNotificationIMP =\n      [didReceiveRemoteNotificationIMPPointer pointerValue];\n\n  // Notify interceptors.\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n  [GULAppDelegateSwizzler\n      notifyInterceptorsWithMethodSelector:methodSelector\n                                  callback:^(id<GULApplicationDelegate> interceptor) {\n                                    NSInvocation *invocation = [GULAppDelegateSwizzler\n                                        appDelegateInvocationForSelector:methodSelector];\n                                    [invocation setTarget:interceptor];\n                                    [invocation setSelector:methodSelector];\n                                    [invocation setArgument:(void *)(&application) atIndex:2];\n                                    [invocation setArgument:(void *)(&userInfo) atIndex:3];\n                                    [invocation invoke];\n                                  }];\n#pragma clang diagnostic pop\n  // Call the real implementation if the real App Delegate has any.\n  if (didReceiveRemoteNotificationIMP) {\n    didReceiveRemoteNotificationIMP(self, methodSelector, application, userInfo);\n  }\n}\n\n+ (nullable NSInvocation *)appDelegateInvocationForSelector:(SEL)selector {\n  struct objc_method_description methodDescription =\n      protocol_getMethodDescription(@protocol(GULApplicationDelegate), selector, NO, YES);\n  if (methodDescription.types == NULL) {\n    return nil;\n  }\n\n  NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:methodDescription.types];\n  return [NSInvocation invocationWithMethodSignature:signature];\n}\n\n+ (void)proxyAppDelegate:(id<GULApplicationDelegate>)appDelegate {\n  if (![appDelegate conformsToProtocol:@protocol(GULApplicationDelegate)]) {\n    GULLogNotice(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\",\n                             (long)kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate],\n        @\"App Delegate does not conform to UIApplicationDelegate protocol. %@\",\n        [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);\n    return;\n  }\n\n  id<GULApplicationDelegate> originalDelegate = appDelegate;\n  // Do not create a subclass if it is not enabled.\n  if (![GULAppDelegateSwizzler isAppDelegateProxyEnabled]) {\n    GULLogNotice(kGULLoggerSwizzler, NO,\n                 [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                            (long)kGULSwizzlerMessageCodeAppDelegateSwizzling011],\n                 @\"App Delegate Proxy is disabled. %@\",\n                 [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);\n    return;\n  }\n  // Do not accept nil delegate.\n  if (!originalDelegate) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling012],\n                @\"Cannot create App Delegate Proxy because App Delegate instance is nil. %@\",\n                [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);\n    return;\n  }\n\n  @try {\n    gOriginalAppDelegateClass = [originalDelegate class];\n    gAppDelegateSubclass = [self createSubclassWithObject:originalDelegate];\n    [self reassignAppDelegate];\n  } @catch (NSException *exception) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling013],\n                @\"Cannot create App Delegate Proxy. %@\",\n                [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);\n    return;\n  }\n}\n\n#pragma mark - Methods to print correct debug logs\n\n+ (NSString *)correctAppDelegateProxyKey {\n  return NSClassFromString(@\"FIRCore\") ? kGULFirebaseAppDelegateProxyEnabledPlistKey\n                                       : kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey;\n}\n\n+ (NSString *)correctAlternativeWhenAppDelegateProxyNotCreated {\n  return NSClassFromString(@\"FIRCore\")\n             ? @\"To log deep link campaigns manually, call the methods in \"\n               @\"FIRAnalytics+AppDelegate.h.\"\n             : @\"\";\n}\n\n#pragma mark - Private Methods for Testing\n\n+ (void)clearInterceptors {\n  [[self interceptors] removeAllObjects];\n}\n\n+ (void)resetProxyOriginalDelegateOnceToken {\n  sProxyAppDelegateOnceToken = 0;\n  sProxyAppDelegateRemoteNotificationOnceToken = 0;\n}\n\n+ (id<GULApplicationDelegate>)originalDelegate {\n  return gOriginalAppDelegate;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m",
    "content": "// Copyright 2019 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <TargetConditionals.h>\n\n#import \"GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h\"\n\n#import \"GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h\"\n#import \"GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h\"\n#import \"GoogleUtilities/Common/GULLoggerCodes.h\"\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h\"\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n\n#import <objc/runtime.h>\n\n#if UISCENE_SUPPORTED\nAPI_AVAILABLE(ios(13.0), tvos(13.0))\ntypedef void (*GULOpenURLContextsIMP)(id, SEL, UIScene *, NSSet<UIOpenURLContext *> *);\n\nAPI_AVAILABLE(ios(13.0), tvos(13.0))\ntypedef void (^GULSceneDelegateInterceptorCallback)(id<UISceneDelegate>);\n\n// The strings below are the keys for associated objects.\nstatic char const *const kGULRealIMPBySelectorKey = \"GUL_realIMPBySelector\";\nstatic char const *const kGULRealClassKey = \"GUL_realClass\";\n#endif  // UISCENE_SUPPORTED\n\nstatic GULLoggerService kGULLoggerSwizzler = @\"[GoogleUtilities/SceneDelegateSwizzler]\";\n\n// Since Firebase SDKs also use this for app delegate proxying, in order to not be a breaking change\n// we disable App Delegate proxying when either of these two flags are set to NO.\n\n/** Plist key that allows Firebase developers to disable App and Scene Delegate Proxying. */\nstatic NSString *const kGULFirebaseSceneDelegateProxyEnabledPlistKey =\n    @\"FirebaseAppDelegateProxyEnabled\";\n\n/** Plist key that allows developers not using Firebase to disable App and Scene Delegate Proxying.\n */\nstatic NSString *const kGULGoogleUtilitiesSceneDelegateProxyEnabledPlistKey =\n    @\"GoogleUtilitiesAppDelegateProxyEnabled\";\n\n/** The prefix of the Scene Delegate. */\nstatic NSString *const kGULSceneDelegatePrefix = @\"GUL_\";\n\n/**\n * This class is necessary to store the delegates in an NSArray without retaining them.\n * [NSValue valueWithNonRetainedObject] also provides this functionality, but does not provide a\n * zeroing pointer. This will cause EXC_BAD_ACCESS when trying to access the object after it is\n * dealloced. Instead, this container stores a weak, zeroing reference to the object, which\n * automatically is set to nil by the runtime when the object is dealloced.\n */\n@interface GULSceneZeroingWeakContainer : NSObject\n\n/** Stores a weak object. */\n@property(nonatomic, weak) id object;\n\n@end\n\n@implementation GULSceneZeroingWeakContainer\n@end\n\n@implementation GULSceneDelegateSwizzler\n\n#pragma mark - Public methods\n\n+ (BOOL)isSceneDelegateProxyEnabled {\n  return [GULAppDelegateSwizzler isAppDelegateProxyEnabled];\n}\n\n+ (void)proxyOriginalSceneDelegate {\n#if UISCENE_SUPPORTED\n  if ([GULAppEnvironmentUtil isAppExtension]) {\n    return;\n  }\n\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    if (@available(iOS 13.0, tvOS 13.0, *)) {\n      if (![GULSceneDelegateSwizzler isSceneDelegateProxyEnabled]) {\n        return;\n      }\n      [[NSNotificationCenter defaultCenter]\n        addObserver:self\n           selector:@selector(handleSceneWillConnectToNotification:)\n               name:UISceneWillConnectNotification\n             object:nil];\n    }\n  });\n#endif  // UISCENE_SUPPORTED\n}\n\n#if UISCENE_SUPPORTED\n+ (GULSceneDelegateInterceptorID)registerSceneDelegateInterceptor:(id<UISceneDelegate>)interceptor {\n  NSAssert(interceptor, @\"SceneDelegateProxy cannot add nil interceptor\");\n  NSAssert([interceptor conformsToProtocol:@protocol(UISceneDelegate)],\n           @\"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate\");\n\n  if (!interceptor) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling000],\n                @\"SceneDelegateProxy cannot add nil interceptor.\");\n    return nil;\n  }\n  if (![interceptor conformsToProtocol:@protocol(UISceneDelegate)]) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling001],\n                @\"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate\");\n    return nil;\n  }\n\n  // The ID should be the same given the same interceptor object.\n  NSString *interceptorID =\n      [NSString stringWithFormat:@\"%@%p\", kGULSceneDelegatePrefix, interceptor];\n  if (!interceptorID.length) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling002],\n                @\"SceneDelegateProxy cannot create Interceptor ID.\");\n    return nil;\n  }\n  GULSceneZeroingWeakContainer *weakObject = [[GULSceneZeroingWeakContainer alloc] init];\n  weakObject.object = interceptor;\n  [GULSceneDelegateSwizzler interceptors][interceptorID] = weakObject;\n  return interceptorID;\n}\n\n+ (void)unregisterSceneDelegateInterceptorWithID:(GULSceneDelegateInterceptorID)interceptorID {\n  NSAssert(interceptorID, @\"SceneDelegateProxy cannot unregister nil interceptor ID.\");\n  NSAssert(((NSString *)interceptorID).length != 0,\n           @\"SceneDelegateProxy cannot unregister empty interceptor ID.\");\n\n  if (!interceptorID) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling003],\n                @\"SceneDelegateProxy cannot unregister empty interceptor ID.\");\n    return;\n  }\n\n  GULSceneZeroingWeakContainer *weakContainer =\n      [GULSceneDelegateSwizzler interceptors][interceptorID];\n  if (!weakContainer.object) {\n    GULLogError(kGULLoggerSwizzler, NO,\n                [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling004],\n                @\"SceneDelegateProxy cannot unregister interceptor that was not registered. \"\n                 \"Interceptor ID %@\",\n                interceptorID);\n    return;\n  }\n\n  [[GULSceneDelegateSwizzler interceptors] removeObjectForKey:interceptorID];\n}\n\n#pragma mark - Helper methods\n\n+ (GULMutableDictionary *)interceptors {\n  static dispatch_once_t onceToken;\n  static GULMutableDictionary *sInterceptors;\n  dispatch_once(&onceToken, ^{\n    sInterceptors = [[GULMutableDictionary alloc] init];\n  });\n  return sInterceptors;\n}\n\n+ (void)clearInterceptors {\n  [[self interceptors] removeAllObjects];\n}\n\n+ (nullable NSValue *)originalImplementationForSelector:(SEL)selector object:(id)object {\n  NSDictionary *realImplementationBySelector =\n      objc_getAssociatedObject(object, &kGULRealIMPBySelectorKey);\n  return realImplementationBySelector[NSStringFromSelector(selector)];\n}\n\n+ (void)proxyDestinationSelector:(SEL)destinationSelector\n    implementationsFromSourceSelector:(SEL)sourceSelector\n                            fromClass:(Class)sourceClass\n                              toClass:(Class)destinationClass\n                            realClass:(Class)realClass\n     storeDestinationImplementationTo:\n         (NSMutableDictionary<NSString *, NSValue *> *)destinationImplementationsBySelector {\n  [self addInstanceMethodWithDestinationSelector:destinationSelector\n            withImplementationFromSourceSelector:sourceSelector\n                                       fromClass:sourceClass\n                                         toClass:destinationClass];\n  IMP sourceImplementation =\n      [GULSceneDelegateSwizzler implementationOfMethodSelector:destinationSelector\n                                                     fromClass:realClass];\n  NSValue *sourceImplementationPointer = [NSValue valueWithPointer:sourceImplementation];\n\n  NSString *destinationSelectorString = NSStringFromSelector(destinationSelector);\n  destinationImplementationsBySelector[destinationSelectorString] = sourceImplementationPointer;\n}\n\n/** Copies a method identified by the methodSelector from one class to the other. After this method\n *  is called, performing [toClassInstance methodSelector] will be similar to calling\n *  [fromClassInstance methodSelector]. This method does nothing if toClass already has a method\n *  identified by methodSelector.\n *\n *  @param methodSelector The SEL that identifies both the method on the fromClass as well as the\n *      one on the toClass.\n *  @param fromClass The class from which a method is sourced.\n *  @param toClass The class to which the method is added. If the class already has a method with\n *      the same selector, this has no effect.\n */\n+ (void)addInstanceMethodWithSelector:(SEL)methodSelector\n                            fromClass:(Class)fromClass\n                              toClass:(Class)toClass {\n  [self addInstanceMethodWithDestinationSelector:methodSelector\n            withImplementationFromSourceSelector:methodSelector\n                                       fromClass:fromClass\n                                         toClass:toClass];\n}\n\n/** Copies a method identified by the sourceSelector from the fromClass as a method for the\n *  destinationSelector on the toClass. After this method is called, performing\n *  [toClassInstance destinationSelector] will be similar to calling\n *  [fromClassInstance sourceSelector]. This method does nothing if toClass already has a method\n *  identified by destinationSelector.\n *\n *  @param destinationSelector The SEL that identifies the method on the toClass.\n *  @param sourceSelector The SEL that identifies the method on the fromClass.\n *  @param fromClass The class from which a method is sourced.\n *  @param toClass The class to which the method is added. If the class already has a method with\n *      the same selector, this has no effect.\n */\n+ (void)addInstanceMethodWithDestinationSelector:(SEL)destinationSelector\n            withImplementationFromSourceSelector:(SEL)sourceSelector\n                                       fromClass:(Class)fromClass\n                                         toClass:(Class)toClass {\n  Method method = class_getInstanceMethod(fromClass, sourceSelector);\n  IMP methodIMP = method_getImplementation(method);\n  const char *types = method_getTypeEncoding(method);\n  if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) {\n    GULLogWarning(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling009],\n        @\"Cannot copy method to destination selector %@ as it already exists\",\n        NSStringFromSelector(destinationSelector));\n  }\n}\n\n/** Gets the IMP of the instance method on the class identified by the selector.\n *\n *  @param selector The selector of which the IMP is to be fetched.\n *  @param aClass The class from which the IMP is to be fetched.\n *  @return The IMP of the instance method identified by selector and aClass.\n */\n+ (IMP)implementationOfMethodSelector:(SEL)selector fromClass:(Class)aClass {\n  Method aMethod = class_getInstanceMethod(aClass, selector);\n  return method_getImplementation(aMethod);\n}\n\n/** Enumerates through all the interceptors and if they respond to a given selector, executes a\n *  GULSceneDelegateInterceptorCallback with the interceptor.\n *\n *  @param methodSelector The SEL to check if an interceptor responds to.\n *  @param callback the GULSceneDelegateInterceptorCallback.\n */\n+ (void)notifyInterceptorsWithMethodSelector:(SEL)methodSelector\n                                    callback:(GULSceneDelegateInterceptorCallback)callback\n    API_AVAILABLE(ios(13.0)) {\n  if (!callback) {\n    return;\n  }\n\n  NSDictionary *interceptors = [GULSceneDelegateSwizzler interceptors].dictionary;\n  [interceptors enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {\n    GULSceneZeroingWeakContainer *interceptorContainer = obj;\n    id interceptor = interceptorContainer.object;\n    if (!interceptor) {\n      GULLogWarning(\n          kGULLoggerSwizzler, NO,\n          [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                     (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling010],\n          @\"SceneDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.\", key);\n      [[GULSceneDelegateSwizzler interceptors] removeObjectForKey:key];\n      return;\n    }\n    if ([interceptor respondsToSelector:methodSelector]) {\n      callback(interceptor);\n    }\n  }];\n}\n\n+ (void)handleSceneWillConnectToNotification:(NSNotification *)notification {\n  if (@available(iOS 13.0, tvOS 13.0, *)) {\n    if ([notification.object isKindOfClass:[UIScene class]]) {\n      UIScene *scene = (UIScene *)notification.object;\n      [GULSceneDelegateSwizzler proxySceneDelegateIfNeeded:scene];\n    }\n  }\n}\n\n#pragma mark - [Donor Methods] UISceneDelegate URL handler\n\n- (void)scene:(UIScene *)scene\n    openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts API_AVAILABLE(ios(13.0), tvos(13.0)) {\n  if (@available(iOS 13.0, tvOS 13.0, *)) {\n    SEL methodSelector = @selector(scene:openURLContexts:);\n    // Call the real implementation if the real Scene Delegate has any.\n    NSValue *openURLContextsIMPPointer =\n        [GULSceneDelegateSwizzler originalImplementationForSelector:methodSelector object:self];\n    GULOpenURLContextsIMP openURLContextsIMP = [openURLContextsIMPPointer pointerValue];\n\n    [GULSceneDelegateSwizzler\n        notifyInterceptorsWithMethodSelector:methodSelector\n                                    callback:^(id<UISceneDelegate> interceptor) {\n                                      if ([interceptor\n                                              conformsToProtocol:@protocol(UISceneDelegate)]) {\n                                        id<UISceneDelegate> sceneInterceptor =\n                                            (id<UISceneDelegate>)interceptor;\n                                        [sceneInterceptor scene:scene openURLContexts:URLContexts];\n                                      }\n                                    }];\n\n    if (openURLContextsIMP) {\n      openURLContextsIMP(self, methodSelector, scene, URLContexts);\n    }\n  }\n}\n\n+ (void)proxySceneDelegateIfNeeded:(UIScene *)scene {\n  Class realClass = [scene.delegate class];\n  NSString *className = NSStringFromClass(realClass);\n\n  // Skip proxying if failed to get the delegate class name for some reason (e.g. `delegate == nil`)\n  // or the class has a prefix of kGULAppDelegatePrefix, which means it has been proxied before.\n  if (className == nil || [className hasPrefix:kGULSceneDelegatePrefix]) {\n    return;\n  }\n\n  NSString *classNameWithPrefix = [kGULSceneDelegatePrefix stringByAppendingString:className];\n  NSString *newClassName =\n      [NSString stringWithFormat:@\"%@-%@\", classNameWithPrefix, [NSUUID UUID].UUIDString];\n\n  if (NSClassFromString(newClassName)) {\n    GULLogError(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\",\n                             (long)\n                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],\n        @\"Cannot create a proxy for Scene Delegate. Subclass already exists. Original Class\"\n        @\": %@, subclass: %@\",\n        className, newClassName);\n    return;\n  }\n\n  // Register the new class as subclass of the real one. Do not allocate more than the real class\n  // size.\n  Class sceneDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0);\n  if (sceneDelegateSubClass == Nil) {\n    GULLogError(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\",\n                             (long)\n                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],\n        @\"Cannot create a proxy for Scene Delegate. Subclass already exists. Original Class\"\n        @\": %@, subclass: Nil\",\n        className);\n    return;\n  }\n\n  NSMutableDictionary<NSString *, NSValue *> *realImplementationsBySelector =\n      [[NSMutableDictionary alloc] init];\n\n  // For scene:openURLContexts:\n  SEL openURLContextsSEL = @selector(scene:openURLContexts:);\n  [self proxyDestinationSelector:openURLContextsSEL\n      implementationsFromSourceSelector:openURLContextsSEL\n                              fromClass:[GULSceneDelegateSwizzler class]\n                                toClass:sceneDelegateSubClass\n                              realClass:realClass\n       storeDestinationImplementationTo:realImplementationsBySelector];\n\n  // Store original implementations to a fake property of the original delegate.\n  objc_setAssociatedObject(scene.delegate, &kGULRealIMPBySelectorKey,\n                           [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n  objc_setAssociatedObject(scene.delegate, &kGULRealClassKey, realClass,\n                           OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n\n  // The subclass size has to be exactly the same size with the original class size. The subclass\n  // cannot have more ivars/properties than its superclass since it will cause an offset in memory\n  // that can lead to overwriting the isa of an object in the next frame.\n  if (class_getInstanceSize(realClass) != class_getInstanceSize(sceneDelegateSubClass)) {\n    GULLogError(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\",\n                             (long)\n                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],\n        @\"Cannot create subclass of Scene Delegate, because the created subclass is not the \"\n        @\"same size. %@\",\n        className);\n    NSAssert(NO, @\"Classes must be the same size to swizzle isa\");\n    return;\n  }\n\n  // Make the newly created class to be the subclass of the real Scene Delegate class.\n  objc_registerClassPair(sceneDelegateSubClass);\n  if (object_setClass(scene.delegate, sceneDelegateSubClass)) {\n    GULLogDebug(\n        kGULLoggerSwizzler, NO,\n        [NSString\n            stringWithFormat:@\"I-SWZ%06ld\",\n                             (long)\n                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],\n        @\"Successfully created Scene Delegate Proxy automatically. To disable the \"\n        @\"proxy, set the flag %@ to NO (Boolean) in the Info.plist\",\n        [GULSceneDelegateSwizzler correctSceneDelegateProxyKey]);\n  }\n}\n\n+ (NSString *)correctSceneDelegateProxyKey {\n  return NSClassFromString(@\"FIRCore\") ? kGULFirebaseSceneDelegateProxyEnabledPlistKey\n                                       : kGULGoogleUtilitiesSceneDelegateProxyEnabledPlistKey;\n}\n\n#endif  // UISCENE_SUPPORTED\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import \"GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n\n@class GULApplication;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GULAppDelegateSwizzler ()\n\n/** ISA Swizzles the given appDelegate as the original app delegate would be.\n *\n *  @param appDelegate The object that needs to be isa swizzled. This should conform to the\n *      application delegate protocol.\n */\n+ (void)proxyAppDelegate:(id<GULApplicationDelegate>)appDelegate;\n\n/** Returns a dictionary containing interceptor IDs mapped to a GULZeroingWeakContainer.\n *\n *  @return A dictionary of the form {NSString : GULZeroingWeakContainer}, where the NSString is\n *      the interceptorID.\n */\n+ (GULMutableDictionary *)interceptors;\n\n/** Deletes all the registered interceptors. */\n+ (void)clearInterceptors;\n\n/** Resets the token that prevents the app delegate proxy from being isa swizzled multiple times. */\n+ (void)resetProxyOriginalDelegateOnceToken;\n\n/** Returns the original app delegate that was proxied.\n *\n *  @return The original app delegate instance that was proxied.\n */\n+ (id<GULApplicationDelegate>)originalDelegate;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import \"GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GULSceneDelegateSwizzler ()\n\n#if UISCENE_SUPPORTED\n\n/** Returns a dictionary containing interceptor IDs mapped to a GULZeroingWeakContainer.\n *\n *  @return A dictionary of the form {NSString : GULZeroingWeakContainer}, where the NSString is\n *      the interceptorID.\n */\n+ (GULMutableDictionary *)interceptors;\n\n/** Deletes all the registered interceptors. */\n+ (void)clearInterceptors;\n\n/** ISA Swizzles the given appDelegate as the original app delegate would be.\n *\n *  @param scene The scene whose delegate needs to be isa swizzled. This should conform to the\n *      scene delegate protocol.\n */\n+ (void)proxySceneDelegateIfNeeded:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0));\n\n#endif  // UISCENE_SUPPORTED\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULApplication.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NSString *const GULAppDelegateInterceptorID;\n\n/** This class contains methods that isa swizzle the app delegate. */\n@interface GULAppDelegateSwizzler : NSProxy\n\n/** Registers an app delegate interceptor whose methods will be invoked as they're invoked on the\n *  original app delegate.\n *\n *  @param interceptor An instance of a class that conforms to the application delegate protocol.\n *      The interceptor is NOT retained.\n *  @return A unique GULAppDelegateInterceptorID if interceptor was successfully registered; nil\n *      if it fails.\n */\n+ (nullable GULAppDelegateInterceptorID)registerAppDelegateInterceptor:\n    (id<GULApplicationDelegate>)interceptor;\n\n/** Unregisters an interceptor with the given ID if it exists.\n *\n *  @param interceptorID The object that was generated when the interceptor was registered.\n */\n+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID;\n\n/** This method ensures that the original app delegate has been proxied. Call this before\n *  registering your interceptor. This method is safe to call multiple times (but it only proxies\n *  the app delegate once).\n *\n *  This method doesn't proxy APNS related methods:\n *  @code\n *    - application:didRegisterForRemoteNotificationsWithDeviceToken:\n *    - application:didFailToRegisterForRemoteNotificationsWithError:\n *    - application:didReceiveRemoteNotification:fetchCompletionHandler:\n *    - application:didReceiveRemoteNotification:\n *  @endcode\n *\n *  To proxy these methods use +[GULAppDelegateSwizzler\n *  proxyOriginalDelegateIncludingAPNSMethods]. The methods have to be proxied separately to\n *  avoid potential warnings from Apple review about missing Push Notification Entitlement (e.g.\n *  https://github.com/firebase/firebase-ios-sdk/issues/2807)\n *\n *  The method has no effect for extensions.\n *\n *  @see proxyOriginalDelegateIncludingAPNSMethods\n */\n+ (void)proxyOriginalDelegate;\n\n/** This method ensures that the original app delegate has been proxied including APNS related\n *  methods. Call this before registering your interceptor. This method is safe to call multiple\n *  times (but it only proxies the app delegate once) or\n *  after +[GULAppDelegateSwizzler proxyOriginalDelegate]\n *\n *  This method calls +[GULAppDelegateSwizzler proxyOriginalDelegate] under the hood.\n *  After calling this method the following App Delegate methods will be proxied in addition to\n *  the methods proxied by proxyOriginalDelegate:\n *  @code\n *    - application:didRegisterForRemoteNotificationsWithDeviceToken:\n *    - application:didFailToRegisterForRemoteNotificationsWithError:\n *    - application:didReceiveRemoteNotification:fetchCompletionHandler:\n *    - application:didReceiveRemoteNotification:\n *  @endcode\n *\n *  The method has no effect for extensions.\n *\n *  @see proxyOriginalDelegate\n */\n+ (void)proxyOriginalDelegateIncludingAPNSMethods;\n\n/** Indicates whether app delegate proxy is explicitly disabled or enabled. Enabled by default.\n *\n *  @return YES if AppDelegateProxy is Enabled, NO otherwise.\n */\n+ (BOOL)isAppDelegateProxyEnabled;\n\n/** Returns the current sharedApplication.\n *\n *  @return the current application instance if in an app, or nil if in extension or if it doesn't\n * exist.\n */\n+ (nullable GULApplication *)sharedApplication;\n\n/** Do not initialize this class. */\n- (instancetype)init NS_UNAVAILABLE;\n\nNS_ASSUME_NONNULL_END\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n\n#import <UIKit/UIKit.h>\n\n#define GULApplication UIApplication\n#define GULApplicationDelegate UIApplicationDelegate\n#define GULUserActivityRestoring UIUserActivityRestoring\n\nstatic NSString *const kGULApplicationClassName = @\"UIApplication\";\n\n#elif TARGET_OS_OSX\n\n#import <AppKit/AppKit.h>\n\n#define GULApplication NSApplication\n#define GULApplicationDelegate NSApplicationDelegate\n#define GULUserActivityRestoring NSUserActivityRestoring\n\nstatic NSString *const kGULApplicationClassName = @\"NSApplication\";\n\n#elif TARGET_OS_WATCH\n\n#import <WatchKit/WatchKit.h>\n\n// We match the according watchOS API but swizzling should not work in watch\n#define GULApplication WKExtension\n#define GULApplicationDelegate WKExtensionDelegate\n#define GULUserActivityRestoring NSUserActivityRestoring\n\nstatic NSString *const kGULApplicationClassName = @\"WKExtension\";\n\n#endif\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h",
    "content": "/*\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <TargetConditionals.h>\n\n#if !TARGET_OS_OSX\n#import <UIKit/UIKit.h>\n#endif  // !TARGET_OS_OSX\n\n#if ((TARGET_OS_IOS || TARGET_OS_TV) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000))\n#define UISCENE_SUPPORTED 1\n#endif\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NSString *const GULSceneDelegateInterceptorID;\n\n/** This class contains methods that isa swizzle the scene delegate. */\n@interface GULSceneDelegateSwizzler : NSProxy\n\n#if UISCENE_SUPPORTED\n\n/** Registers a scene delegate interceptor whose methods will be invoked as they're invoked on the\n *  original scene delegate.\n *\n *  @param interceptor An instance of a class that conforms to the application delegate protocol.\n *      The interceptor is NOT retained.\n *  @return A unique GULSceneDelegateInterceptorID if interceptor was successfully registered; nil\n *      if it fails.\n */\n+ (nullable GULSceneDelegateInterceptorID)registerSceneDelegateInterceptor:\n    (id<UISceneDelegate>)interceptor API_AVAILABLE(ios(13.0), tvos(13.0));\n\n/** Unregisters an interceptor with the given ID if it exists.\n *\n *  @param interceptorID The object that was generated when the interceptor was registered.\n */\n+ (void)unregisterSceneDelegateInterceptorWithID:(GULSceneDelegateInterceptorID)interceptorID\n    API_AVAILABLE(ios(13.0), tvos(13.0));\n\n/** Do not initialize this class. */\n- (instancetype)init NS_UNAVAILABLE;\n\n#endif  // UISCENE_SUPPORTED\n\n/** This method ensures that the original scene delegate has been proxied. Call this before\n *  registering your interceptor. This method is safe to call multiple times (but it only proxies\n *  the scene delegate once).\n *\n *  The method has no effect for extensions.\n */\n+ (void)proxyOriginalSceneDelegate;\n\n/** Indicates whether scene delegate proxy is explicitly disabled or enabled. Enabled by default.\n *\n *  @return YES if SceneDelegateProxy is Enabled, NO otherwise.\n */\n+ (BOOL)isSceneDelegateProxyEnabled;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, GULSwizzlerMessageCode) {\n  // App Delegate Swizzling.\n  kGULSwizzlerMessageCodeAppDelegateSwizzling000 = 1000,                 // I-SWZ001000\n  kGULSwizzlerMessageCodeAppDelegateSwizzling001 = 1001,                 // I-SWZ001001\n  kGULSwizzlerMessageCodeAppDelegateSwizzling002 = 1002,                 // I-SWZ001002\n  kGULSwizzlerMessageCodeAppDelegateSwizzling003 = 1003,                 // I-SWZ001003\n  kGULSwizzlerMessageCodeAppDelegateSwizzling004 = 1004,                 // I-SWZ001004\n  kGULSwizzlerMessageCodeAppDelegateSwizzling005 = 1005,                 // I-SWZ001005\n  kGULSwizzlerMessageCodeAppDelegateSwizzling006 = 1006,                 // I-SWZ001006\n  kGULSwizzlerMessageCodeAppDelegateSwizzling007 = 1007,                 // I-SWZ001007\n  kGULSwizzlerMessageCodeAppDelegateSwizzling008 = 1008,                 // I-SWZ001008\n  kGULSwizzlerMessageCodeAppDelegateSwizzling009 = 1009,                 // I-SWZ001009\n  kGULSwizzlerMessageCodeAppDelegateSwizzling010 = 1010,                 // I-SWZ001010\n  kGULSwizzlerMessageCodeAppDelegateSwizzling011 = 1011,                 // I-SWZ001011\n  kGULSwizzlerMessageCodeAppDelegateSwizzling012 = 1012,                 // I-SWZ001012\n  kGULSwizzlerMessageCodeAppDelegateSwizzling013 = 1013,                 // I-SWZ001013\n  kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate = 1014,  // I-SWZ001014\n\n  // Scene Delegate Swizzling.\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling000 = 1100,                   // I-SWZ001100\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling001 = 1101,                   // I-SWZ001101\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling002 = 1102,                   // I-SWZ001102\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling003 = 1103,                   // I-SWZ001103\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling004 = 1104,                   // I-SWZ001104\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling005 = 1105,                   // I-SWZ001105\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling006 = 1106,                   // I-SWZ001106\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling007 = 1107,                   // I-SWZ001107\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling008 = 1108,                   // I-SWZ001108\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling009 = 1109,                   // I-SWZ001109\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling010 = 1110,                   // I-SWZ001110\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling011 = 1111,                   // I-SWZ001111\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling012 = 1112,                   // I-SWZ001112\n  kGULSwizzlerMessageCodeSceneDelegateSwizzling013 = 1113,                   // I-SWZ001113\n  kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate = 1114,  // I-SWZ001114\n\n  // Method Swizzling.\n  kGULSwizzlerMessageCodeMethodSwizzling000 = 2000,  // I-SWZ002000\n};\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorage.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h\"\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h\"\n\nNSString *const kGULHeartbeatStorageDirectory = @\"Google/FIRApp\";\n\n@interface GULHeartbeatDateStorage ()\n\n/** The name of the file that stores heartbeat information. */\n@property(nonatomic, readonly) NSString *fileName;\n@end\n\n@implementation GULHeartbeatDateStorage\n\n@synthesize fileURL = _fileURL;\n\n- (instancetype)initWithFileName:(NSString *)fileName {\n  if (fileName == nil) return nil;\n\n  self = [super init];\n  if (self) {\n    _fileName = fileName;\n  }\n  return self;\n}\n\n/** Lazy getter for fileURL.\n * @return fileURL where heartbeat information is stored.\n */\n- (NSURL *)fileURL {\n  if (!_fileURL) {\n    NSURL *directoryURL = [self directoryPathURL];\n    [self checkAndCreateDirectory:directoryURL];\n    _fileURL = [directoryURL URLByAppendingPathComponent:_fileName];\n  }\n  return _fileURL;\n}\n\n/** Returns the URL path of the directory for heartbeat storage data.\n * @return the URL path of the directory for heartbeat storage data.\n */\n- (NSURL *)directoryPathURL {\n  NSArray<NSString *> *paths;\n#if TARGET_OS_TV\n  paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);\n#else\n  paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);\n#endif  // TARGET_OS_TV\n  NSString *rootPath = [paths lastObject];\n  NSURL *rootURL = [NSURL fileURLWithPath:rootPath];\n  NSURL *directoryURL = [rootURL URLByAppendingPathComponent:kGULHeartbeatStorageDirectory];\n  return directoryURL;\n}\n\n/** Check for the existence of the directory specified by the URL, and create it if it does not\n * exist.\n * @param directoryPathURL The path to the directory that needs to exist.\n */\n- (void)checkAndCreateDirectory:(NSURL *)directoryPathURL {\n  NSError *error;\n  if (![directoryPathURL checkResourceIsReachableAndReturnError:&error]) {\n    NSError *error;\n    [[NSFileManager defaultManager] createDirectoryAtURL:directoryPathURL\n                             withIntermediateDirectories:YES\n                                              attributes:nil\n                                                   error:&error];\n  }\n}\n\n- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag {\n  @synchronized(self.class) {\n    NSDictionary *heartbeatDictionary = [self heartbeatDictionaryWithFileURL:self.fileURL];\n    NSDate *heartbeatDate = heartbeatDictionary[tag];\n\n    // Validate the value type. If the storage file was corrupted or updated with a different format\n    // by a newer SDK version the value type may be different.\n    if (![heartbeatDate isKindOfClass:[NSDate class]]) {\n      heartbeatDate = nil;\n    }\n\n    return heartbeatDate;\n  }\n}\n\n- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag {\n  // Synchronize on the class to ensure that the different instances of the class will not access\n  // the same file concurrently.\n  // TODO: Consider a different synchronization strategy here and in `-heartbeatDateForTag:` method.\n  // Currently no heartbeats can be read/written concurrently even if they are in different files.\n  @synchronized(self.class) {\n    NSMutableDictionary *heartbeatDictionary =\n        [[self heartbeatDictionaryWithFileURL:self.fileURL] mutableCopy];\n    heartbeatDictionary[tag] = date;\n    NSError *error;\n    BOOL isSuccess = [self writeDictionary:[heartbeatDictionary copy]\n                             forWritingURL:self.fileURL\n                                     error:&error];\n    return isSuccess;\n  }\n}\n\n- (NSDictionary *)heartbeatDictionaryWithFileURL:(NSURL *)readingFileURL {\n  NSDictionary *heartbeatDictionary;\n\n  NSError *error;\n  NSData *objectData = [NSData dataWithContentsOfURL:readingFileURL options:0 error:&error];\n\n  if (objectData.length > 0 && error == nil) {\n    NSSet<Class> *objectClasses =\n        [NSSet setWithArray:@[ NSDictionary.class, NSDate.class, NSString.class ]];\n    heartbeatDictionary = [GULSecureCoding unarchivedObjectOfClasses:objectClasses\n                                                            fromData:objectData\n                                                               error:&error];\n  }\n\n  if (heartbeatDictionary.count == 0 || error != nil) {\n    heartbeatDictionary = [NSDictionary dictionary];\n  }\n\n  return heartbeatDictionary;\n}\n\n- (BOOL)writeDictionary:(NSDictionary *)dictionary\n          forWritingURL:(NSURL *)writingFileURL\n                  error:(NSError **)outError {\n  // Archive a mutable copy `dictionary` for writing to disk. This is done for\n  // backwards compatibility. See Google Utilities issue #36 for more context.\n  // TODO: Remove usage of mutable copy in a future version of Google Utilities.\n  NSData *data = [GULSecureCoding archivedDataWithRootObject:[dictionary mutableCopy]\n                                                       error:outError];\n  if (data.length == 0) {\n    return NO;\n  }\n\n  return [data writeToURL:writingFileURL atomically:YES];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h\"\n\n@interface GULHeartbeatDateStorageUserDefaults ()\n\n/** The storage to store the date of the last sent heartbeat. */\n@property(nonatomic, readonly) NSUserDefaults *userDefaults;\n\n/** The key for user defaults to store heartbeat information. */\n@property(nonatomic, readonly) NSString *key;\n\n@end\n\n@implementation GULHeartbeatDateStorageUserDefaults\n\n- (instancetype)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key {\n  self = [super init];\n  if (self) {\n    _userDefaults = defaults;\n    _key = key;\n  }\n  return self;\n}\n\n- (NSMutableDictionary *)heartbeatDictionaryFromDefaults {\n  NSDictionary *heartbeatDict = [self.userDefaults objectForKey:self.key];\n  if (heartbeatDict != nil) {\n    return [heartbeatDict mutableCopy];\n  } else {\n    return [NSMutableDictionary dictionary];\n  }\n}\n\n- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag {\n  NSDate *date = nil;\n  @synchronized(self.userDefaults) {\n    NSMutableDictionary *dict = [self heartbeatDictionaryFromDefaults];\n    date = dict[tag];\n  }\n\n  return date;\n}\n\n- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag {\n  @synchronized(self.userDefaults) {\n    NSMutableDictionary *dict = [self heartbeatDictionaryFromDefaults];\n    dict[tag] = date;\n    [self.userDefaults setObject:dict forKey:self.key];\n  }\n  return true;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/GULSecureCoding.m",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h\"\n\nNSString *const kGULSecureCodingError = @\"GULSecureCodingError\";\n\n@implementation GULSecureCoding\n\n+ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes\n                                fromData:(NSData *)data\n                                   error:(NSError **)outError {\n  id object;\n#if __has_builtin(__builtin_available)\n  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {\n    object = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:outError];\n  } else\n#endif  // __has_builtin(__builtin_available)\n  {\n    @try {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n      NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];\n#pragma clang diagnostic pop\n      unarchiver.requiresSecureCoding = YES;\n\n      object = [unarchiver decodeObjectOfClasses:classes forKey:NSKeyedArchiveRootObjectKey];\n    } @catch (NSException *exception) {\n      if (outError) {\n        *outError = [self archivingErrorWithException:exception];\n      }\n    }\n\n    if (object == nil && outError && *outError == nil) {\n      NSString *failureReason = @\"NSKeyedUnarchiver failed to unarchive data.\";\n      *outError = [NSError errorWithDomain:kGULSecureCodingError\n                                      code:-1\n                                  userInfo:@{NSLocalizedFailureReasonErrorKey : failureReason}];\n    }\n  }\n\n  return object;\n}\n\n+ (nullable id)unarchivedObjectOfClass:(Class)class\n                              fromData:(NSData *)data\n                                 error:(NSError **)outError {\n  return [self unarchivedObjectOfClasses:[NSSet setWithObject:class] fromData:data error:outError];\n}\n\n+ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError {\n  NSData *archiveData;\n#if __has_builtin(__builtin_available)\n  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {\n    archiveData = [NSKeyedArchiver archivedDataWithRootObject:object\n                                        requiringSecureCoding:YES\n                                                        error:outError];\n  } else\n#endif  // __has_builtin(__builtin_available)\n  {\n    @try {\n      NSMutableData *data = [NSMutableData data];\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n      NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];\n#pragma clang diagnostic pop\n      archiver.requiresSecureCoding = YES;\n\n      [archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];\n      [archiver finishEncoding];\n\n      archiveData = [data copy];\n    } @catch (NSException *exception) {\n      if (outError) {\n        *outError = [self archivingErrorWithException:exception];\n      }\n    }\n  }\n\n  return archiveData;\n}\n\n+ (NSError *)archivingErrorWithException:(NSException *)exception {\n  NSString *failureReason = [NSString\n      stringWithFormat:@\"NSKeyedArchiver exception with name: %@, reason: %@, userInfo: %@\",\n                       exception.name, exception.reason, exception.userInfo];\n  NSDictionary *errorUserInfo = @{NSLocalizedFailureReasonErrorKey : failureReason};\n\n  return [NSError errorWithDomain:kGULSecureCodingError code:-1 userInfo:errorUserInfo];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface GULAppEnvironmentUtil : NSObject\n\n/// Indicates whether the app is from Apple Store or not. Returns NO if the app is on simulator,\n/// development environment or sideloaded.\n+ (BOOL)isFromAppStore;\n\n/// Indicates whether the app is a Testflight app. Returns YES if the app has sandbox receipt.\n/// Returns NO otherwise.\n+ (BOOL)isAppStoreReceiptSandbox;\n\n/// Indicates whether the app is on simulator or not at runtime depending on the device\n/// architecture.\n+ (BOOL)isSimulator;\n\n/// The current device model. Returns an empty string if device model cannot be retrieved.\n+ (nullable NSString *)deviceModel;\n\n/// The current operating system version. Returns an empty string if the system version cannot be\n/// retrieved.\n+ (NSString *)systemVersion;\n\n/// Indicates whether it is running inside an extension or an app.\n+ (BOOL)isAppExtension;\n\n/// @return Returns @YES when is run on iOS version greater or equal to 7.0\n+ (BOOL)isIOS7OrHigher DEPRECATED_MSG_ATTRIBUTE(\n    \"Always `YES` because only iOS 8 and higher supported. The method will be removed.\");\n\n/// @return YES if Swift runtime detected in the app.\n+ (BOOL)hasSwiftRuntime;\n\n/// @return An Apple platform. Possible values \"ios\", \"tvos\", \"macos\", \"watchos\", \"maccatalyst\".\n+ (NSString *)applePlatform;\n\n/// @return The way the library was added to the app, e.g. \"swiftpm\", \"cocoapods\", etc.\n+ (NSString *)deploymentType;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * Describes an object that can store and fetch heartbeat dates for given tags.\n */\n@protocol GULHeartbeatDateStorable <NSObject>\n\n/**\n * Reads the date from the specified file for the given tag.\n * @return Returns date if exists, otherwise `nil`.\n */\n- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag;\n\n/**\n * Saves the date for the specified tag in the specified file.\n * @return YES on success, NO otherwise.\n */\n- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULHeartbeatDateStorable.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The name of the directory where the heartbeat data is stored.\nextern NSString *const kGULHeartbeatStorageDirectory;\n\n/// Stores either a date or a dictionary to a specified file.\n@interface GULHeartbeatDateStorage : NSObject <GULHeartbeatDateStorable>\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@property(nonatomic, readonly) NSURL *fileURL;\n\n/**\n * Default initializer.\n * @param fileName The name of the file to store the date information.\n * exist, it will be created if needed.\n */\n- (instancetype)initWithFileName:(NSString *)fileName;\n\n/**\n * Reads the date from the specified file for the given tag.\n * @return Returns date if exists, otherwise `nil`.\n */\n- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag;\n\n/**\n * Saves the date for the specified tag in the specified file.\n * @return YES on success, NO otherwise.\n */\n- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h",
    "content": "/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULHeartbeatDateStorable.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// Stores either a date or a dictionary to a specified file.\n@interface GULHeartbeatDateStorageUserDefaults : NSObject <GULHeartbeatDateStorable>\n\n/**\n * Default initializer. tvOS can only write to the cache directory and\n * there are no guarantees that the directory will persist. User defaults will\n * be retained, so that should be used instead.\n * @param defaults User defaults instance to store the heartbeat information.\n * @param key The key to be used with the user defaults instance.\n */\n- (instancetype)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n * Reads the date from the specified file for the given tag.\n * @return Returns date if exists, otherwise `nil`.\n */\n- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag;\n\n/**\n * Saves the date for the specified tag in the specified file.\n * @return YES on success, NO otherwise.\n */\n- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<ValueType>;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The class provides a convenient abstraction on top of the iOS Keychain API to save data.\n@interface GULKeychainStorage : NSObject\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** Initializes the keychain storage with Keychain Service name.\n *  @param service A Keychain Service name that will be used to store and retrieve objects. See also\n * `kSecAttrService`.\n */\n- (instancetype)initWithService:(NSString *)service;\n\n/**\n * Get an object by key.\n * @param key The key.\n * @param objectClass The expected object class required by `NSSecureCoding`.\n * @param accessGroup The Keychain Access Group.\n *\n * @return Returns a promise. It is resolved with an object stored by key if exists. It is resolved\n * with `nil` when the object not found. It fails on a Keychain error.\n */\n- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key\n                                        objectClass:(Class)objectClass\n                                        accessGroup:(nullable NSString *)accessGroup;\n\n/**\n * Saves the given object by the given key.\n * @param object The object to store.\n * @param key The key to store the object. If there is an existing object by the key, it will be\n * overridden.\n * @param accessGroup The Keychain Access Group.\n *\n * @return Returns which is resolved with `[NSNull null]` on success.\n */\n- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object\n                             forKey:(NSString *)key\n                        accessGroup:(nullable NSString *)accessGroup;\n\n/**\n * Removes the object by the given key.\n * @param key The key to store the object. If there is an existing object by the key, it will be\n * overridden.\n * @param accessGroup The Keychain Access Group.\n *\n * @return Returns which is resolved with `[NSNull null]` on success.\n */\n- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key\n                                 accessGroup:(nullable NSString *)accessGroup;\n\n#if TARGET_OS_OSX\n/// If not `nil`, then only this keychain will be used to save and read data (see\n/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests.\n@property(nonatomic, nullable) SecKeychainRef keychainRef;\n#endif  // TARGET_OSX\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nFOUNDATION_EXPORT NSString *const kGULKeychainUtilsErrorDomain;\n\n/// Helper functions to access Keychain.\n@interface GULKeychainUtils : NSObject\n\n/** Fetches a keychain item data matching to the provided query.\n *  @param query A dictionary with Keychain query parameters. See docs for `SecItemCopyMatching` for\n * details.\n *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be\n * assigned with an error if there is.\n *  @returns Data for the first Keychain Item matching the provided query or `nil` if there is not\n * such an item (`outError` will be `nil` in this case) or an error occurred.\n */\n+ (nullable NSData *)getItemWithQuery:(NSDictionary *)query\n                                error:(NSError *_Nullable *_Nullable)outError;\n\n/** Stores data to a Keychain Item matching to the provided query. An existing Keychain Item\n * matching the query parameters will be updated or a new will be created.\n *  @param item A Keychain Item data to store.\n *  @param query A dictionary with Keychain query parameters. See docs for `SecItemAdd` and\n * `SecItemUpdate` for details.\n *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be\n * assigned with an error if there is.\n *  @returns `YES` when data was successfully stored, `NO` otherwise.\n */\n+ (BOOL)setItem:(NSData *)item\n      withQuery:(NSDictionary *)query\n          error:(NSError *_Nullable *_Nullable)outError;\n\n/** Removes a Keychain Item matching to the provided query.\n *  @param query A dictionary with Keychain query parameters. See docs for `SecItemDelete` for\n * details.\n *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be\n * assigned with an error if there is.\n *  @returns `YES` if the item was removed successfully or doesn't exist, `NO` otherwise.\n */\n+ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h",
    "content": "// Copyright 2019 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The class wraps `NSKeyedArchiver` and `NSKeyedUnarchiver` API to provide a unified secure coding\n *  methods for iOS versions before and after 11.\n */\n@interface GULSecureCoding : NSObject\n\n+ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes\n                                fromData:(NSData *)data\n                                   error:(NSError **)outError;\n\n+ (nullable id)unarchivedObjectOfClass:(Class)class\n                              fromData:(NSData *)data\n                                 error:(NSError **)outError;\n\n+ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The class represents HTTP response received from `NSURLSession`. */\n@interface GULURLSessionDataResponse : NSObject\n\n@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse;\n@property(nonatomic, nullable, readonly) NSData *HTTPBody;\n\n- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(nullable NSData *)body;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n@class FBLPromise<Value>;\n@class GULURLSessionDataResponse;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** Promise based API for `NSURLSession`. */\n@interface NSURLSession (GULPromises)\n\n/** Creates a promise wrapping `-[NSURLSession dataTaskWithRequest:completionHandler:]` method.\n * @param URLRequest The request to create a data task with.\n * @return A promise that is fulfilled when an HTTP response is received (with any response code),\n * or is rejected with the error passed to the task completion.\n */\n- (FBLPromise<GULURLSessionDataResponse *> *)gul_dataTaskPromiseWithRequest:\n    (NSURLRequest *)URLRequest;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h\"\n#import <Security/Security.h>\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h\"\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h\"\n\n@interface GULKeychainStorage ()\n@property(nonatomic, readonly) dispatch_queue_t keychainQueue;\n@property(nonatomic, readonly) dispatch_queue_t inMemoryCacheQueue;\n@property(nonatomic, readonly) NSString *service;\n@property(nonatomic, readonly) NSCache<NSString *, id<NSSecureCoding>> *inMemoryCache;\n@end\n\n@implementation GULKeychainStorage\n\n- (instancetype)initWithService:(NSString *)service {\n  NSCache *cache = [[NSCache alloc] init];\n  // Cache up to 5 installations.\n  cache.countLimit = 5;\n  return [self initWithService:service cache:cache];\n}\n\n- (instancetype)initWithService:(NSString *)service cache:(NSCache *)cache {\n  self = [super init];\n  if (self) {\n    _keychainQueue =\n        dispatch_queue_create(\"com.gul.KeychainStorage.Keychain\", DISPATCH_QUEUE_SERIAL);\n    _inMemoryCacheQueue =\n        dispatch_queue_create(\"com.gul.KeychainStorage.InMemoryCache\", DISPATCH_QUEUE_SERIAL);\n    _service = [service copy];\n    _inMemoryCache = cache;\n  }\n  return self;\n}\n\n#pragma mark - Public\n\n- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key\n                                        objectClass:(Class)objectClass\n                                        accessGroup:(nullable NSString *)accessGroup {\n  return [FBLPromise onQueue:self.inMemoryCacheQueue\n                          do:^id _Nullable {\n                            // Return cached object or fail otherwise.\n                            id object = [self.inMemoryCache objectForKey:key];\n                            return object\n                                       ?: [[NSError alloc]\n                                              initWithDomain:FBLPromiseErrorDomain\n                                                        code:FBLPromiseErrorCodeValidationFailure\n                                                    userInfo:nil];\n                          }]\n      .recover(^id _Nullable(NSError *error) {\n        // Look for the object in the keychain.\n        return [self getObjectFromKeychainForKey:key\n                                     objectClass:objectClass\n                                     accessGroup:accessGroup];\n      });\n}\n\n- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object\n                             forKey:(NSString *)key\n                        accessGroup:(nullable NSString *)accessGroup {\n  return [FBLPromise onQueue:self.inMemoryCacheQueue\n                          do:^id _Nullable {\n                            // Save to the in-memory cache first.\n                            [self.inMemoryCache setObject:object forKey:[key copy]];\n                            return [NSNull null];\n                          }]\n      .thenOn(self.keychainQueue, ^id(id result) {\n        // Then store the object to the keychain.\n        NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];\n        NSError *error;\n        NSData *encodedObject = [GULSecureCoding archivedDataWithRootObject:object error:&error];\n        if (!encodedObject) {\n          return error;\n        }\n\n        if (![GULKeychainUtils setItem:encodedObject withQuery:query error:&error]) {\n          return error;\n        }\n\n        return [NSNull null];\n      });\n}\n\n- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key\n                                 accessGroup:(nullable NSString *)accessGroup {\n  return [FBLPromise onQueue:self.inMemoryCacheQueue\n                          do:^id _Nullable {\n                            [self.inMemoryCache removeObjectForKey:key];\n                            return nil;\n                          }]\n      .thenOn(self.keychainQueue, ^id(id result) {\n        NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];\n\n        NSError *error;\n        if (![GULKeychainUtils removeItemWithQuery:query error:&error]) {\n          return error;\n        }\n\n        return [NSNull null];\n      });\n}\n\n#pragma mark - Private\n\n- (FBLPromise<id<NSSecureCoding>> *)getObjectFromKeychainForKey:(NSString *)key\n                                                    objectClass:(Class)objectClass\n                                                    accessGroup:(nullable NSString *)accessGroup {\n  // Look for the object in the keychain.\n  return [FBLPromise\n             onQueue:self.keychainQueue\n                  do:^id {\n                    NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];\n                    NSError *error;\n                    NSData *encodedObject = [GULKeychainUtils getItemWithQuery:query error:&error];\n\n                    if (error) {\n                      return error;\n                    }\n                    if (!encodedObject) {\n                      return nil;\n                    }\n                    id object = [GULSecureCoding unarchivedObjectOfClass:objectClass\n                                                                fromData:encodedObject\n                                                                   error:&error];\n                    if (error) {\n                      return error;\n                    }\n\n                    return object;\n                  }]\n      .thenOn(self.inMemoryCacheQueue,\n              ^id<NSSecureCoding> _Nullable(id<NSSecureCoding> _Nullable object) {\n                // Save object to the in-memory cache if exists and return the object.\n                if (object) {\n                  [self.inMemoryCache setObject:object forKey:[key copy]];\n                }\n                return object;\n              });\n}\n\n- (void)resetInMemoryCache {\n  [self.inMemoryCache removeAllObjects];\n}\n\n#pragma mark - Keychain\n\n- (NSMutableDictionary<NSString *, id> *)keychainQueryWithKey:(NSString *)key\n                                                  accessGroup:(nullable NSString *)accessGroup {\n  NSMutableDictionary<NSString *, id> *query = [NSMutableDictionary dictionary];\n\n  query[(__bridge NSString *)kSecClass] = (__bridge NSString *)kSecClassGenericPassword;\n  query[(__bridge NSString *)kSecAttrService] = self.service;\n  query[(__bridge NSString *)kSecAttrAccount] = key;\n\n  if (accessGroup) {\n    query[(__bridge NSString *)kSecAttrAccessGroup] = accessGroup;\n  }\n\n#if TARGET_OS_OSX\n  if (self.keychainRef) {\n    query[(__bridge NSString *)kSecUseKeychain] = (__bridge id)(self.keychainRef);\n    query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ];\n  }\n#endif  // TARGET_OSX\n\n  return query;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m",
    "content": "/*\n * Copyright 2019 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h\"\n\nNSString *const kGULKeychainUtilsErrorDomain = @\"com.gul.keychain.ErrorDomain\";\n\n@implementation GULKeychainUtils\n\n+ (nullable NSData *)getItemWithQuery:(NSDictionary *)query\n                                error:(NSError *_Nullable *_Nullable)outError {\n  NSMutableDictionary *mutableQuery = [query mutableCopy];\n\n  mutableQuery[(__bridge id)kSecReturnData] = @YES;\n  mutableQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;\n\n  CFDataRef result = NULL;\n  OSStatus status =\n      SecItemCopyMatching((__bridge CFDictionaryRef)mutableQuery, (CFTypeRef *)&result);\n\n  if (status == errSecSuccess && result != NULL) {\n    if (outError) {\n      *outError = nil;\n    }\n\n    return (__bridge_transfer NSData *)result;\n  }\n\n  if (status == errSecItemNotFound) {\n    if (outError) {\n      *outError = nil;\n    }\n  } else {\n    if (outError) {\n      *outError = [self keychainErrorWithFunction:@\"SecItemCopyMatching\" status:status];\n    }\n  }\n  return nil;\n}\n\n+ (BOOL)setItem:(NSData *)item\n      withQuery:(NSDictionary *)query\n          error:(NSError *_Nullable *_Nullable)outError {\n  NSData *existingItem = [self getItemWithQuery:query error:outError];\n  if (outError && *outError) {\n    return NO;\n  }\n\n  NSMutableDictionary *mutableQuery = [query mutableCopy];\n  mutableQuery[(__bridge id)kSecAttrAccessible] =\n      (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;\n\n  OSStatus status;\n  if (!existingItem) {\n    mutableQuery[(__bridge id)kSecValueData] = item;\n    status = SecItemAdd((__bridge CFDictionaryRef)mutableQuery, NULL);\n  } else {\n    NSDictionary *attributes = @{(__bridge id)kSecValueData : item};\n    status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes);\n  }\n\n  if (status == noErr) {\n    if (outError) {\n      *outError = nil;\n    }\n    return YES;\n  }\n\n  NSString *function = existingItem ? @\"SecItemUpdate\" : @\"SecItemAdd\";\n  if (outError) {\n    *outError = [self keychainErrorWithFunction:function status:status];\n  }\n  return NO;\n}\n\n+ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError {\n  OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);\n\n  if (status == noErr || status == errSecItemNotFound) {\n    if (outError) {\n      *outError = nil;\n    }\n    return YES;\n  }\n\n  if (outError) {\n    *outError = [self keychainErrorWithFunction:@\"SecItemDelete\" status:status];\n  }\n  return NO;\n}\n\n#pragma mark - Errors\n\n+ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status {\n  NSString *failureReason = [NSString stringWithFormat:@\"%@ (%li)\", keychainFunction, (long)status];\n  NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey : failureReason};\n  return [NSError errorWithDomain:kGULKeychainUtilsErrorDomain code:0 userInfo:userInfo];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h\"\n\n@implementation GULURLSessionDataResponse\n\n- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(NSData *)body {\n  self = [super init];\n  if (self) {\n    _HTTPResponse = response;\n    _HTTPBody = body;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m",
    "content": "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h\"\n\n#if __has_include(<FBLPromises/FBLPromises.h>)\n#import <FBLPromises/FBLPromises.h>\n#else\n#import \"FBLPromises.h\"\n#endif\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h\"\n\n@implementation NSURLSession (GULPromises)\n\n- (FBLPromise<GULURLSessionDataResponse *> *)gul_dataTaskPromiseWithRequest:\n    (NSURLRequest *)URLRequest {\n  return [FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n    [[self dataTaskWithRequest:URLRequest\n             completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response,\n                                 NSError *_Nullable error) {\n               if (error) {\n                 reject(error);\n               } else {\n                 fulfill([[GULURLSessionDataResponse alloc]\n                     initWithResponse:(NSHTTPURLResponse *)response\n                             HTTPBody:data]);\n               }\n             }] resume];\n  }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h\"\n\n#import <Foundation/Foundation.h>\n#import <dlfcn.h>\n#import <mach-o/dyld.h>\n#import <sys/utsname.h>\n#import <objc/runtime.h>\n\n#if TARGET_OS_IOS\n#import <UIKit/UIKit.h>\n#endif\n\n/// The encryption info struct and constants are missing from the iPhoneSimulator SDK, but not from\n/// the iPhoneOS or Mac OS X SDKs. Since one doesn't ever ship a Simulator binary, we'll just\n/// provide the definitions here.\n#if TARGET_OS_SIMULATOR && !defined(LC_ENCRYPTION_INFO)\n#define LC_ENCRYPTION_INFO 0x21\nstruct encryption_info_command {\n  uint32_t cmd;\n  uint32_t cmdsize;\n  uint32_t cryptoff;\n  uint32_t cryptsize;\n  uint32_t cryptid;\n};\n#endif\n\n@implementation GULAppEnvironmentUtil\n\n/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox.\n/// This will affect your data integrity when using Firebase Analytics, as it will disable some\n/// necessary checks.\nstatic NSString *const kFIRAppStoreReceiptURLCheckEnabledKey =\n    @\"FirebaseAppStoreReceiptURLCheckEnabled\";\n\n/// The file name of the sandbox receipt. This is available on iOS >= 8.0\nstatic NSString *const kFIRAIdentitySandboxReceiptFileName = @\"sandboxReceipt\";\n\n/// The following copyright from Landon J. Fuller applies to the isAppEncrypted function.\n///\n/// Copyright (c) 2017 Landon J. Fuller <landon@landonf.org>\n/// All rights reserved.\n///\n/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software\n/// and associated documentation files (the \"Software\"), to deal in the Software without\n/// restriction, including without limitation the rights to use, copy, modify, merge, publish,\n/// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in all copies or\n/// substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n/// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n/// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n///\n/// Comment from <a href=\"http://iphonedevwiki.net/index.php/Crack_prevention\">iPhone Dev Wiki\n/// Crack Prevention</a>:\n/// App Store binaries are signed by both their developer and Apple. This encrypts the binary so\n/// that decryption keys are needed in order to make the binary readable. When iOS executes the\n/// binary, the decryption keys are used to decrypt the binary into a readable state where it is\n/// then loaded into memory and executed. iOS can tell the encryption status of a binary via the\n/// cryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is a non-zero\n/// value then the binary is encrypted.\n///\n/// 'Cracking' works by letting the kernel decrypt the binary then siphoning the decrypted data into\n/// a new binary file, resigning, and repackaging. This will only work on jailbroken devices as\n/// codesignature validation has been removed. Resigning takes place because while the codesignature\n/// doesn't have to be valid thanks to the jailbreak, it does have to be in place unless you have\n/// AppSync or similar to disable codesignature checks.\n///\n/// More information at <a href=\"http://landonf.org/2009/02/index.html\">Landon Fuller's blog</a>\nstatic BOOL IsAppEncrypted() {\n  const struct mach_header *executableHeader = NULL;\n  for (uint32_t i = 0; i < _dyld_image_count(); i++) {\n    const struct mach_header *header = _dyld_get_image_header(i);\n    if (header && header->filetype == MH_EXECUTE) {\n      executableHeader = header;\n      break;\n    }\n  }\n\n  if (!executableHeader) {\n    return NO;\n  }\n\n  BOOL is64bit = (executableHeader->magic == MH_MAGIC_64);\n  uintptr_t cursor = (uintptr_t)executableHeader +\n                     (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));\n  const struct segment_command *segmentCommand = NULL;\n  uint32_t i = 0;\n\n  while (i++ < executableHeader->ncmds) {\n    segmentCommand = (struct segment_command *)cursor;\n\n    if (!segmentCommand) {\n      continue;\n    }\n\n    if ((!is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO) ||\n        (is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO_64)) {\n      if (is64bit) {\n        struct encryption_info_command_64 *cryptCmd =\n            (struct encryption_info_command_64 *)segmentCommand;\n        return cryptCmd && cryptCmd->cryptid != 0;\n      } else {\n        struct encryption_info_command *cryptCmd = (struct encryption_info_command *)segmentCommand;\n        return cryptCmd && cryptCmd->cryptid != 0;\n      }\n    }\n    cursor += segmentCommand->cmdsize;\n  }\n\n  return NO;\n}\n\nstatic BOOL HasSCInfoFolder() {\n#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH\n  NSString *bundlePath = [NSBundle mainBundle].bundlePath;\n  NSString *scInfoPath = [bundlePath stringByAppendingPathComponent:@\"SC_Info\"];\n  return [[NSFileManager defaultManager] fileExistsAtPath:scInfoPath];\n#elif TARGET_OS_OSX\n  return NO;\n#endif\n}\n\nstatic BOOL HasEmbeddedMobileProvision() {\n#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH\n  return [[NSBundle mainBundle] pathForResource:@\"embedded\" ofType:@\"mobileprovision\"].length > 0;\n#elif TARGET_OS_OSX\n  return NO;\n#endif\n}\n\n+ (BOOL)isFromAppStore {\n  static dispatch_once_t isEncryptedOnce;\n  static BOOL isEncrypted = NO;\n\n  dispatch_once(&isEncryptedOnce, ^{\n    isEncrypted = IsAppEncrypted();\n  });\n\n  if ([GULAppEnvironmentUtil isSimulator]) {\n    return NO;\n  }\n\n  // If an app contain the sandboxReceipt file, it means its coming from TestFlight\n  // This must be checked before the SCInfo Folder check below since TestFlight apps may\n  // also have an SCInfo folder.\n  if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox]) {\n    return NO;\n  }\n\n  if (HasSCInfoFolder()) {\n    // When iTunes downloads a .ipa, it also gets a customized .sinf file which is added to the\n    // main SC_Info directory.\n    return YES;\n  }\n\n  // For iOS >= 8.0, iTunesMetadata.plist is moved outside of the sandbox. Any attempt to read\n  // the iTunesMetadata.plist outside of the sandbox will be rejected by Apple.\n  // If the app does not contain the embedded.mobileprovision which is stripped out by Apple when\n  // the app is submitted to store, then it is highly likely that it is from Apple Store.\n  return isEncrypted && !HasEmbeddedMobileProvision();\n}\n\n+ (BOOL)isAppStoreReceiptSandbox {\n  // Since checking the App Store's receipt URL can be memory intensive, check the option in the\n  // Info.plist if developers opted out of this check.\n  id enableSandboxCheck =\n      [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreReceiptURLCheckEnabledKey];\n  if (enableSandboxCheck && [enableSandboxCheck isKindOfClass:[NSNumber class]] &&\n      ![enableSandboxCheck boolValue]) {\n    return NO;\n  }\n\n  NSURL *appStoreReceiptURL = [NSBundle mainBundle].appStoreReceiptURL;\n  NSString *appStoreReceiptFileName = appStoreReceiptURL.lastPathComponent;\n  return [appStoreReceiptFileName isEqualToString:kFIRAIdentitySandboxReceiptFileName];\n}\n\n+ (BOOL)isSimulator {\n#if TARGET_OS_SIMULATOR\n  return YES;\n#elif TARGET_OS_MACCATALYST\n  return NO;\n#elif TARGET_OS_IOS || TARGET_OS_TV\n  NSString *platform = [GULAppEnvironmentUtil deviceModel];\n  return [platform isEqual:@\"x86_64\"] || [platform isEqual:@\"i386\"];\n#elif TARGET_OS_OSX\n  return NO;\n#endif\n  return NO;\n}\n\n+ (NSString *)deviceModel {\n  static dispatch_once_t once;\n  static NSString *deviceModel;\n\n  dispatch_once(&once, ^{\n    struct utsname systemInfo;\n    if (uname(&systemInfo) == 0) {\n      deviceModel = [NSString stringWithUTF8String:systemInfo.machine];\n    }\n  });\n  return deviceModel;\n}\n\n+ (NSString *)systemVersion {\n#if TARGET_OS_IOS\n  return [UIDevice currentDevice].systemVersion;\n#elif TARGET_OS_OSX || TARGET_OS_TV || TARGET_OS_WATCH\n  // Assemble the systemVersion, excluding the patch version if it's 0.\n  NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion;\n  NSMutableString *versionString = [[NSMutableString alloc]\n      initWithFormat:@\"%ld.%ld\", (long)osVersion.majorVersion, (long)osVersion.minorVersion];\n  if (osVersion.patchVersion != 0) {\n    [versionString appendFormat:@\".%ld\", (long)osVersion.patchVersion];\n  }\n  return versionString;\n#endif\n}\n\n+ (BOOL)isAppExtension {\n#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH\n  // Documented by <a href=\"https://goo.gl/RRB2Up\">Apple</a>\n  BOOL appExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@\".appex\"];\n  return appExtension;\n#elif TARGET_OS_OSX\n  return NO;\n#endif\n}\n\n+ (BOOL)isIOS7OrHigher {\n  return YES;\n}\n\n+ (BOOL)hasSwiftRuntime {\n  // The class\n  // [Swift._SwiftObject](https://github.com/apple/swift/blob/5eac3e2818eb340b11232aff83edfbd1c307fa03/stdlib/public/runtime/SwiftObject.h#L35)\n  // is a part of Swift runtime, so it should be present if Swift runtime is available.\n\n  BOOL hasSwiftRuntime =\n      objc_lookUpClass(\"Swift._SwiftObject\") != nil ||\n      // Swift object class name before\n      // https://github.com/apple/swift/commit/9637b4a6e11ddca72f5f6dbe528efc7c92f14d01\n      objc_getClass(\"_TtCs12_SwiftObject\") != nil;\n\n  return hasSwiftRuntime;\n}\n\n+ (NSString *)applePlatform {\n  NSString *applePlatform = @\"unknown\";\n\n  // When a Catalyst app is run on macOS then both `TARGET_OS_MACCATALYST` and `TARGET_OS_IOS` are\n  // `true`, which means the condition list is order-sensitive.\n#if TARGET_OS_MACCATALYST\n  applePlatform = @\"maccatalyst\";\n#elif TARGET_OS_IOS\n#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000\n  if (@available(iOS 14.0, *)) {\n    // Early iOS 14 betas do not include isiOSAppOnMac (#6969)\n    applePlatform = ([[NSProcessInfo processInfo] respondsToSelector:@selector(isiOSAppOnMac)] &&\n                      [NSProcessInfo processInfo].isiOSAppOnMac) ? @\"ios_on_mac\" : @\"ios\";\n  } else {\n    applePlatform = @\"ios\";\n  }\n#else // defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000\n  applePlatform = @\"ios\";\n#endif // defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000\n\n#elif TARGET_OS_TV\n  applePlatform = @\"tvos\";\n#elif TARGET_OS_OSX\n  applePlatform = @\"macos\";\n#elif TARGET_OS_WATCH\n  applePlatform = @\"watchos\";\n#endif // TARGET_OS_MACCATALYST\n\n  return applePlatform;\n}\n\n+ (NSString *)deploymentType {\n#if SWIFT_PACKAGE\n  NSString *deploymentType = @\"swiftpm\";\n#elif FIREBASE_BUILD_CARTHAGE\n  NSString *deploymentType = @\"carthage\";\n#elif FIREBASE_BUILD_ZIP_FILE\n  NSString *deploymentType = @\"zip\";\n#else\n  NSString *deploymentType = @\"cocoapods\";\n#endif\n\n  return deploymentType;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m",
    "content": "// Copyright 2018 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\n#include <asl.h>\n\n#import \"GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h\"\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h\"\n\n/// ASL client facility name used by GULLogger.\nconst char *kGULLoggerASLClientFacilityName = \"com.google.utilities.logger\";\n\nstatic dispatch_once_t sGULLoggerOnceToken;\n\nstatic aslclient sGULLoggerClient;\n\nstatic dispatch_queue_t sGULClientQueue;\n\nstatic BOOL sGULLoggerDebugMode;\n\nstatic GULLoggerLevel sGULLoggerMaximumLevel;\n\n// Allow clients to register a version to include in the log.\nstatic NSString *sVersion = @\"\";\n\nstatic GULLoggerService kGULLoggerLogger = @\"[GULLogger]\";\n\n#ifdef DEBUG\n/// The regex pattern for the message code.\nstatic NSString *const kMessageCodePattern = @\"^I-[A-Z]{3}[0-9]{6}$\";\nstatic NSRegularExpression *sMessageCodeRegex;\n#endif\n\nvoid GULLoggerInitializeASL(void) {\n  dispatch_once(&sGULLoggerOnceToken, ^{\n    NSInteger majorOSVersion = [[GULAppEnvironmentUtil systemVersion] integerValue];\n    uint32_t aslOptions = ASL_OPT_STDERR;\n#if TARGET_OS_SIMULATOR\n    // The iOS 11 simulator doesn't need the ASL_OPT_STDERR flag.\n    if (majorOSVersion >= 11) {\n      aslOptions = 0;\n    }\n#else\n    // Devices running iOS 10 or higher don't need the ASL_OPT_STDERR flag.\n    if (majorOSVersion >= 10) {\n      aslOptions = 0;\n    }\n#endif  // TARGET_OS_SIMULATOR\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"  // asl is deprecated\n    // Initialize the ASL client handle.\n    sGULLoggerClient = asl_open(NULL, kGULLoggerASLClientFacilityName, aslOptions);\n    sGULLoggerMaximumLevel = GULLoggerLevelNotice;\n\n    // Set the filter used by system/device log. Initialize in default mode.\n    asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE));\n\n    sGULClientQueue = dispatch_queue_create(\"GULLoggingClientQueue\", DISPATCH_QUEUE_SERIAL);\n    dispatch_set_target_queue(sGULClientQueue,\n                              dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));\n#ifdef DEBUG\n    sMessageCodeRegex = [NSRegularExpression regularExpressionWithPattern:kMessageCodePattern\n                                                                  options:0\n                                                                    error:NULL];\n#endif\n  });\n}\n\nvoid GULLoggerEnableSTDERR(void) {\n  asl_add_log_file(sGULLoggerClient, STDERR_FILENO);\n}\n\nvoid GULLoggerForceDebug(void) {\n  // We should enable debug mode if we're not running from App Store.\n  if (![GULAppEnvironmentUtil isFromAppStore]) {\n    sGULLoggerDebugMode = YES;\n    GULSetLoggerLevel(GULLoggerLevelDebug);\n  }\n}\n\n__attribute__((no_sanitize(\"thread\"))) void GULSetLoggerLevel(GULLoggerLevel loggerLevel) {\n  if (loggerLevel < GULLoggerLevelMin || loggerLevel > GULLoggerLevelMax) {\n    GULLogError(kGULLoggerLogger, NO, @\"I-COR000023\", @\"Invalid logger level, %ld\",\n                (long)loggerLevel);\n    return;\n  }\n  GULLoggerInitializeASL();\n  // We should not raise the logger level if we are running from App Store.\n  if (loggerLevel >= GULLoggerLevelNotice && [GULAppEnvironmentUtil isFromAppStore]) {\n    return;\n  }\n\n  sGULLoggerMaximumLevel = loggerLevel;\n  dispatch_async(sGULClientQueue, ^{\n    asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(loggerLevel));\n  });\n}\n\n/**\n * Check if the level is high enough to be loggable.\n */\n__attribute__((no_sanitize(\"thread\"))) BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel) {\n  GULLoggerInitializeASL();\n  if (sGULLoggerDebugMode) {\n    return YES;\n  }\n  return (BOOL)(loggerLevel <= sGULLoggerMaximumLevel);\n}\n\n#ifdef DEBUG\nvoid GULResetLogger(void) {\n  sGULLoggerOnceToken = 0;\n  sGULLoggerDebugMode = NO;\n}\n\naslclient getGULLoggerClient(void) {\n  return sGULLoggerClient;\n}\n\ndispatch_queue_t getGULClientQueue(void) {\n  return sGULClientQueue;\n}\n\nBOOL getGULLoggerDebugMode(void) {\n  return sGULLoggerDebugMode;\n}\n#endif\n\nvoid GULLoggerRegisterVersion(NSString *version) {\n  sVersion = version;\n}\n\nvoid GULLogBasic(GULLoggerLevel level,\n                 GULLoggerService service,\n                 BOOL forceLog,\n                 NSString *messageCode,\n                 NSString *message,\n                 va_list args_ptr) {\n  GULLoggerInitializeASL();\n  if (!(level <= sGULLoggerMaximumLevel || sGULLoggerDebugMode || forceLog)) {\n    return;\n  }\n\n#ifdef DEBUG\n  NSCAssert(messageCode.length == 11, @\"Incorrect message code length.\");\n  NSRange messageCodeRange = NSMakeRange(0, messageCode.length);\n  NSUInteger numberOfMatches = [sMessageCodeRegex numberOfMatchesInString:messageCode\n                                                                  options:0\n                                                                    range:messageCodeRange];\n  NSCAssert(numberOfMatches == 1, @\"Incorrect message code format.\");\n#endif\n  NSString *logMsg;\n  if (args_ptr == NULL) {\n    logMsg = message;\n  } else {\n    logMsg = [[NSString alloc] initWithFormat:message arguments:args_ptr];\n  }\n  logMsg = [NSString stringWithFormat:@\"%@ - %@[%@] %@\", sVersion, service, messageCode, logMsg];\n  dispatch_async(sGULClientQueue, ^{\n    asl_log(sGULLoggerClient, NULL, (int)level, \"%s\", logMsg.UTF8String);\n  });\n}\n#pragma clang diagnostic pop\n\n/**\n * Generates the logging functions using macros.\n *\n * Calling GULLogError({service}, @\"I-XYZ000001\", @\"Configure %@ failed.\", @\"blah\") shows:\n * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Error> [{service}][I-XYZ000001] Configure blah failed.\n * Calling GULLogDebug({service}, @\"I-XYZ000001\", @\"Configure succeed.\") shows:\n * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [{service}][I-XYZ000001] Configure succeed.\n */\n#define GUL_LOGGING_FUNCTION(level)                                                     \\\n  void GULLog##level(GULLoggerService service, BOOL force, NSString *messageCode,       \\\n                     NSString *message, ...) {                                          \\\n    va_list args_ptr;                                                                   \\\n    va_start(args_ptr, message);                                                        \\\n    GULLogBasic(GULLoggerLevel##level, service, force, messageCode, message, args_ptr); \\\n    va_end(args_ptr);                                                                   \\\n  }\n\nGUL_LOGGING_FUNCTION(Error)\nGUL_LOGGING_FUNCTION(Warning)\nGUL_LOGGING_FUNCTION(Notice)\nGUL_LOGGING_FUNCTION(Info)\nGUL_LOGGING_FUNCTION(Debug)\n\n#undef GUL_MAKE_LOGGER\n\n#pragma mark - GULLoggerWrapper\n\n@implementation GULLoggerWrapper\n\n+ (void)logWithLevel:(GULLoggerLevel)level\n         withService:(GULLoggerService)service\n            withCode:(NSString *)messageCode\n         withMessage:(NSString *)message\n            withArgs:(va_list)args {\n  GULLogBasic(level, service, NO, messageCode, message, args);\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULLoggerLevel.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * The services used in the logger.\n */\ntypedef NSString *const GULLoggerService;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\n/**\n * Initialize GULLogger.\n */\nextern void GULLoggerInitializeASL(void);\n\n/**\n * Override log level to Debug.\n */\nvoid GULLoggerForceDebug(void);\n\n/**\n * Turn on logging to STDERR.\n */\nextern void GULLoggerEnableSTDERR(void);\n\n/**\n * Changes the default logging level of GULLoggerLevelNotice to a user-specified level.\n * The default level cannot be set above GULLoggerLevelNotice if the app is running from App Store.\n * (required) log level (one of the GULLoggerLevel enum values).\n */\nextern void GULSetLoggerLevel(GULLoggerLevel loggerLevel);\n\n/**\n * Checks if the specified logger level is loggable given the current settings.\n * (required) log level (one of the GULLoggerLevel enum values).\n */\nextern BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel);\n\n/**\n * Register version to include in logs.\n * (required) version\n */\nextern void GULLoggerRegisterVersion(NSString *version);\n\n/**\n * Logs a message to the Xcode console and the device log. If running from AppStore, will\n * not log any messages with a level higher than GULLoggerLevelNotice to avoid log spamming.\n * (required) log level (one of the GULLoggerLevel enum values).\n * (required) service name of type GULLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\nextern void GULLogBasic(GULLoggerLevel level,\n                        GULLoggerService service,\n                        BOOL forceLog,\n                        NSString *messageCode,\n                        NSString *message,\n// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable\n// See: http://stackoverflow.com/q/29095469\n#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX\n                        va_list args_ptr\n#else\n                        va_list _Nullable args_ptr\n#endif\n);\n\n/**\n * The following functions accept the following parameters in order:\n * (required) service name of type GULLoggerService.\n * (required) message code starting from \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n *            See go/firebase-log-proposal for details.\n * (required) message string which can be a format string.\n * (optional) the list of arguments to substitute into the format string.\n * Example usage:\n * GULLogError(kGULLoggerCore, @\"I-COR000001\", @\"Configuration of %@ failed.\", app.name);\n */\nextern void GULLogError(GULLoggerService service,\n                        BOOL force,\n                        NSString *messageCode,\n                        NSString *message,\n                        ...) NS_FORMAT_FUNCTION(4, 5);\nextern void GULLogWarning(GULLoggerService service,\n                          BOOL force,\n                          NSString *messageCode,\n                          NSString *message,\n                          ...) NS_FORMAT_FUNCTION(4, 5);\nextern void GULLogNotice(GULLoggerService service,\n                         BOOL force,\n                         NSString *messageCode,\n                         NSString *message,\n                         ...) NS_FORMAT_FUNCTION(4, 5);\nextern void GULLogInfo(GULLoggerService service,\n                       BOOL force,\n                       NSString *messageCode,\n                       NSString *message,\n                       ...) NS_FORMAT_FUNCTION(4, 5);\nextern void GULLogDebug(GULLoggerService service,\n                        BOOL force,\n                        NSString *messageCode,\n                        NSString *message,\n                        ...) NS_FORMAT_FUNCTION(4, 5);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif  // __cplusplus\n\n@interface GULLoggerWrapper : NSObject\n\n/**\n * Objective-C wrapper for GULLogBasic to allow weak linking to GULLogger\n * (required) log level (one of the GULLoggerLevel enum values).\n * (required) service name of type GULLoggerService.\n * (required) message code starting with \"I-\" which means iOS, followed by a capitalized\n *            three-character service identifier and a six digit integer message ID that is unique\n *            within the service.\n *            An example of the message code is @\"I-COR000001\".\n * (required) message string which can be a format string.\n * (optional) variable arguments list obtained from calling va_start, used when message is a format\n *            string.\n */\n\n+ (void)logWithLevel:(GULLoggerLevel)level\n         withService:(GULLoggerService)service\n            withCode:(NSString *)messageCode\n         withMessage:(NSString *)message\n            withArgs:(va_list)args;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h",
    "content": "/*\n * Copyright 2018 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * The log levels used by internal logging.\n */\ntypedef NS_ENUM(NSInteger, GULLoggerLevel) {\n  /** Error level, matches ASL_LEVEL_ERR. */\n  GULLoggerLevelError = 3,\n  /** Warning level, matches ASL_LEVEL_WARNING. */\n  GULLoggerLevelWarning = 4,\n  /** Notice level, matches ASL_LEVEL_NOTICE. */\n  GULLoggerLevelNotice = 5,\n  /** Info level, matches ASL_LEVEL_INFO. */\n  GULLoggerLevelInfo = 6,\n  /** Debug level, matches ASL_LEVEL_DEBUG. */\n  GULLoggerLevelDebug = 7,\n  /** Minimum log level. */\n  GULLoggerLevelMin = GULLoggerLevelError,\n  /** Maximum log level. */\n  GULLoggerLevelMax = GULLoggerLevelDebug\n} NS_SWIFT_NAME(GoogleLoggerLevel);\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h\"\n\n#import <objc/runtime.h>\n\n#ifdef DEBUG\n#import \"GoogleUtilities/Common/GULLoggerCodes.h\"\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\nstatic GULLoggerService kGULLoggerSwizzler = @\"[GoogleUtilities/MethodSwizzler]\";\n#endif\n\ndispatch_queue_t GetGULSwizzlingQueue(void) {\n  static dispatch_queue_t queue;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    queue = dispatch_queue_create(\"com.google.GULSwizzler\", DISPATCH_QUEUE_SERIAL);\n  });\n  return queue;\n}\n\n@implementation GULSwizzler\n\n+ (void)swizzleClass:(Class)aClass\n            selector:(SEL)selector\n     isClassSelector:(BOOL)isClassSelector\n           withBlock:(nullable id)block {\n  dispatch_sync(GetGULSwizzlingQueue(), ^{\n    NSAssert(selector, @\"The selector cannot be NULL\");\n    NSAssert(aClass, @\"The class cannot be Nil\");\n    Class resolvedClass = aClass;\n    Method method = nil;\n    if (isClassSelector) {\n      method = class_getClassMethod(aClass, selector);\n      resolvedClass = object_getClass(aClass);\n    } else {\n      method = class_getInstanceMethod(aClass, selector);\n    }\n    NSAssert(method, @\"You're attempting to swizzle a method that doesn't exist. (%@, %@)\",\n             NSStringFromClass(resolvedClass), NSStringFromSelector(selector));\n    IMP newImp = imp_implementationWithBlock(block);\n#ifdef DEBUG\n    IMP currentImp = class_getMethodImplementation(resolvedClass, selector);\n    Class class = NSClassFromString(@\"GULSwizzlingCache\");\n    if (class) {\n      SEL cacheSelector = NSSelectorFromString(@\"cacheCurrentIMP:forNewIMP:forClass:withSelector:\");\n      NSMethodSignature *methodSignature = [class methodSignatureForSelector:cacheSelector];\n      if (methodSignature != nil) {\n        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];\n        [inv setSelector:cacheSelector];\n        [inv setTarget:class];\n        [inv setArgument:&(currentImp) atIndex:2];\n        [inv setArgument:&(newImp) atIndex:3];\n        [inv setArgument:&(resolvedClass) atIndex:4];\n        [inv setArgument:(void *_Nonnull)&(selector) atIndex:5];\n        [inv invoke];\n      }\n    }\n#endif\n\n    const char *typeEncoding = method_getTypeEncoding(method);\n    __unused IMP originalImpOfClass =\n        class_replaceMethod(resolvedClass, selector, newImp, typeEncoding);\n\n#ifdef DEBUG\n    // If !originalImpOfClass, then the IMP came from a superclass.\n    if (originalImpOfClass) {\n      SEL selector = NSSelectorFromString(@\"originalIMPOfCurrentIMP:\");\n      NSMethodSignature *methodSignature = [class methodSignatureForSelector:selector];\n      if (methodSignature != nil) {\n        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];\n        [inv setSelector:selector];\n        [inv setTarget:class];\n        [inv setArgument:&(currentImp) atIndex:2];\n        [inv invoke];\n        IMP testOriginal;\n        [inv getReturnValue:&testOriginal];\n        if (originalImpOfClass != testOriginal) {\n          GULLogWarning(kGULLoggerSwizzler, NO,\n                        [NSString stringWithFormat:@\"I-SWZ%06ld\",\n                                                   (long)kGULSwizzlerMessageCodeMethodSwizzling000],\n                        @\"Swizzling class: %@ SEL:%@ after it has been previously been swizzled.\",\n                        NSStringFromClass(resolvedClass), NSStringFromSelector(selector));\n        }\n      }\n    }\n#endif\n  });\n}\n\n+ (nullable IMP)currentImplementationForClass:(Class)aClass\n                                     selector:(SEL)selector\n                              isClassSelector:(BOOL)isClassSelector {\n  NSAssert(selector, @\"The selector cannot be NULL\");\n  NSAssert(aClass, @\"The class cannot be Nil\");\n  if (selector == NULL || aClass == nil) {\n    return nil;\n  }\n  __block IMP currentIMP = nil;\n  dispatch_sync(GetGULSwizzlingQueue(), ^{\n    Method method = nil;\n    if (isClassSelector) {\n      method = class_getClassMethod(aClass, selector);\n    } else {\n      method = class_getInstanceMethod(aClass, selector);\n    }\n    NSAssert(method, @\"The Method for this class/selector combo doesn't exist (%@, %@).\",\n             NSStringFromClass(aClass), NSStringFromSelector(selector));\n    if (method == nil) {\n      return;\n    }\n    currentIMP = method_getImplementation(method);\n    NSAssert(currentIMP, @\"The IMP for this class/selector combo doesn't exist (%@, %@).\",\n             NSStringFromClass(aClass), NSStringFromSelector(selector));\n  });\n  return currentIMP;\n}\n\n+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector {\n  Method method = isClassSelector ? class_getClassMethod(aClass, selector)\n                                  : class_getInstanceMethod(aClass, selector);\n  return method != nil;\n}\n\n+ (NSArray<id> *)ivarObjectsForObject:(id)object {\n  NSMutableArray *array = [NSMutableArray array];\n  unsigned int count;\n  Ivar *vars = class_copyIvarList([object class], &count);\n  for (NSUInteger i = 0; i < count; i++) {\n    const char *typeEncoding = ivar_getTypeEncoding(vars[i]);\n    // Check to see if the ivar is an object.\n    if (strncmp(typeEncoding, \"@\", 1) == 0) {\n      id ivarObject = object_getIvar(object, vars[i]);\n      [array addObject:ivarObject];\n    }\n  }\n  free(vars);\n  return array;\n}\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * GULOriginalIMPConvenienceMacros.h\n *\n * This header contains convenience macros for invoking the original IMP of a swizzled method.\n */\n\n/**\n *  Invokes original IMP when the original selector takes no arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n */\n#define GUL_INVOKE_ORIGINAL_IMP0(__receivingObject, __swizzledSEL, __returnType, __originalIMP) \\\n  ((__returnType(*)(id, SEL))__originalIMP)(__receivingObject, __swizzledSEL)\n\n/**\n *  Invokes original IMP when the original selector takes 1 argument.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP1(__receivingObject, __swizzledSEL, __returnType, __originalIMP,   \\\n                                 __arg1)                                                          \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1)))__originalIMP)(__receivingObject, __swizzledSEL, \\\n                                                                __arg1)\n\n/**\n *  Invokes original IMP when the original selector takes 2 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP2(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \\\n                                 __arg1, __arg2)                                                \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2)))__originalIMP)(            \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2)\n\n/**\n *  Invokes original IMP when the original selector takes 3 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP3(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \\\n                                 __arg1, __arg2, __arg3)                                         \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2),                             \\\n                    __typeof__(__arg3)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \\\n                                                       __arg2, __arg3)\n\n/**\n *  Invokes original IMP when the original selector takes 4 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP4(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \\\n                                 __arg1, __arg2, __arg3, __arg4)                                 \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \\\n                    __typeof__(__arg4)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \\\n                                                       __arg2, __arg3, __arg4)\n\n/**\n *  Invokes original IMP when the original selector takes 5 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n *  @param __arg5 The fifth argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP5(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \\\n                                 __arg1, __arg2, __arg3, __arg4, __arg5)                        \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \\\n                    __typeof__(__arg4), __typeof__(__arg5)))__originalIMP)(                     \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5)\n\n/**\n *  Invokes original IMP when the original selector takes 6 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n *  @param __arg5 The fifth argument.\n *  @param __arg6 The sixth argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP6(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \\\n                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6)                \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \\\n                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6)))__originalIMP)( \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6)\n\n/**\n *  Invokes original IMP when the original selector takes 7 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n *  @param __arg5 The fifth argument.\n *  @param __arg6 The sixth argument.\n *  @param __arg7 The seventh argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP7(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \\\n                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7)        \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \\\n                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                 \\\n                    __typeof__(__arg7)))__originalIMP)(                                         \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7)\n\n/**\n *  Invokes original IMP when the original selector takes 8 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n *  @param __arg5 The fifth argument.\n *  @param __arg6 The sixth argument.\n *  @param __arg7 The seventh argument.\n *  @param __arg8 The eighth argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP8(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \\\n                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8) \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \\\n                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                  \\\n                    __typeof__(__arg7), __typeof__(__arg8)))__originalIMP)(                      \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7,  \\\n      __arg8)\n\n/**\n *  Invokes original IMP when the original selector takes 9 arguments.\n *\n *  @param __receivingObject The object on which the IMP is invoked.\n *  @param __swizzledSEL The selector used for swizzling.\n *  @param __returnType  The return type of the original implementation.\n *  @param __originalIMP The original IMP.\n *  @param __arg1 The first argument.\n *  @param __arg2 The second argument.\n *  @param __arg3 The third argument.\n *  @param __arg4 The fourth argument.\n *  @param __arg5 The fifth argument.\n *  @param __arg6 The sixth argument.\n *  @param __arg7 The seventh argument.\n *  @param __arg8 The eighth argument.\n *  @param __arg9 The ninth argument.\n */\n#define GUL_INVOKE_ORIGINAL_IMP9(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \\\n                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8, \\\n                                 __arg9)                                                         \\\n  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \\\n                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                  \\\n                    __typeof__(__arg7), __typeof__(__arg8), __typeof__(__arg9)))__originalIMP)(  \\\n      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7,  \\\n      __arg8, __arg9)\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** This class handles the runtime manipulation necessary to instrument selectors. It stores the\n *  classes and selectors that have been swizzled, and runs all operations on its own queue.\n */\n@interface GULSwizzler : NSObject\n\n/** Manipulates the Objective-C runtime to replace the original IMP with the supplied block.\n *\n *  @param aClass The class to swizzle.\n *  @param selector The selector of the class to swizzle.\n *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.\n *  @param block The block that replaces the original IMP.\n */\n+ (void)swizzleClass:(Class)aClass\n            selector:(SEL)selector\n     isClassSelector:(BOOL)isClassSelector\n           withBlock:(nullable id)block;\n\n/** Returns the current IMP for the given class and selector.\n *\n *  @param aClass The class to use.\n *  @param selector The selector to find the implementation of.\n *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.\n *  @return The implementation of the selector in the runtime.\n */\n+ (nullable IMP)currentImplementationForClass:(Class)aClass\n                                     selector:(SEL)selector\n                              isClassSelector:(BOOL)isClassSelector;\n\n/** Checks the runtime to see if a selector exists on a class. If a property is declared as\n *  @dynamic, we have a reverse swizzling situation, where the implementation of a method exists\n *  only in concrete subclasses, and NOT in the superclass. We can detect that situation using\n *  this helper method. Similarly, we can detect situations where a class doesn't implement a\n *  protocol method.\n *\n *  @param selector The selector to check for.\n *  @param aClass The class to check.\n *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.\n *  @return YES if the method was found in this selector/class combination, NO otherwise.\n */\n+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector;\n\n/** Returns a list of all Objective-C (and not primitive) ivars contained by the given object.\n *\n *  @param object The object whose ivars will be iterated.\n *  @return The list of ivar objects.\n */\n+ (NSArray<id> *)ivarObjectsForObject:(id)object;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m",
    "content": "// Copyright 2018 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h\"\n\n#import <zlib.h>\n\n#define kChunkSize 1024\n#define Z_DEFAULT_COMPRESSION (-1)\n\nNSString *const GULNSDataZlibErrorDomain = @\"com.google.GULNSDataZlibErrorDomain\";\nNSString *const GULNSDataZlibErrorKey = @\"GULNSDataZlibErrorKey\";\nNSString *const GULNSDataZlibRemainingBytesKey = @\"GULNSDataZlibRemainingBytesKey\";\n\n@implementation NSData (GULGzip)\n\n+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error {\n  const void *bytes = [data bytes];\n  NSUInteger length = [data length];\n  if (!bytes || !length) {\n    return nil;\n  }\n\n#if defined(__LP64__) && __LP64__\n  // Don't support > 32bit length for 64 bit, see note in header.\n  if (length > UINT_MAX) {\n    return nil;\n  }\n#endif\n\n  z_stream strm;\n  bzero(&strm, sizeof(z_stream));\n\n  // Setup the input.\n  strm.avail_in = (unsigned int)length;\n  strm.next_in = (unsigned char *)bytes;\n\n  int windowBits = 15;  // 15 to enable any window size\n  windowBits += 32;     // and +32 to enable zlib or gzip header detection.\n\n  int retCode;\n  if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) {\n    if (error) {\n      NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]\n                                                           forKey:GULNSDataZlibErrorKey];\n      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                   code:GULNSDataZlibErrorInternal\n                               userInfo:userInfo];\n    }\n    return nil;\n  }\n\n  // Hint the size at 4x the input size.\n  NSMutableData *result = [NSMutableData dataWithCapacity:(length * 4)];\n  unsigned char output[kChunkSize];\n\n  // Loop to collect the data.\n  do {\n    // Update what we're passing in.\n    strm.avail_out = kChunkSize;\n    strm.next_out = output;\n    retCode = inflate(&strm, Z_NO_FLUSH);\n    if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {\n      if (error) {\n        NSMutableDictionary *userInfo =\n            [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]\n                                               forKey:GULNSDataZlibErrorKey];\n        if (strm.msg) {\n          NSString *message = [NSString stringWithUTF8String:strm.msg];\n          if (message) {\n            [userInfo setObject:message forKey:NSLocalizedDescriptionKey];\n          }\n        }\n        *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                     code:GULNSDataZlibErrorInternal\n                                 userInfo:userInfo];\n      }\n      inflateEnd(&strm);\n      return nil;\n    }\n    // Collect what we got.\n    unsigned gotBack = kChunkSize - strm.avail_out;\n    if (gotBack > 0) {\n      [result appendBytes:output length:gotBack];\n    }\n\n  } while (retCode == Z_OK);\n\n  // Make sure there wasn't more data tacked onto the end of a valid compressed stream.\n  if (strm.avail_in != 0) {\n    if (error) {\n      NSDictionary *userInfo =\n          [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in]\n                                      forKey:GULNSDataZlibRemainingBytesKey];\n      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                   code:GULNSDataZlibErrorDataRemaining\n                               userInfo:userInfo];\n    }\n    result = nil;\n  }\n  // The only way out of the loop was by hitting the end of the stream.\n  NSAssert(retCode == Z_STREAM_END,\n           @\"Thought we finished inflate w/o getting a result of stream end, code %d\", retCode);\n\n  // Clean up.\n  inflateEnd(&strm);\n\n  return result;\n}\n\n+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error {\n  const void *bytes = [data bytes];\n  NSUInteger length = [data length];\n\n  int level = Z_DEFAULT_COMPRESSION;\n  if (!bytes || !length) {\n    return nil;\n  }\n\n#if defined(__LP64__) && __LP64__\n  // Don't support > 32bit length for 64 bit, see note in header.\n  if (length > UINT_MAX) {\n    if (error) {\n      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                   code:GULNSDataZlibErrorGreaterThan32BitsToCompress\n                               userInfo:nil];\n    }\n    return nil;\n  }\n#endif\n\n  z_stream strm;\n  bzero(&strm, sizeof(z_stream));\n\n  int memLevel = 8;          // Default.\n  int windowBits = 15 + 16;  // Enable gzip header instead of zlib header.\n\n  int retCode;\n  if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits, memLevel,\n                              Z_DEFAULT_STRATEGY)) != Z_OK) {\n    if (error) {\n      NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]\n                                                           forKey:GULNSDataZlibErrorKey];\n      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                   code:GULNSDataZlibErrorInternal\n                               userInfo:userInfo];\n    }\n    return nil;\n  }\n\n  // Hint the size at 1/4 the input size.\n  NSMutableData *result = [NSMutableData dataWithCapacity:(length / 4)];\n  unsigned char output[kChunkSize];\n\n  // Setup the input.\n  strm.avail_in = (unsigned int)length;\n  strm.next_in = (unsigned char *)bytes;\n\n  // Collect the data.\n  do {\n    // update what we're passing in\n    strm.avail_out = kChunkSize;\n    strm.next_out = output;\n    retCode = deflate(&strm, Z_FINISH);\n    if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {\n      if (error) {\n        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]\n                                                             forKey:GULNSDataZlibErrorKey];\n        *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain\n                                     code:GULNSDataZlibErrorInternal\n                                 userInfo:userInfo];\n      }\n      deflateEnd(&strm);\n      return nil;\n    }\n    // Collect what we got.\n    unsigned gotBack = kChunkSize - strm.avail_out;\n    if (gotBack > 0) {\n      [result appendBytes:output length:gotBack];\n    }\n\n  } while (retCode == Z_OK);\n\n  // If the loop exits, it used all input and the stream ended.\n  NSAssert(strm.avail_in == 0,\n           @\"Should have finished deflating without using all input, %u bytes left\", strm.avail_in);\n  NSAssert(retCode == Z_STREAM_END,\n           @\"thought we finished deflate w/o getting a result of stream end, code %d\", retCode);\n\n  // Clean up.\n  deflateEnd(&strm);\n\n  return result;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h",
    "content": "// Copyright 2018 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\n/// This is a copy of Google Toolbox for Mac library to avoid creating an extra framework.\n\n// NOTE: For 64bit, none of these apis handle input sizes >32bits, they will return nil when given\n// such data. To handle data of that size you really should be streaming it rather then doing it all\n// in memory.\n\n@interface NSData (GULGzip)\n\n/// Returns an data as the result of decompressing the payload of |data|.The data to decompress must\n/// be a gzipped payloads.\n+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error;\n\n/// Returns an compressed data with the result of gzipping the payload of |data|. Uses the default\n/// compression level.\n+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error;\n\nFOUNDATION_EXPORT NSString *const GULNSDataZlibErrorDomain;\nFOUNDATION_EXPORT NSString *const GULNSDataZlibErrorKey;           // NSNumber\nFOUNDATION_EXPORT NSString *const GULNSDataZlibRemainingBytesKey;  // NSNumber\n\ntypedef NS_ENUM(NSInteger, GULNSDataZlibError) {\n  GULNSDataZlibErrorGreaterThan32BitsToCompress = 1024,\n  // An internal zlib error.\n  // GULNSDataZlibErrorKey will contain the error value.\n  // NSLocalizedDescriptionKey may contain an error string from zlib.\n  // Look in zlib.h for list of errors.\n  GULNSDataZlibErrorInternal,\n  // There was left over data in the buffer that was not used.\n  // GULNSDataZlibRemainingBytesKey will contain number of remaining bytes.\n  GULNSDataZlibErrorDataRemaining\n};\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n\n@implementation GULMutableDictionary {\n  /// The mutable dictionary.\n  NSMutableDictionary *_objects;\n\n  /// Serial synchronization queue. All reads should use dispatch_sync, while writes use\n  /// dispatch_async.\n  dispatch_queue_t _queue;\n}\n\n- (instancetype)init {\n  self = [super init];\n\n  if (self) {\n    _objects = [[NSMutableDictionary alloc] init];\n    _queue = dispatch_queue_create(\"GULMutableDictionary\", DISPATCH_QUEUE_SERIAL);\n  }\n\n  return self;\n}\n\n- (NSString *)description {\n  __block NSString *description;\n  dispatch_sync(_queue, ^{\n    description = self->_objects.description;\n  });\n  return description;\n}\n\n- (id)objectForKey:(id)key {\n  __block id object;\n  dispatch_sync(_queue, ^{\n    object = [self->_objects objectForKey:key];\n  });\n  return object;\n}\n\n- (void)setObject:(id)object forKey:(id<NSCopying>)key {\n  dispatch_async(_queue, ^{\n    [self->_objects setObject:object forKey:key];\n  });\n}\n\n- (void)removeObjectForKey:(id)key {\n  dispatch_async(_queue, ^{\n    [self->_objects removeObjectForKey:key];\n  });\n}\n\n- (void)removeAllObjects {\n  dispatch_async(_queue, ^{\n    [self->_objects removeAllObjects];\n  });\n}\n\n- (NSUInteger)count {\n  __block NSUInteger count;\n  dispatch_sync(_queue, ^{\n    count = self->_objects.count;\n  });\n  return count;\n}\n\n- (id)objectForKeyedSubscript:(id<NSCopying>)key {\n  __block id object;\n  dispatch_sync(_queue, ^{\n    object = self->_objects[key];\n  });\n  return object;\n}\n\n- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {\n  dispatch_async(_queue, ^{\n    self->_objects[key] = obj;\n  });\n}\n\n- (NSDictionary *)dictionary {\n  __block NSDictionary *dictionary;\n  dispatch_sync(_queue, ^{\n    dictionary = [self->_objects copy];\n  });\n  return dictionary;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h\"\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n#import \"GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h\"\n#import \"GoogleUtilities/Network/GULNetworkInternal.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h\"\n#import \"GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h\"\n\n/// Constant string for request header Content-Encoding.\nstatic NSString *const kGULNetworkContentCompressionKey = @\"Content-Encoding\";\n\n/// Constant string for request header Content-Encoding value.\nstatic NSString *const kGULNetworkContentCompressionValue = @\"gzip\";\n\n/// Constant string for request header Content-Length.\nstatic NSString *const kGULNetworkContentLengthKey = @\"Content-Length\";\n\n/// Constant string for request header Content-Type.\nstatic NSString *const kGULNetworkContentTypeKey = @\"Content-Type\";\n\n/// Constant string for request header Content-Type value.\nstatic NSString *const kGULNetworkContentTypeValue = @\"application/x-www-form-urlencoded\";\n\n/// Constant string for GET request method.\nstatic NSString *const kGULNetworkGETRequestMethod = @\"GET\";\n\n/// Constant string for POST request method.\nstatic NSString *const kGULNetworkPOSTRequestMethod = @\"POST\";\n\n/// Default constant string as a prefix for network logger.\nstatic NSString *const kGULNetworkLogTag = @\"Google/Utilities/Network\";\n\n@interface GULNetwork () <GULReachabilityDelegate, GULNetworkLoggerDelegate>\n@end\n\n@implementation GULNetwork {\n  /// Network reachability.\n  GULReachabilityChecker *_reachability;\n\n  /// The dictionary of requests by session IDs { NSString : id }.\n  GULMutableDictionary *_requests;\n}\n\n- (instancetype)init {\n  return [self initWithReachabilityHost:kGULNetworkReachabilityHost];\n}\n\n- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost {\n  self = [super init];\n  if (self) {\n    // Setup reachability.\n    _reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self\n                                                                        withHost:reachabilityHost];\n    if (![_reachability start]) {\n      return nil;\n    }\n\n    _requests = [[GULMutableDictionary alloc] init];\n    _timeoutInterval = kGULNetworkTimeOutInterval;\n  }\n  return self;\n}\n\n- (void)dealloc {\n  _reachability.reachabilityDelegate = nil;\n  [_reachability stop];\n}\n\n#pragma mark - External Methods\n\n+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID\n                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler {\n  [GULNetworkURLSession handleEventsForBackgroundURLSessionID:sessionID\n                                            completionHandler:completionHandler];\n}\n\n- (NSString *)postURL:(NSURL *)url\n                   payload:(NSData *)payload\n                     queue:(dispatch_queue_t)queue\n    usingBackgroundSession:(BOOL)usingBackgroundSession\n         completionHandler:(GULNetworkCompletionHandler)handler {\n  if (!url.absoluteString.length) {\n    [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler];\n    return nil;\n  }\n\n  NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval;\n\n  NSMutableURLRequest *request =\n      [[NSMutableURLRequest alloc] initWithURL:url\n                                   cachePolicy:NSURLRequestReloadIgnoringLocalCacheData\n                               timeoutInterval:timeOutInterval];\n\n  if (!request) {\n    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation\n                        queue:queue\n                  withHandler:handler];\n    return nil;\n  }\n\n  NSError *compressError = nil;\n  NSData *compressedData = [NSData gul_dataByGzippingData:payload error:&compressError];\n  if (!compressedData || compressError) {\n    if (compressError || payload.length > 0) {\n      // If the payload is not empty but it fails to compress the payload, something has been wrong.\n      [self handleErrorWithCode:GULErrorCodeNetworkPayloadCompression\n                          queue:queue\n                    withHandler:handler];\n      return nil;\n    }\n    compressedData = [[NSData alloc] init];\n  }\n\n  NSString *postLength = @(compressedData.length).stringValue;\n\n  // Set up the request with the compressed data.\n  [request setValue:postLength forHTTPHeaderField:kGULNetworkContentLengthKey];\n  request.HTTPBody = compressedData;\n  request.HTTPMethod = kGULNetworkPOSTRequestMethod;\n  [request setValue:kGULNetworkContentTypeValue forHTTPHeaderField:kGULNetworkContentTypeKey];\n  [request setValue:kGULNetworkContentCompressionValue\n      forHTTPHeaderField:kGULNetworkContentCompressionKey];\n\n  GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self];\n  fetcher.backgroundNetworkEnabled = usingBackgroundSession;\n\n  __weak GULNetwork *weakSelf = self;\n  NSString *requestID = [fetcher\n      sessionIDFromAsyncPOSTRequest:request\n                  completionHandler:^(NSHTTPURLResponse *response, NSData *data,\n                                      NSString *sessionID, NSError *error) {\n                    GULNetwork *strongSelf = weakSelf;\n                    if (!strongSelf) {\n                      return;\n                    }\n                    dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();\n                    dispatch_async(queueToDispatch, ^{\n                      if (sessionID.length) {\n                        [strongSelf->_requests removeObjectForKey:sessionID];\n                      }\n                      if (handler) {\n                        handler(response, data, error);\n                      }\n                    });\n                  }];\n  if (!requestID) {\n    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation\n                        queue:queue\n                  withHandler:handler];\n    return nil;\n  }\n\n  [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                    messageCode:kGULNetworkMessageCodeNetwork000\n                        message:@\"Uploading data. Host\"\n                        context:url];\n  _requests[requestID] = fetcher;\n  return requestID;\n}\n\n- (NSString *)getURL:(NSURL *)url\n                   headers:(NSDictionary *)headers\n                     queue:(dispatch_queue_t)queue\n    usingBackgroundSession:(BOOL)usingBackgroundSession\n         completionHandler:(GULNetworkCompletionHandler)handler {\n  if (!url.absoluteString.length) {\n    [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler];\n    return nil;\n  }\n\n  NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval;\n  NSMutableURLRequest *request =\n      [[NSMutableURLRequest alloc] initWithURL:url\n                                   cachePolicy:NSURLRequestReloadIgnoringLocalCacheData\n                               timeoutInterval:timeOutInterval];\n\n  if (!request) {\n    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation\n                        queue:queue\n                  withHandler:handler];\n    return nil;\n  }\n\n  request.HTTPMethod = kGULNetworkGETRequestMethod;\n  request.allHTTPHeaderFields = headers;\n\n  GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self];\n  fetcher.backgroundNetworkEnabled = usingBackgroundSession;\n\n  __weak GULNetwork *weakSelf = self;\n  NSString *requestID = [fetcher\n      sessionIDFromAsyncGETRequest:request\n                 completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSString *sessionID,\n                                     NSError *error) {\n                   GULNetwork *strongSelf = weakSelf;\n                   if (!strongSelf) {\n                     return;\n                   }\n                   dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();\n                   dispatch_async(queueToDispatch, ^{\n                     if (sessionID.length) {\n                       [strongSelf->_requests removeObjectForKey:sessionID];\n                     }\n                     if (handler) {\n                       handler(response, data, error);\n                     }\n                   });\n                 }];\n\n  if (!requestID) {\n    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation\n                        queue:queue\n                  withHandler:handler];\n    return nil;\n  }\n\n  [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                    messageCode:kGULNetworkMessageCodeNetwork001\n                        message:@\"Downloading data. Host\"\n                        context:url];\n  _requests[requestID] = fetcher;\n  return requestID;\n}\n\n- (BOOL)hasUploadInProgress {\n  return _requests.count > 0;\n}\n\n#pragma mark - Network Reachability\n\n/// Tells reachability delegate to call reachabilityDidChangeToStatus: to notify the network\n/// reachability has changed.\n- (void)reachability:(GULReachabilityChecker *)reachability\n       statusChanged:(GULReachabilityStatus)status {\n  _networkConnected = (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi);\n  [_reachabilityDelegate reachabilityDidChange];\n}\n\n#pragma mark - Network logger delegate\n\n- (void)setLoggerDelegate:(id<GULNetworkLoggerDelegate>)loggerDelegate {\n  // Explicitly check whether the delegate responds to the methods because conformsToProtocol does\n  // not work correctly even though the delegate does respond to the methods.\n  if (!loggerDelegate ||\n      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:\n                                                                messageCode:message:contexts:)] ||\n      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:\n                                                                messageCode:message:context:)] ||\n      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:\n                                                                messageCode:message:)]) {\n    GULLogError(kGULLoggerNetwork, NO,\n                [NSString stringWithFormat:@\"I-NET%06ld\", (long)kGULNetworkMessageCodeNetwork002],\n                @\"Cannot set the network logger delegate: delegate does not conform to the network \"\n                 \"logger protocol.\");\n    return;\n  }\n  _loggerDelegate = loggerDelegate;\n}\n\n#pragma mark - Private methods\n\n/// Handles network error and calls completion handler with the error.\n- (void)handleErrorWithCode:(NSInteger)code\n                      queue:(dispatch_queue_t)queue\n                withHandler:(GULNetworkCompletionHandler)handler {\n  NSDictionary *userInfo = @{kGULNetworkErrorContext : @\"Failed to create network request\"};\n  NSError *error = [[NSError alloc] initWithDomain:kGULNetworkErrorDomain\n                                              code:code\n                                          userInfo:userInfo];\n  [self GULNetwork_logWithLevel:kGULNetworkLogLevelWarning\n                    messageCode:kGULNetworkMessageCodeNetwork002\n                        message:@\"Failed to create network request. Code, error\"\n                       contexts:@[ @(code), error ]];\n  if (handler) {\n    dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();\n    dispatch_async(queueToDispatch, ^{\n      handler(nil, nil, error);\n    });\n  }\n}\n\n#pragma mark - Network logger\n\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message\n                       contexts:(NSArray *)contexts {\n  // Let the delegate log the message if there is a valid logger delegate. Otherwise, just log\n  // errors/warnings/info messages to the console log.\n  if (_loggerDelegate) {\n    [_loggerDelegate GULNetwork_logWithLevel:logLevel\n                                 messageCode:messageCode\n                                     message:message\n                                    contexts:contexts];\n    return;\n  }\n  if (_isDebugModeEnabled || logLevel == kGULNetworkLogLevelError ||\n      logLevel == kGULNetworkLogLevelWarning || logLevel == kGULNetworkLogLevelInfo) {\n    NSString *formattedMessage = GULStringWithLogMessage(message, logLevel, contexts);\n    NSLog(@\"%@\", formattedMessage);\n    GULLogBasic((GULLoggerLevel)logLevel, kGULLoggerNetwork, NO,\n                [NSString stringWithFormat:@\"I-NET%06ld\", (long)messageCode], formattedMessage,\n                NULL);\n  }\n}\n\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message\n                        context:(id)context {\n  if (_loggerDelegate) {\n    [_loggerDelegate GULNetwork_logWithLevel:logLevel\n                                 messageCode:messageCode\n                                     message:message\n                                     context:context];\n    return;\n  }\n  NSArray *contexts = context ? @[ context ] : @[];\n  [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:contexts];\n}\n\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message {\n  if (_loggerDelegate) {\n    [_loggerDelegate GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message];\n    return;\n  }\n  [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:@[]];\n}\n\n/// Returns a string for the given log level (e.g. kGULNetworkLogLevelError -> @\"ERROR\").\nstatic NSString *GULLogLevelDescriptionFromLogLevel(GULNetworkLogLevel logLevel) {\n  static NSDictionary *levelNames = nil;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    levelNames = @{\n      @(kGULNetworkLogLevelError) : @\"ERROR\",\n      @(kGULNetworkLogLevelWarning) : @\"WARNING\",\n      @(kGULNetworkLogLevelInfo) : @\"INFO\",\n      @(kGULNetworkLogLevelDebug) : @\"DEBUG\"\n    };\n  });\n  return levelNames[@(logLevel)];\n}\n\n/// Returns a formatted string to be used for console logging.\nstatic NSString *GULStringWithLogMessage(NSString *message,\n                                         GULNetworkLogLevel logLevel,\n                                         NSArray *contexts) {\n  if (!message) {\n    message = @\"(Message was nil)\";\n  } else if (!message.length) {\n    message = @\"(Message was empty)\";\n  }\n  NSMutableString *result = [[NSMutableString alloc]\n      initWithFormat:@\"<%@/%@> %@\", kGULNetworkLogTag, GULLogLevelDescriptionFromLogLevel(logLevel),\n                     message];\n\n  if (!contexts.count) {\n    return result;\n  }\n\n  NSMutableArray *formattedContexts = [[NSMutableArray alloc] init];\n  for (id item in contexts) {\n    [formattedContexts addObject:(item != [NSNull null] ? item : @\"(nil)\")];\n  }\n\n  [result appendString:@\": \"];\n  [result appendString:[formattedContexts componentsJoinedByString:@\", \"]];\n  return result;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h\"\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\n#import <Foundation/Foundation.h>\n\nNSString *const kGULNetworkBackgroundSessionConfigIDPrefix = @\"com.gul.network.background-upload\";\nNSString *const kGULNetworkApplicationSupportSubdirectory = @\"GUL/Network\";\nNSString *const kGULNetworkTempDirectoryName = @\"GULNetworkTemporaryDirectory\";\nconst NSTimeInterval kGULNetworkTempFolderExpireTime = 60 * 60;  // 1 hour\nconst NSTimeInterval kGULNetworkTimeOutInterval = 60;            // 1 minute.\nNSString *const kGULNetworkReachabilityHost = @\"app-measurement.com\";\nNSString *const kGULNetworkErrorContext = @\"Context\";\n\nconst int kGULNetworkHTTPStatusOK = 200;\nconst int kGULNetworkHTTPStatusNoContent = 204;\nconst int kGULNetworkHTTPStatusCodeMultipleChoices = 300;\nconst int kGULNetworkHTTPStatusCodeMovedPermanently = 301;\nconst int kGULNetworkHTTPStatusCodeFound = 302;\nconst int kGULNetworkHTTPStatusCodeNotModified = 304;\nconst int kGULNetworkHTTPStatusCodeMovedTemporarily = 307;\nconst int kGULNetworkHTTPStatusCodeNotFound = 404;\nconst int kGULNetworkHTTPStatusCodeCannotAcceptTraffic = 429;\nconst int kGULNetworkHTTPStatusCodeUnavailable = 503;\n\nNSString *const kGULNetworkErrorDomain = @\"com.gul.network.ErrorDomain\";\n\nGULLoggerService kGULLoggerNetwork = @\"[GULNetwork]\";\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkInternal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\nextern NSString *const kGULNetworkErrorDomain;\n\n/// The logger service for GULNetwork.\nextern GULLoggerService kGULLoggerNetwork;\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h\"\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n#import \"GoogleUtilities/Network/GULNetworkInternal.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h\"\n#import \"GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h\"\n\n@interface GULNetworkURLSession () <NSURLSessionDelegate,\n                                    NSURLSessionDataDelegate,\n                                    NSURLSessionDownloadDelegate,\n                                    NSURLSessionTaskDelegate>\n@end\n\n@implementation GULNetworkURLSession {\n  /// The handler to be called when the request completes or error has occurs.\n  GULNetworkURLSessionCompletionHandler _completionHandler;\n\n  /// Session ID generated randomly with a fixed prefix.\n  NSString *_sessionID;\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n  /// The session configuration. NSURLSessionConfiguration' is only available on iOS 7.0 or newer.\n  NSURLSessionConfiguration *_sessionConfig;\n\n  /// The current NSURLSession.\n  NSURLSession *__weak _Nullable _URLSession;\n#pragma clang diagnostic pop\n\n  /// The path to the directory where all temporary files are stored before uploading.\n  NSURL *_networkDirectoryURL;\n\n  /// The downloaded data from fetching.\n  NSData *_downloadedData;\n\n  /// The path to the temporary file which stores the uploading data.\n  NSURL *_uploadingFileURL;\n\n  /// The current request.\n  NSURLRequest *_request;\n}\n\n#pragma mark - Init\n\n- (instancetype)initWithNetworkLoggerDelegate:(id<GULNetworkLoggerDelegate>)networkLoggerDelegate {\n  self = [super init];\n  if (self) {\n    // Create URL to the directory where all temporary files to upload have to be stored.\n#if TARGET_OS_TV\n    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);\n#else\n    NSArray *paths =\n        NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);\n#endif\n    NSString *storageDirectory = paths.firstObject;\n    NSArray *tempPathComponents = @[\n      storageDirectory, kGULNetworkApplicationSupportSubdirectory, kGULNetworkTempDirectoryName\n    ];\n    _networkDirectoryURL = [NSURL fileURLWithPathComponents:tempPathComponents];\n    _sessionID = [NSString stringWithFormat:@\"%@-%@\", kGULNetworkBackgroundSessionConfigIDPrefix,\n                                            [[NSUUID UUID] UUIDString]];\n    _loggerDelegate = networkLoggerDelegate;\n  }\n  return self;\n}\n\n#pragma mark - External Methods\n\n#pragma mark - To be called from AppDelegate\n\n+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID\n                            completionHandler:\n                                (GULNetworkSystemCompletionHandler)systemCompletionHandler {\n  // The session may not be Analytics background. Ignore those that do not have the prefix.\n  if (![sessionID hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) {\n    return;\n  }\n  GULNetworkURLSession *fetcher = [self fetcherWithSessionIdentifier:sessionID];\n  if (fetcher != nil) {\n    [fetcher addSystemCompletionHandler:systemCompletionHandler forSession:sessionID];\n  } else {\n    GULLogError(kGULLoggerNetwork, NO,\n                [NSString stringWithFormat:@\"I-NET%06ld\", (long)kGULNetworkMessageCodeNetwork003],\n                @\"Failed to retrieve background session with ID %@ after app is relaunched.\",\n                sessionID);\n  }\n}\n\n#pragma mark - External Methods\n\n/// Sends an async POST request using NSURLSession for iOS >= 7.0, and returns an ID of the\n/// connection.\n- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request\n                                   completionHandler:(GULNetworkURLSessionCompletionHandler)handler\n    API_AVAILABLE(ios(7.0)) {\n  // NSURLSessionUploadTask does not work with NSData in the background.\n  // To avoid this issue, write the data to a temporary file to upload it.\n  // Make a temporary file with the data subset.\n  _uploadingFileURL = [self temporaryFilePathWithSessionID:_sessionID];\n  NSError *writeError;\n  NSURLSessionUploadTask *postRequestTask;\n  NSURLSession *session;\n  BOOL didWriteFile = NO;\n\n  // Clean up the entire temp folder to avoid temp files that remain in case the previous session\n  // crashed and did not clean up.\n  [self maybeRemoveTempFilesAtURL:_networkDirectoryURL\n                     expiringTime:kGULNetworkTempFolderExpireTime];\n\n  // If there is no background network enabled, no need to write to file. This will allow default\n  // network session which runs on the foreground.\n  if (_backgroundNetworkEnabled && [self ensureTemporaryDirectoryExists]) {\n    didWriteFile = [request.HTTPBody writeToFile:_uploadingFileURL.path\n                                         options:NSDataWritingAtomic\n                                           error:&writeError];\n\n    if (writeError) {\n      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                   messageCode:kGULNetworkMessageCodeURLSession000\n                                       message:@\"Failed to write request data to file\"\n                                       context:writeError];\n    }\n  }\n\n  if (didWriteFile) {\n    // Exclude this file from backing up to iTunes. There are conflicting reports that excluding\n    // directory from backing up does not exclude files of that directory from backing up.\n    [self excludeFromBackupForURL:_uploadingFileURL];\n\n    _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID];\n    [self populateSessionConfig:_sessionConfig withRequest:request];\n    session = [NSURLSession sessionWithConfiguration:_sessionConfig\n                                            delegate:self\n                                       delegateQueue:[NSOperationQueue mainQueue]];\n    postRequestTask = [session uploadTaskWithRequest:request fromFile:_uploadingFileURL];\n  } else {\n    // If we cannot write to file, just send it in the foreground.\n    _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];\n    [self populateSessionConfig:_sessionConfig withRequest:request];\n    session = [NSURLSession sessionWithConfiguration:_sessionConfig\n                                            delegate:self\n                                       delegateQueue:[NSOperationQueue mainQueue]];\n    postRequestTask = [session uploadTaskWithRequest:request fromData:request.HTTPBody];\n  }\n\n  if (!session || !postRequestTask) {\n    NSError *error = [[NSError alloc]\n        initWithDomain:kGULNetworkErrorDomain\n                  code:GULErrorCodeNetworkRequestCreation\n              userInfo:@{kGULNetworkErrorContext : @\"Cannot create network session\"}];\n    [self callCompletionHandler:handler withResponse:nil data:nil error:error];\n    return nil;\n  }\n\n  _URLSession = session;\n\n  // Save the session into memory.\n  [[self class] setSessionInFetcherMap:self forSessionID:_sessionID];\n\n  _request = [request copy];\n\n  // Store completion handler because background session does not accept handler block but custom\n  // delegate.\n  _completionHandler = [handler copy];\n  [postRequestTask resume];\n\n  return _sessionID;\n}\n\n/// Sends an async GET request using NSURLSession for iOS >= 7.0, and returns an ID of the session.\n- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request\n                                  completionHandler:(GULNetworkURLSessionCompletionHandler)handler\n    API_AVAILABLE(ios(7.0)) {\n  if (_backgroundNetworkEnabled) {\n    _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID];\n  } else {\n    _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];\n  }\n\n  [self populateSessionConfig:_sessionConfig withRequest:request];\n\n  // Do not cache the GET request.\n  _sessionConfig.URLCache = nil;\n\n  NSURLSession *session = [NSURLSession sessionWithConfiguration:_sessionConfig\n                                                        delegate:self\n                                                   delegateQueue:[NSOperationQueue mainQueue]];\n  NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];\n\n  if (!session || !downloadTask) {\n    NSError *error = [[NSError alloc]\n        initWithDomain:kGULNetworkErrorDomain\n                  code:GULErrorCodeNetworkRequestCreation\n              userInfo:@{kGULNetworkErrorContext : @\"Cannot create network session\"}];\n    [self callCompletionHandler:handler withResponse:nil data:nil error:error];\n    return nil;\n  }\n\n  _URLSession = session;\n\n  // Save the session into memory.\n  [[self class] setSessionInFetcherMap:self forSessionID:_sessionID];\n\n  _request = [request copy];\n\n  _completionHandler = [handler copy];\n  [downloadTask resume];\n\n  return _sessionID;\n}\n\n#pragma mark - NSURLSessionDataDelegate\n\n/// Called by the NSURLSession when the data task has received some of the expected data.\n/// Once the session is completed, URLSession:task:didCompleteWithError will be called and the\n/// completion handler will be called with the downloaded data.\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\n    didReceiveData:(NSData *)data {\n  @synchronized(self) {\n    NSMutableData *mutableData = [[NSMutableData alloc] init];\n    if (_downloadedData) {\n      mutableData = _downloadedData.mutableCopy;\n    }\n    [mutableData appendData:data];\n    _downloadedData = mutableData;\n  }\n}\n\n#pragma mark - NSURLSessionTaskDelegate\n\n/// Called by the NSURLSession once the download task is completed. The file is saved in the\n/// provided URL so we need to read the data and store into _downloadedData. Once the session is\n/// completed, URLSession:task:didCompleteWithError will be called and the completion handler will\n/// be called with the downloaded data.\n- (void)URLSession:(NSURLSession *)session\n                 downloadTask:(NSURLSessionDownloadTask *)task\n    didFinishDownloadingToURL:(NSURL *)url API_AVAILABLE(ios(7.0)) {\n  if (!url.path) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                    messageCode:kGULNetworkMessageCodeURLSession001\n                        message:@\"Unable to read downloaded data from empty temp path\"];\n    _downloadedData = nil;\n    return;\n  }\n\n  NSError *error;\n  _downloadedData = [NSData dataWithContentsOfFile:url.path options:0 error:&error];\n\n  if (error) {\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                 messageCode:kGULNetworkMessageCodeURLSession002\n                                     message:@\"Cannot read the content of downloaded data\"\n                                     context:error];\n    _downloadedData = nil;\n  }\n}\n\n#if TARGET_OS_IOS || TARGET_OS_TV\n- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session\n    API_AVAILABLE(ios(7.0)) {\n  [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                               messageCode:kGULNetworkMessageCodeURLSession003\n                                   message:@\"Background session finished\"\n                                   context:session.configuration.identifier];\n  [self callSystemCompletionHandler:session.configuration.identifier];\n}\n#endif\n\n- (void)URLSession:(NSURLSession *)session\n                    task:(NSURLSessionTask *)task\n    didCompleteWithError:(NSError *)error API_AVAILABLE(ios(7.0)) {\n  // Avoid any chance of recursive behavior leading to it being used repeatedly.\n  GULNetworkURLSessionCompletionHandler handler = _completionHandler;\n  _completionHandler = nil;\n\n  if (task.response) {\n    // The following assertion should always be true for HTTP requests, see https://goo.gl/gVLxT7.\n    NSAssert([task.response isKindOfClass:[NSHTTPURLResponse class]], @\"URL response must be HTTP\");\n\n    // The server responded so ignore the error created by the system.\n    error = nil;\n  } else if (!error) {\n    error = [[NSError alloc]\n        initWithDomain:kGULNetworkErrorDomain\n                  code:GULErrorCodeNetworkInvalidResponse\n              userInfo:@{kGULNetworkErrorContext : @\"Network Error: Empty network response\"}];\n  }\n\n  [self callCompletionHandler:handler\n                 withResponse:(NSHTTPURLResponse *)task.response\n                         data:_downloadedData\n                        error:error];\n\n  // Remove the temp file to avoid trashing devices with lots of temp files.\n  [self removeTempItemAtURL:_uploadingFileURL];\n\n  // Try to clean up stale files again.\n  [self maybeRemoveTempFilesAtURL:_networkDirectoryURL\n                     expiringTime:kGULNetworkTempFolderExpireTime];\n\n  // This is called without checking the sessionID here since non-background sessions\n  // won't have an ID.\n  [session finishTasksAndInvalidate];\n\n  // Explicitly remove the session so it won't be reused. The weak map table should\n  // remove the session on deallocation, but dealloc may not happen immediately after\n  // calling `finishTasksAndInvalidate`.\n  NSString *sessionID = session.configuration.identifier;\n  [[self class] setSessionInFetcherMap:nil forSessionID:sessionID];\n}\n\n- (void)URLSession:(NSURLSession *)session\n                   task:(NSURLSessionTask *)task\n    didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge\n      completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,\n                                  NSURLCredential *credential))completionHandler\n    API_AVAILABLE(ios(7.0)) {\n  // The handling is modeled after GTMSessionFetcher.\n  if ([challenge.protectionSpace.authenticationMethod\n          isEqualToString:NSURLAuthenticationMethodServerTrust]) {\n    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;\n    if (serverTrust == NULL) {\n      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                                   messageCode:kGULNetworkMessageCodeURLSession004\n                                       message:@\"Received empty server trust for host. Host\"\n                                       context:_request.URL];\n      completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);\n      return;\n    }\n    NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];\n    if (!credential) {\n      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning\n                                   messageCode:kGULNetworkMessageCodeURLSession005\n                                       message:@\"Unable to verify server identity. Host\"\n                                       context:_request.URL];\n      completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);\n      return;\n    }\n\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                                 messageCode:kGULNetworkMessageCodeURLSession006\n                                     message:@\"Received SSL challenge for host. Host\"\n                                     context:_request.URL];\n\n    void (^callback)(BOOL) = ^(BOOL allow) {\n      if (allow) {\n        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);\n      } else {\n        [self->_loggerDelegate\n            GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                        messageCode:kGULNetworkMessageCodeURLSession007\n                            message:@\"Cancelling authentication challenge for host. Host\"\n                            context:self->_request.URL];\n        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);\n      }\n    };\n\n    // Retain the trust object to avoid a SecTrustEvaluate() crash on iOS 7.\n    CFRetain(serverTrust);\n\n    // Evaluate the certificate chain.\n    //\n    // The delegate queue may be the main thread. Trust evaluation could cause some\n    // blocking network activity, so we must evaluate async, as documented at\n    // https://developer.apple.com/library/ios/technotes/tn2232/\n    dispatch_queue_t evaluateBackgroundQueue =\n        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);\n\n    dispatch_async(evaluateBackgroundQueue, ^{\n      SecTrustResultType trustEval = kSecTrustResultInvalid;\n      BOOL shouldAllow;\n      OSStatus trustError;\n\n      @synchronized([GULNetworkURLSession class]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n        trustError = SecTrustEvaluate(serverTrust, &trustEval);\n#pragma clang dianostic pop\n      }\n\n      if (trustError != errSecSuccess) {\n        [self->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                           messageCode:kGULNetworkMessageCodeURLSession008\n                                               message:@\"Cannot evaluate server trust. Error, host\"\n                                              contexts:@[ @(trustError), self->_request.URL ]];\n        shouldAllow = NO;\n      } else {\n        // Having a trust level \"unspecified\" by the user is the usual result, described at\n        // https://developer.apple.com/library/mac/qa/qa1360\n        shouldAllow =\n            (trustEval == kSecTrustResultUnspecified || trustEval == kSecTrustResultProceed);\n      }\n\n      // Call the call back with the permission.\n      callback(shouldAllow);\n\n      CFRelease(serverTrust);\n    });\n    return;\n  }\n\n  // Default handling for other Auth Challenges.\n  completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);\n}\n\n#pragma mark - Internal Methods\n\n/// Stores system completion handler with session ID as key.\n- (void)addSystemCompletionHandler:(GULNetworkSystemCompletionHandler)handler\n                        forSession:(NSString *)identifier {\n  if (!handler) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                    messageCode:kGULNetworkMessageCodeURLSession009\n                        message:@\"Cannot store nil system completion handler in network\"];\n    return;\n  }\n\n  if (!identifier.length) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                    messageCode:kGULNetworkMessageCodeURLSession010\n                        message:@\"Cannot store system completion handler with empty network \"\n                                 \"session identifier\"];\n    return;\n  }\n\n  GULMutableDictionary *systemCompletionHandlers =\n      [[self class] sessionIDToSystemCompletionHandlerDictionary];\n  if (systemCompletionHandlers[identifier]) {\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning\n                                 messageCode:kGULNetworkMessageCodeURLSession011\n                                     message:@\"Got multiple system handlers for a single session ID\"\n                                     context:identifier];\n  }\n\n  systemCompletionHandlers[identifier] = handler;\n}\n\n/// Calls the system provided completion handler with the session ID stored in the dictionary.\n/// The handler will be removed from the dictionary after being called.\n- (void)callSystemCompletionHandler:(NSString *)identifier {\n  GULMutableDictionary *systemCompletionHandlers =\n      [[self class] sessionIDToSystemCompletionHandlerDictionary];\n  GULNetworkSystemCompletionHandler handler = [systemCompletionHandlers objectForKey:identifier];\n\n  if (handler) {\n    [systemCompletionHandlers removeObjectForKey:identifier];\n\n    dispatch_async(dispatch_get_main_queue(), ^{\n      handler();\n    });\n  }\n}\n\n/// Sets or updates the session ID of this session.\n- (void)setSessionID:(NSString *)sessionID {\n  _sessionID = [sessionID copy];\n}\n\n/// Creates a background session configuration with the session ID using the supported method.\n- (NSURLSessionConfiguration *)backgroundSessionConfigWithSessionID:(NSString *)sessionID\n    API_AVAILABLE(ios(7.0)) {\n#if (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) &&         \\\n     MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) || \\\n    TARGET_OS_TV ||                                              \\\n    (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)\n\n  // iOS 8/10.10 builds require the new backgroundSessionConfiguration method name.\n  return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];\n\n#elif (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) &&        \\\n       MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10) || \\\n    (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0)\n\n  // Do a runtime check to avoid a deprecation warning about using\n  // +backgroundSessionConfiguration: on iOS 8.\n  if ([NSURLSessionConfiguration\n          respondsToSelector:@selector(backgroundSessionConfigurationWithIdentifier:)]) {\n    // Running on iOS 8+/OS X 10.10+.\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n    return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];\n#pragma clang diagnostic pop\n  } else {\n    // Running on iOS 7/OS X 10.9.\n    return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID];\n  }\n\n#else\n  // Building with an SDK earlier than iOS 8/OS X 10.10.\n  return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID];\n#endif\n}\n\n- (void)maybeRemoveTempFilesAtURL:(NSURL *)folderURL expiringTime:(NSTimeInterval)staleTime {\n  if (!folderURL.absoluteString.length) {\n    return;\n  }\n\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n  NSError *error = nil;\n\n  NSArray *properties = @[ NSURLCreationDateKey ];\n  NSArray *directoryContent =\n      [fileManager contentsOfDirectoryAtURL:folderURL\n                 includingPropertiesForKeys:properties\n                                    options:NSDirectoryEnumerationSkipsSubdirectoryDescendants\n                                      error:&error];\n  if (error && error.code != NSFileReadNoSuchFileError) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelDebug\n                    messageCode:kGULNetworkMessageCodeURLSession012\n                        message:@\"Cannot get files from the temporary network folder. Error\"\n                        context:error];\n    return;\n  }\n\n  if (!directoryContent.count) {\n    return;\n  }\n\n  NSTimeInterval now = [NSDate date].timeIntervalSince1970;\n  for (NSURL *tempFile in directoryContent) {\n    NSDate *creationDate;\n    BOOL getCreationDate = [tempFile getResourceValue:&creationDate\n                                               forKey:NSURLCreationDateKey\n                                                error:NULL];\n    if (!getCreationDate) {\n      continue;\n    }\n    NSTimeInterval creationTimeInterval = creationDate.timeIntervalSince1970;\n    if (fabs(now - creationTimeInterval) > staleTime) {\n      [self removeTempItemAtURL:tempFile];\n    }\n  }\n}\n\n/// Removes the temporary file written to disk for sending the request. It has to be cleaned up\n/// after the session is done.\n- (void)removeTempItemAtURL:(NSURL *)fileURL {\n  if (!fileURL.absoluteString.length) {\n    return;\n  }\n\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n  NSError *error = nil;\n\n  if (![fileManager removeItemAtURL:fileURL error:&error] && error.code != NSFileNoSuchFileError) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                    messageCode:kGULNetworkMessageCodeURLSession013\n                        message:@\"Failed to remove temporary uploading data file. Error\"\n                        context:error.localizedDescription];\n  }\n}\n\n/// Gets the fetcher with the session ID.\n+ (instancetype)fetcherWithSessionIdentifier:(NSString *)sessionIdentifier {\n  GULNetworkURLSession *session = [self sessionFromFetcherMapForSessionID:sessionIdentifier];\n  if (!session && [sessionIdentifier hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) {\n    session = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:nil];\n    [session setSessionID:sessionIdentifier];\n    [self setSessionInFetcherMap:session forSessionID:sessionIdentifier];\n  }\n  return session;\n}\n\n/// Returns a map of the fetcher by session ID. Creates a map if it is not created.\n/// When reading and writing from/to the session map, don't use this method directly.\n/// To avoid thread safety issues, use one of the helper methods at the bottom of the\n/// file: setSessionInFetcherMap:forSessionID:, sessionFromFetcherMapForSessionID:\n+ (NSMapTable<NSString *, GULNetworkURLSession *> *)sessionIDToFetcherMap {\n  static NSMapTable *sessionIDToFetcherMap;\n\n  static dispatch_once_t sessionMapOnceToken;\n  dispatch_once(&sessionMapOnceToken, ^{\n    sessionIDToFetcherMap = [NSMapTable strongToWeakObjectsMapTable];\n  });\n  return sessionIDToFetcherMap;\n}\n\n+ (NSLock *)sessionIDToFetcherMapReadWriteLock {\n  static NSLock *lock;\n\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    lock = [[NSLock alloc] init];\n  });\n  return lock;\n}\n\n/// Returns a map of system provided completion handler by session ID. Creates a map if it is not\n/// created.\n+ (GULMutableDictionary *)sessionIDToSystemCompletionHandlerDictionary {\n  static GULMutableDictionary *systemCompletionHandlers;\n\n  static dispatch_once_t systemCompletionHandlerOnceToken;\n  dispatch_once(&systemCompletionHandlerOnceToken, ^{\n    systemCompletionHandlers = [[GULMutableDictionary alloc] init];\n  });\n  return systemCompletionHandlers;\n}\n\n- (NSURL *)temporaryFilePathWithSessionID:(NSString *)sessionID {\n  NSString *tempName = [NSString stringWithFormat:@\"GULUpload_temp_%@\", sessionID];\n  return [_networkDirectoryURL URLByAppendingPathComponent:tempName];\n}\n\n/// Makes sure that the directory to store temp files exists. If not, tries to create it and returns\n/// YES. If there is anything wrong, returns NO.\n- (BOOL)ensureTemporaryDirectoryExists {\n  NSFileManager *fileManager = [NSFileManager defaultManager];\n  NSError *error = nil;\n\n  // Create a temporary directory if it does not exist or was deleted.\n  if ([_networkDirectoryURL checkResourceIsReachableAndReturnError:&error]) {\n    return YES;\n  }\n\n  if (error && error.code != NSFileReadNoSuchFileError) {\n    [_loggerDelegate\n        GULNetwork_logWithLevel:kGULNetworkLogLevelWarning\n                    messageCode:kGULNetworkMessageCodeURLSession014\n                        message:@\"Error while trying to access Network temp folder. Error\"\n                        context:error];\n  }\n\n  NSError *writeError = nil;\n\n  [fileManager createDirectoryAtURL:_networkDirectoryURL\n        withIntermediateDirectories:YES\n                         attributes:nil\n                              error:&writeError];\n  if (writeError) {\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                 messageCode:kGULNetworkMessageCodeURLSession015\n                                     message:@\"Cannot create temporary directory. Error\"\n                                     context:writeError];\n    return NO;\n  }\n\n  // Set the iCloud exclusion attribute on the Documents URL.\n  [self excludeFromBackupForURL:_networkDirectoryURL];\n\n  return YES;\n}\n\n- (void)excludeFromBackupForURL:(NSURL *)url {\n  if (!url.path) {\n    return;\n  }\n\n  // Set the iCloud exclusion attribute on the Documents URL.\n  NSError *preventBackupError = nil;\n  [url setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:&preventBackupError];\n  if (preventBackupError) {\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                 messageCode:kGULNetworkMessageCodeURLSession016\n                                     message:@\"Cannot exclude temporary folder from iTunes backup\"];\n  }\n}\n\n- (void)URLSession:(NSURLSession *)session\n                          task:(NSURLSessionTask *)task\n    willPerformHTTPRedirection:(NSHTTPURLResponse *)response\n                    newRequest:(NSURLRequest *)request\n             completionHandler:(void (^)(NSURLRequest *))completionHandler API_AVAILABLE(ios(7.0)) {\n  NSArray *nonAllowedRedirectionCodes = @[\n    @(kGULNetworkHTTPStatusCodeFound), @(kGULNetworkHTTPStatusCodeMovedPermanently),\n    @(kGULNetworkHTTPStatusCodeMovedTemporarily), @(kGULNetworkHTTPStatusCodeMultipleChoices)\n  ];\n\n  // Allow those not in the non allowed list to be followed.\n  if (![nonAllowedRedirectionCodes containsObject:@(response.statusCode)]) {\n    completionHandler(request);\n    return;\n  }\n\n  // Do not allow redirection if the response code is in the non-allowed list.\n  NSURLRequest *newRequest = request;\n\n  if (response) {\n    newRequest = nil;\n  }\n\n  completionHandler(newRequest);\n}\n\n#pragma mark - Helper Methods\n\n+ (void)setSessionInFetcherMap:(GULNetworkURLSession *)session forSessionID:(NSString *)sessionID {\n  [[self sessionIDToFetcherMapReadWriteLock] lock];\n  GULNetworkURLSession *existingSession =\n      [[[self class] sessionIDToFetcherMap] objectForKey:sessionID];\n  if (existingSession) {\n    if (session) {\n      NSString *message = [NSString stringWithFormat:@\"Discarding session: %@\", existingSession];\n      [existingSession->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelInfo\n                                                    messageCode:kGULNetworkMessageCodeURLSession019\n                                                        message:message];\n    }\n    [existingSession->_URLSession finishTasksAndInvalidate];\n  }\n  if (session) {\n    [[[self class] sessionIDToFetcherMap] setObject:session forKey:sessionID];\n  } else {\n    [[[self class] sessionIDToFetcherMap] removeObjectForKey:sessionID];\n  }\n  [[self sessionIDToFetcherMapReadWriteLock] unlock];\n}\n\n+ (nullable GULNetworkURLSession *)sessionFromFetcherMapForSessionID:(NSString *)sessionID {\n  [[self sessionIDToFetcherMapReadWriteLock] lock];\n  GULNetworkURLSession *session = [[[self class] sessionIDToFetcherMap] objectForKey:sessionID];\n  [[self sessionIDToFetcherMapReadWriteLock] unlock];\n  return session;\n}\n\n- (void)callCompletionHandler:(GULNetworkURLSessionCompletionHandler)handler\n                 withResponse:(NSHTTPURLResponse *)response\n                         data:(NSData *)data\n                        error:(NSError *)error {\n  if (error) {\n    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError\n                                 messageCode:kGULNetworkMessageCodeURLSession017\n                                     message:@\"Encounter network error. Code, error\"\n                                    contexts:@[ @(error.code), error ]];\n  }\n\n  if (handler) {\n    dispatch_async(dispatch_get_main_queue(), ^{\n      handler(response, data, self->_sessionID, error);\n    });\n  }\n}\n\n// Always use the request parameters even if the default session configuration is more restrictive.\n- (void)populateSessionConfig:(NSURLSessionConfiguration *)sessionConfig\n                  withRequest:(NSURLRequest *)request API_AVAILABLE(ios(7.0)) {\n  sessionConfig.HTTPAdditionalHeaders = request.allHTTPHeaderFields;\n  sessionConfig.timeoutIntervalForRequest = request.timeoutInterval;\n  sessionConfig.timeoutIntervalForResource = request.timeoutInterval;\n  sessionConfig.requestCachePolicy = request.cachePolicy;\n}\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/// A mutable dictionary that provides atomic accessor and mutators.\n@interface GULMutableDictionary : NSObject\n\n/// Returns an object given a key in the dictionary or nil if not found.\n- (id)objectForKey:(id)key;\n\n/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary.\n- (void)setObject:(id)object forKey:(id<NSCopying>)key;\n\n/// Removes the object given its session ID from the dictionary.\n- (void)removeObjectForKey:(id)key;\n\n/// Removes all objects.\n- (void)removeAllObjects;\n\n/// Returns the number of current objects in the dictionary.\n- (NSUInteger)count;\n\n/// Returns an object given a key in the dictionary or nil if not found.\n- (id)objectForKeyedSubscript:(id<NSCopying>)key;\n\n/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary.\n- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key;\n\n/// Returns the immutable dictionary.\n- (NSDictionary *)dictionary;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULNetworkConstants.h\"\n#import \"GULNetworkLoggerProtocol.h\"\n#import \"GULNetworkURLSession.h\"\n\n/// Delegate protocol for GULNetwork events.\n@protocol GULNetworkReachabilityDelegate\n\n/// Tells the delegate to handle events when the network reachability changes to connected or not\n/// connected.\n- (void)reachabilityDidChange;\n\n@end\n\n/// The Network component that provides network status and handles network requests and responses.\n/// This is not thread safe.\n///\n/// NOTE:\n/// User must add FIRAnalytics handleEventsForBackgroundURLSessionID:completionHandler to the\n/// AppDelegate application:handleEventsForBackgroundURLSession:completionHandler:\n@interface GULNetwork : NSObject\n\n/// Indicates if network connectivity is available.\n@property(nonatomic, readonly, getter=isNetworkConnected) BOOL networkConnected;\n\n/// Indicates if there are any uploads in progress.\n@property(nonatomic, readonly, getter=hasUploadInProgress) BOOL uploadInProgress;\n\n/// An optional delegate that can be used in the event when network reachability changes.\n@property(nonatomic, weak) id<GULNetworkReachabilityDelegate> reachabilityDelegate;\n\n/// An optional delegate that can be used to log messages, warnings or errors that occur in the\n/// network operations.\n@property(nonatomic, weak) id<GULNetworkLoggerDelegate> loggerDelegate;\n\n/// Indicates whether the logger should display debug messages.\n@property(nonatomic, assign) BOOL isDebugModeEnabled;\n\n/// The time interval in seconds for the network request to timeout.\n@property(nonatomic, assign) NSTimeInterval timeoutInterval;\n\n/// Initializes with the default reachability host.\n- (instancetype)init;\n\n/// Initializes with a custom reachability host.\n- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost;\n\n/// Handles events when background session with the given ID has finished.\n+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID\n                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler;\n\n/// Compresses and sends a POST request with the provided data to the URL. The session will be\n/// background session if usingBackgroundSession is YES. Otherwise, the POST session is default\n/// session. Returns a session ID or nil if an error occurs.\n- (NSString *)postURL:(NSURL *)url\n                   payload:(NSData *)payload\n                     queue:(dispatch_queue_t)queue\n    usingBackgroundSession:(BOOL)usingBackgroundSession\n         completionHandler:(GULNetworkCompletionHandler)handler;\n\n/// Sends a GET request with the provided data to the URL. The session will be background session\n/// if usingBackgroundSession is YES. Otherwise, the GET session is default session. Returns a\n/// session ID or nil if an error occurs.\n- (NSString *)getURL:(NSURL *)url\n                   headers:(NSDictionary *)headers\n                     queue:(dispatch_queue_t)queue\n    usingBackgroundSession:(BOOL)usingBackgroundSession\n         completionHandler:(GULNetworkCompletionHandler)handler;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n/// Error codes in Firebase Network error domain.\n/// Note: these error codes should never change. It would make it harder to decode the errors if\n/// we inadvertently altered any of these codes in a future SDK version.\ntypedef NS_ENUM(NSInteger, GULNetworkErrorCode) {\n  /// Unknown error.\n  GULNetworkErrorCodeUnknown = 0,\n  /// Error occurs when the request URL is invalid.\n  GULErrorCodeNetworkInvalidURL = 1,\n  /// Error occurs when request cannot be constructed.\n  GULErrorCodeNetworkRequestCreation = 2,\n  /// Error occurs when payload cannot be compressed.\n  GULErrorCodeNetworkPayloadCompression = 3,\n  /// Error occurs when session task cannot be created.\n  GULErrorCodeNetworkSessionTaskCreation = 4,\n  /// Error occurs when there is no response.\n  GULErrorCodeNetworkInvalidResponse = 5\n};\n\n#pragma mark - Network constants\n\n/// The prefix of the ID of the background session.\nextern NSString *const kGULNetworkBackgroundSessionConfigIDPrefix;\n\n/// The sub directory to store the files of data that is being uploaded in the background.\nextern NSString *const kGULNetworkApplicationSupportSubdirectory;\n\n/// Name of the temporary directory that stores files for background uploading.\nextern NSString *const kGULNetworkTempDirectoryName;\n\n/// The period when the temporary uploading file can stay.\nextern const NSTimeInterval kGULNetworkTempFolderExpireTime;\n\n/// The default network request timeout interval.\nextern const NSTimeInterval kGULNetworkTimeOutInterval;\n\n/// The host to check the reachability of the network.\nextern NSString *const kGULNetworkReachabilityHost;\n\n/// The key to get the error context of the UserInfo.\nextern NSString *const kGULNetworkErrorContext;\n\n#pragma mark - Network Status Code\n\nextern const int kGULNetworkHTTPStatusOK;\nextern const int kGULNetworkHTTPStatusNoContent;\nextern const int kGULNetworkHTTPStatusCodeMultipleChoices;\nextern const int kGULNetworkHTTPStatusCodeMovedPermanently;\nextern const int kGULNetworkHTTPStatusCodeFound;\nextern const int kGULNetworkHTTPStatusCodeNotModified;\nextern const int kGULNetworkHTTPStatusCodeMovedTemporarily;\nextern const int kGULNetworkHTTPStatusCodeNotFound;\nextern const int kGULNetworkHTTPStatusCodeCannotAcceptTraffic;\nextern const int kGULNetworkHTTPStatusCodeUnavailable;\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULNetworkMessageCode.h\"\n\n/// The log levels used by GULNetworkLogger.\ntypedef NS_ENUM(NSInteger, GULNetworkLogLevel) {\n  kGULNetworkLogLevelError = 3,\n  kGULNetworkLogLevelWarning = 4,\n  kGULNetworkLogLevelInfo = 6,\n  kGULNetworkLogLevelDebug = 7,\n};\n\n@protocol GULNetworkLoggerDelegate <NSObject>\n\n@required\n/// Tells the delegate to log a message with an array of contexts and the log level.\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message\n                       contexts:(NSArray *)contexts;\n\n/// Tells the delegate to log a message with a context and the log level.\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message\n                        context:(id)context;\n\n/// Tells the delegate to log a message with the log level.\n- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel\n                    messageCode:(GULNetworkMessageCode)messageCode\n                        message:(NSString *)message;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum.\ntypedef NS_ENUM(NSInteger, GULNetworkMessageCode) {\n  // GULNetwork.m\n  kGULNetworkMessageCodeNetwork000 = 900000,  // I-NET900000\n  kGULNetworkMessageCodeNetwork001 = 900001,  // I-NET900001\n  kGULNetworkMessageCodeNetwork002 = 900002,  // I-NET900002\n  kGULNetworkMessageCodeNetwork003 = 900003,  // I-NET900003\n  // GULNetworkURLSession.m\n  kGULNetworkMessageCodeURLSession000 = 901000,  // I-NET901000\n  kGULNetworkMessageCodeURLSession001 = 901001,  // I-NET901001\n  kGULNetworkMessageCodeURLSession002 = 901002,  // I-NET901002\n  kGULNetworkMessageCodeURLSession003 = 901003,  // I-NET901003\n  kGULNetworkMessageCodeURLSession004 = 901004,  // I-NET901004\n  kGULNetworkMessageCodeURLSession005 = 901005,  // I-NET901005\n  kGULNetworkMessageCodeURLSession006 = 901006,  // I-NET901006\n  kGULNetworkMessageCodeURLSession007 = 901007,  // I-NET901007\n  kGULNetworkMessageCodeURLSession008 = 901008,  // I-NET901008\n  kGULNetworkMessageCodeURLSession009 = 901009,  // I-NET901009\n  kGULNetworkMessageCodeURLSession010 = 901010,  // I-NET901010\n  kGULNetworkMessageCodeURLSession011 = 901011,  // I-NET901011\n  kGULNetworkMessageCodeURLSession012 = 901012,  // I-NET901012\n  kGULNetworkMessageCodeURLSession013 = 901013,  // I-NET901013\n  kGULNetworkMessageCodeURLSession014 = 901014,  // I-NET901014\n  kGULNetworkMessageCodeURLSession015 = 901015,  // I-NET901015\n  kGULNetworkMessageCodeURLSession016 = 901016,  // I-NET901016\n  kGULNetworkMessageCodeURLSession017 = 901017,  // I-NET901017\n  kGULNetworkMessageCodeURLSession018 = 901018,  // I-NET901018\n  kGULNetworkMessageCodeURLSession019 = 901019,  // I-NET901019\n};\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"GULNetworkLoggerProtocol.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef void (^GULNetworkCompletionHandler)(NSHTTPURLResponse *_Nullable response,\n                                            NSData *_Nullable data,\n                                            NSError *_Nullable error);\ntypedef void (^GULNetworkURLSessionCompletionHandler)(NSHTTPURLResponse *_Nullable response,\n                                                      NSData *_Nullable data,\n                                                      NSString *sessionID,\n                                                      NSError *_Nullable error);\ntypedef void (^GULNetworkSystemCompletionHandler)(void);\n\n/// The protocol that uses NSURLSession for iOS >= 7.0 to handle requests and responses.\n@interface GULNetworkURLSession : NSObject\n\n/// Indicates whether the background network is enabled. Default value is NO.\n@property(nonatomic, getter=isBackgroundNetworkEnabled) BOOL backgroundNetworkEnabled;\n\n/// The logger delegate to log message, errors or warnings that occur during the network operations.\n@property(nonatomic, weak, nullable) id<GULNetworkLoggerDelegate> loggerDelegate;\n\n/// Calls the system provided completion handler after the background session is finished.\n+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID\n                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler;\n\n/// Initializes with logger delegate.\n- (instancetype)initWithNetworkLoggerDelegate:\n    (nullable id<GULNetworkLoggerDelegate>)networkLoggerDelegate NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/// Sends an asynchronous POST request and calls the provided completion handler when the request\n/// completes or when errors occur, and returns an ID of the session/connection.\n- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request\n                                   completionHandler:(GULNetworkURLSessionCompletionHandler)handler;\n\n/// Sends an asynchronous GET request and calls the provided completion handler when the request\n/// completes or when errors occur, and returns an ID of the session.\n- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request\n                                  completionHandler:(GULNetworkURLSessionCompletionHandler)handler;\n\nNS_ASSUME_NONNULL_END\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import \"GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h\"\n\n#if !TARGET_OS_WATCH\ntypedef SCNetworkReachabilityRef (*GULReachabilityCreateWithNameFn)(CFAllocatorRef allocator,\n                                                                    const char *host);\n\ntypedef Boolean (*GULReachabilitySetCallbackFn)(SCNetworkReachabilityRef target,\n                                                SCNetworkReachabilityCallBack callback,\n                                                SCNetworkReachabilityContext *context);\ntypedef Boolean (*GULReachabilityScheduleWithRunLoopFn)(SCNetworkReachabilityRef target,\n                                                        CFRunLoopRef runLoop,\n                                                        CFStringRef runLoopMode);\ntypedef Boolean (*GULReachabilityUnscheduleFromRunLoopFn)(SCNetworkReachabilityRef target,\n                                                          CFRunLoopRef runLoop,\n                                                          CFStringRef runLoopMode);\n\ntypedef void (*GULReachabilityReleaseFn)(CFTypeRef cf);\n\nstruct GULReachabilityApi {\n  GULReachabilityCreateWithNameFn createWithNameFn;\n  GULReachabilitySetCallbackFn setCallbackFn;\n  GULReachabilityScheduleWithRunLoopFn scheduleWithRunLoopFn;\n  GULReachabilityUnscheduleFromRunLoopFn unscheduleFromRunLoopFn;\n  GULReachabilityReleaseFn releaseFn;\n};\n#endif\n@interface GULReachabilityChecker (Internal)\n\n- (const struct GULReachabilityApi *)reachabilityApi;\n- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m",
    "content": "// Copyright 2017 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\n#import \"GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h\"\n\n#import \"GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h\"\n#import \"GoogleUtilities/Reachability/GULReachabilityMessageCode.h\"\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\nstatic GULLoggerService kGULLoggerReachability = @\"[GULReachability]\";\n#if !TARGET_OS_WATCH\nstatic void ReachabilityCallback(SCNetworkReachabilityRef reachability,\n                                 SCNetworkReachabilityFlags flags,\n                                 void *info);\n\nstatic const struct GULReachabilityApi kGULDefaultReachabilityApi = {\n    SCNetworkReachabilityCreateWithName,\n    SCNetworkReachabilitySetCallback,\n    SCNetworkReachabilityScheduleWithRunLoop,\n    SCNetworkReachabilityUnscheduleFromRunLoop,\n    CFRelease,\n};\n\nstatic NSString *const kGULReachabilityUnknownStatus = @\"Unknown\";\nstatic NSString *const kGULReachabilityConnectedStatus = @\"Connected\";\nstatic NSString *const kGULReachabilityDisconnectedStatus = @\"Disconnected\";\n#endif\n@interface GULReachabilityChecker ()\n\n@property(nonatomic, assign) const struct GULReachabilityApi *reachabilityApi;\n@property(nonatomic, assign) GULReachabilityStatus reachabilityStatus;\n@property(nonatomic, copy) NSString *host;\n#if !TARGET_OS_WATCH\n@property(nonatomic, assign) SCNetworkReachabilityRef reachability;\n#endif\n\n@end\n\n@implementation GULReachabilityChecker\n\n@synthesize reachabilityApi = reachabilityApi_;\n#if !TARGET_OS_WATCH\n@synthesize reachability = reachability_;\n#endif\n\n- (const struct GULReachabilityApi *)reachabilityApi {\n  return reachabilityApi_;\n}\n\n- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi {\n#if !TARGET_OS_WATCH\n  if (reachability_) {\n    GULLogError(kGULLoggerReachability, NO,\n                [NSString stringWithFormat:@\"I-REA%06ld\", (long)kGULReachabilityMessageCode000],\n                @\"Cannot change reachability API while reachability is running. \"\n                @\"Call stop first.\");\n    return;\n  }\n  reachabilityApi_ = reachabilityApi;\n#endif\n}\n\n@synthesize reachabilityStatus = reachabilityStatus_;\n@synthesize host = host_;\n@synthesize reachabilityDelegate = reachabilityDelegate_;\n\n- (BOOL)isActive {\n#if !TARGET_OS_WATCH\n  return reachability_ != nil;\n#else\n  return NO;\n#endif\n}\n\n- (void)setReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate {\n  if (reachabilityDelegate &&\n      (![(NSObject *)reachabilityDelegate conformsToProtocol:@protocol(GULReachabilityDelegate)])) {\n    GULLogError(kGULLoggerReachability, NO,\n                [NSString stringWithFormat:@\"I-NET%06ld\", (long)kGULReachabilityMessageCode005],\n                @\"Reachability delegate doesn't conform to Reachability protocol.\");\n    return;\n  }\n  reachabilityDelegate_ = reachabilityDelegate;\n}\n\n- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate\n                                    withHost:(NSString *)host {\n  self = [super init];\n\n  if (!host || !host.length) {\n    GULLogError(kGULLoggerReachability, NO,\n                [NSString stringWithFormat:@\"I-REA%06ld\", (long)kGULReachabilityMessageCode001],\n                @\"Invalid host specified\");\n    return nil;\n  }\n  if (self) {\n#if !TARGET_OS_WATCH\n    [self setReachabilityDelegate:reachabilityDelegate];\n    reachabilityApi_ = &kGULDefaultReachabilityApi;\n    reachabilityStatus_ = kGULReachabilityUnknown;\n    host_ = [host copy];\n    reachability_ = nil;\n#endif\n  }\n  return self;\n}\n\n- (void)dealloc {\n  reachabilityDelegate_ = nil;\n  [self stop];\n}\n\n- (BOOL)start {\n#if TARGET_OS_WATCH\n  return NO;\n#else\n\n  if (!reachability_) {\n    reachability_ = reachabilityApi_->createWithNameFn(kCFAllocatorDefault, [host_ UTF8String]);\n    if (!reachability_) {\n      return NO;\n    }\n    SCNetworkReachabilityContext context = {\n        0,                       /* version */\n        (__bridge void *)(self), /* info (passed as last parameter to reachability callback) */\n        NULL,                    /* retain */\n        NULL,                    /* release */\n        NULL                     /* copyDescription */\n    };\n    if (!reachabilityApi_->setCallbackFn(reachability_, ReachabilityCallback, &context) ||\n        !reachabilityApi_->scheduleWithRunLoopFn(reachability_, CFRunLoopGetMain(),\n                                                 kCFRunLoopCommonModes)) {\n      reachabilityApi_->releaseFn(reachability_);\n      reachability_ = nil;\n\n      GULLogError(kGULLoggerReachability, NO,\n                  [NSString stringWithFormat:@\"I-REA%06ld\", (long)kGULReachabilityMessageCode002],\n                  @\"Failed to start reachability handle\");\n      return NO;\n    }\n  }\n  GULLogDebug(kGULLoggerReachability, NO,\n              [NSString stringWithFormat:@\"I-REA%06ld\", (long)kGULReachabilityMessageCode003],\n              @\"Monitoring the network status\");\n  return YES;\n#endif\n}\n\n- (void)stop {\n#if !TARGET_OS_WATCH\n  if (reachability_) {\n    reachabilityStatus_ = kGULReachabilityUnknown;\n    reachabilityApi_->unscheduleFromRunLoopFn(reachability_, CFRunLoopGetMain(),\n                                              kCFRunLoopCommonModes);\n    reachabilityApi_->releaseFn(reachability_);\n    reachability_ = nil;\n  }\n#endif\n}\n\n#if !TARGET_OS_WATCH\n- (GULReachabilityStatus)statusForFlags:(SCNetworkReachabilityFlags)flags {\n  GULReachabilityStatus status = kGULReachabilityNotReachable;\n  // If the Reachable flag is not set, we definitely don't have connectivity.\n  if (flags & kSCNetworkReachabilityFlagsReachable) {\n    // Reachable flag is set. Check further flags.\n    if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired)) {\n// Connection required flag is not set, so we have connectivity.\n#if TARGET_OS_IOS || TARGET_OS_TV\n      status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular\n                                                           : kGULReachabilityViaWifi;\n#elif TARGET_OS_OSX\n      status = kGULReachabilityViaWifi;\n#endif\n    } else if ((flags & (kSCNetworkReachabilityFlagsConnectionOnDemand |\n                         kSCNetworkReachabilityFlagsConnectionOnTraffic)) &&\n               !(flags & kSCNetworkReachabilityFlagsInterventionRequired)) {\n// If the connection on demand or connection on traffic flag is set, and user intervention\n// is not required, we have connectivity.\n#if TARGET_OS_IOS || TARGET_OS_TV\n      status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular\n                                                           : kGULReachabilityViaWifi;\n#elif TARGET_OS_OSX\n      status = kGULReachabilityViaWifi;\n#endif\n    }\n  }\n  return status;\n}\n\n- (void)reachabilityFlagsChanged:(SCNetworkReachabilityFlags)flags {\n  GULReachabilityStatus status = [self statusForFlags:flags];\n  if (reachabilityStatus_ != status) {\n    NSString *reachabilityStatusString;\n    if (status == kGULReachabilityUnknown) {\n      reachabilityStatusString = kGULReachabilityUnknownStatus;\n    } else {\n      reachabilityStatusString = (status == kGULReachabilityNotReachable)\n                                     ? kGULReachabilityDisconnectedStatus\n                                     : kGULReachabilityConnectedStatus;\n    }\n\n    GULLogDebug(kGULLoggerReachability, NO,\n                [NSString stringWithFormat:@\"I-REA%06ld\", (long)kGULReachabilityMessageCode004],\n                @\"Network status has changed. Code:%@, status:%@\", @(status),\n                reachabilityStatusString);\n    reachabilityStatus_ = status;\n    [reachabilityDelegate_ reachability:self statusChanged:reachabilityStatus_];\n  }\n}\n\n#endif\n@end\n\n#if !TARGET_OS_WATCH\nstatic void ReachabilityCallback(SCNetworkReachabilityRef reachability,\n                                 SCNetworkReachabilityFlags flags,\n                                 void *info) {\n  GULReachabilityChecker *checker = (__bridge GULReachabilityChecker *)info;\n  [checker reachabilityFlagsChanged:flags];\n}\n#endif\n\n// This function used to be at the top of the file, but it was moved here\n// as a workaround for a suspected compiler bug. When compiled in Release mode\n// and run on an iOS device with WiFi disabled, the reachability code crashed\n// when calling SCNetworkReachabilityScheduleWithRunLoop, or shortly thereafter.\n// After unsuccessfully trying to diagnose the cause of the crash, it was\n// discovered that moving this function to the end of the file magically fixed\n// the crash. If you are going to edit this file, exercise caution and make sure\n// to test thoroughly with an iOS device under various network conditions.\nconst NSString *GULReachabilityStatusString(GULReachabilityStatus status) {\n  switch (status) {\n    case kGULReachabilityUnknown:\n      return @\"Reachability Unknown\";\n\n    case kGULReachabilityNotReachable:\n      return @\"Not reachable\";\n\n    case kGULReachabilityViaWifi:\n      return @\"Reachable via Wifi\";\n\n    case kGULReachabilityViaCellular:\n      return @\"Reachable via Cellular Data\";\n\n    default:\n      return [NSString stringWithFormat:@\"Invalid reachability status %d\", (int)status];\n  }\n}\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityMessageCode.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\n// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum.\ntypedef NS_ENUM(NSInteger, GULReachabilityMessageCode) {\n  // GULReachabilityChecker.m\n  kGULReachabilityMessageCode000 = 902000,  // I-NET902000\n  kGULReachabilityMessageCode001 = 902001,  // I-NET902001\n  kGULReachabilityMessageCode002 = 902002,  // I-NET902002\n  kGULReachabilityMessageCode003 = 902003,  // I-NET902003\n  kGULReachabilityMessageCode004 = 902004,  // I-NET902004\n  kGULReachabilityMessageCode005 = 902005,  // I-NET902005\n  kGULReachabilityMessageCode006 = 902006,  // I-NET902006\n};\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h",
    "content": "/*\n * Copyright 2017 Google\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n#if !TARGET_OS_WATCH\n#import <SystemConfiguration/SystemConfiguration.h>\n#endif\n\n/// Reachability Status\ntypedef enum {\n  kGULReachabilityUnknown,  ///< Have not yet checked or been notified whether host is reachable.\n  kGULReachabilityNotReachable,  ///< Host is not reachable.\n  kGULReachabilityViaWifi,       ///< Host is reachable via Wifi.\n  kGULReachabilityViaCellular,   ///< Host is reachable via cellular.\n} GULReachabilityStatus;\n\nconst NSString *GULReachabilityStatusString(GULReachabilityStatus status);\n\n@class GULReachabilityChecker;\n\n/// Google Analytics iOS Reachability Checker.\n@protocol GULReachabilityDelegate\n@required\n/// Called when network status has changed.\n- (void)reachability:(GULReachabilityChecker *)reachability\n       statusChanged:(GULReachabilityStatus)status;\n@end\n\n/// Google Analytics iOS Network Status Checker.\n@interface GULReachabilityChecker : NSObject\n\n/// The last known reachability status, or GULReachabilityStatusUnknown if the\n/// checker is not active.\n@property(nonatomic, readonly) GULReachabilityStatus reachabilityStatus;\n/// The host to which reachability status is to be checked.\n@property(nonatomic, copy, readonly) NSString *host;\n/// The delegate to be notified of reachability status changes.\n@property(nonatomic, weak) id<GULReachabilityDelegate> reachabilityDelegate;\n/// `YES` if the reachability checker is active, `NO` otherwise.\n@property(nonatomic, readonly) BOOL isActive;\n\n/// Initialize the reachability checker. Note that you must call start to begin checking for and\n/// receiving notifications about network status changes.\n///\n/// @param reachabilityDelegate The delegate to be notified when reachability status to host\n/// changes.\n///\n/// @param host The name of the host.\n///\n- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate\n                                    withHost:(NSString *)host;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/// Start checking for reachability to the specified host. This has no effect if the status\n/// checker is already checking for connectivity.\n///\n/// @return `YES` if initiating status checking was successful or the status checking has already\n/// been initiated, `NO` otherwise.\n- (BOOL)start;\n\n/// Stop checking for reachability to the specified host. This has no effect if the status\n/// checker is not checking for connectivity.\n- (void)stop;\n\n@end\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m",
    "content": "// Copyright 2018 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h\"\n\n#import \"GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nstatic NSTimeInterval const kGULSynchronizeInterval = 1.0;\n\nstatic NSString *const kGULLogFormat = @\"I-GUL%06ld\";\n\nstatic GULLoggerService kGULLogUserDefaultsService = @\"[GoogleUtilities/UserDefaults]\";\n\ntypedef NS_ENUM(NSInteger, GULUDMessageCode) {\n  GULUDMessageCodeInvalidKeyGet = 1,\n  GULUDMessageCodeInvalidKeySet = 2,\n  GULUDMessageCodeInvalidObjectSet = 3,\n  GULUDMessageCodeSynchronizeFailed = 4,\n};\n\n@interface GULUserDefaults ()\n\n/// Equivalent to the suite name for NSUserDefaults.\n@property(readonly) CFStringRef appNameRef;\n\n@property(atomic) BOOL isPreferenceFileExcluded;\n\n@end\n\n@implementation GULUserDefaults {\n  // The application name is the same with the suite name of the NSUserDefaults, and it is used for\n  // preferences.\n  CFStringRef _appNameRef;\n}\n\n+ (GULUserDefaults *)standardUserDefaults {\n  static GULUserDefaults *standardUserDefaults;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    standardUserDefaults = [[GULUserDefaults alloc] init];\n  });\n  return standardUserDefaults;\n}\n\n- (instancetype)init {\n  return [self initWithSuiteName:nil];\n}\n\n- (instancetype)initWithSuiteName:(nullable NSString *)suiteName {\n  self = [super init];\n\n  NSString *name = [suiteName copy];\n\n  if (self) {\n    // `kCFPreferencesCurrentApplication` maps to the same defaults database as\n    // `[NSUserDefaults standardUserDefaults]`.\n    _appNameRef =\n        name.length ? (__bridge_retained CFStringRef)name : kCFPreferencesCurrentApplication;\n  }\n\n  return self;\n}\n\n- (void)dealloc {\n  // If we're using a custom `_appNameRef` it needs to be released. If it's a constant, it shouldn't\n  // need to be released since we don't own it.\n  if (CFStringCompare(_appNameRef, kCFPreferencesCurrentApplication, 0) != kCFCompareEqualTo) {\n    CFRelease(_appNameRef);\n  }\n\n  [NSObject cancelPreviousPerformRequestsWithTarget:self\n                                           selector:@selector(synchronize)\n                                             object:nil];\n}\n\n- (nullable id)objectForKey:(NSString *)defaultName {\n  NSString *key = [defaultName copy];\n  if (![key isKindOfClass:[NSString class]] || !key.length) {\n    GULLogWarning(@\"<GoogleUtilities>\", NO,\n                  [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet],\n                  @\"Cannot get object for invalid user default key.\");\n    return nil;\n  }\n  return (__bridge_transfer id)CFPreferencesCopyAppValue((__bridge CFStringRef)key, _appNameRef);\n}\n\n- (void)setObject:(nullable id)value forKey:(NSString *)defaultName {\n  NSString *key = [defaultName copy];\n  if (![key isKindOfClass:[NSString class]] || !key.length) {\n    GULLogWarning(kGULLogUserDefaultsService, NO,\n                  [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeySet],\n                  @\"Cannot set object for invalid user default key.\");\n    return;\n  }\n  if (!value) {\n    CFPreferencesSetAppValue((__bridge CFStringRef)key, NULL, _appNameRef);\n    [self scheduleSynchronize];\n    return;\n  }\n  BOOL isAcceptableValue =\n      [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] ||\n      [value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]] ||\n      [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSData class]];\n  if (!isAcceptableValue) {\n    GULLogWarning(kGULLogUserDefaultsService, NO,\n                  [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidObjectSet],\n                  @\"Cannot set invalid object to user defaults. Must be a string, number, array, \"\n                  @\"dictionary, date, or data. Value: %@\",\n                  value);\n    return;\n  }\n\n  CFPreferencesSetAppValue((__bridge CFStringRef)key, (__bridge CFStringRef)value, _appNameRef);\n  [self scheduleSynchronize];\n}\n\n- (void)removeObjectForKey:(NSString *)key {\n  [self setObject:nil forKey:key];\n}\n\n#pragma mark - Getters\n\n- (NSInteger)integerForKey:(NSString *)defaultName {\n  NSNumber *object = [self objectForKey:defaultName];\n  return object.integerValue;\n}\n\n- (float)floatForKey:(NSString *)defaultName {\n  NSNumber *object = [self objectForKey:defaultName];\n  return object.floatValue;\n}\n\n- (double)doubleForKey:(NSString *)defaultName {\n  NSNumber *object = [self objectForKey:defaultName];\n  return object.doubleValue;\n}\n\n- (BOOL)boolForKey:(NSString *)defaultName {\n  NSNumber *object = [self objectForKey:defaultName];\n  return object.boolValue;\n}\n\n- (nullable NSString *)stringForKey:(NSString *)defaultName {\n  return [self objectForKey:defaultName];\n}\n\n- (nullable NSArray *)arrayForKey:(NSString *)defaultName {\n  return [self objectForKey:defaultName];\n}\n\n- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName {\n  return [self objectForKey:defaultName];\n}\n\n#pragma mark - Setters\n\n- (void)setInteger:(NSInteger)integer forKey:(NSString *)defaultName {\n  [self setObject:@(integer) forKey:defaultName];\n}\n\n- (void)setFloat:(float)value forKey:(NSString *)defaultName {\n  [self setObject:@(value) forKey:defaultName];\n}\n\n- (void)setDouble:(double)doubleNumber forKey:(NSString *)defaultName {\n  [self setObject:@(doubleNumber) forKey:defaultName];\n}\n\n- (void)setBool:(BOOL)boolValue forKey:(NSString *)defaultName {\n  [self setObject:@(boolValue) forKey:defaultName];\n}\n\n#pragma mark - Save data\n\n- (void)synchronize {\n  if (!CFPreferencesAppSynchronize(_appNameRef)) {\n    GULLogError(kGULLogUserDefaultsService, NO,\n                [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeSynchronizeFailed],\n                @\"Cannot synchronize user defaults to disk\");\n  }\n}\n\n#pragma mark - Private methods\n\n- (void)scheduleSynchronize {\n  // Synchronize data using a timer so that multiple set... calls can be coalesced under one\n  // synchronize.\n  [NSObject cancelPreviousPerformRequestsWithTarget:self\n                                           selector:@selector(synchronize)\n                                             object:nil];\n  // This method may be called on multiple queues (due to set... methods can be called on any queue)\n  // synchronize can be scheduled on different queues, so make sure that it does not crash. If this\n  // instance goes away, self will be released also, no one will retain it and the schedule won't be\n  // called.\n  [self performSelector:@selector(synchronize) withObject:nil afterDelay:kGULSynchronizeInterval];\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h",
    "content": "// Copyright 2018 Google\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A thread-safe user defaults that uses C functions from CFPreferences.h instead of\n/// `NSUserDefaults`. This is to avoid sending an `NSNotification` when it's changed from a\n/// background thread to avoid crashing. // TODO: Insert radar number here.\n@interface GULUserDefaults : NSObject\n\n/// A shared user defaults similar to +[NSUserDefaults standardUserDefaults] and accesses the same\n/// data of the standardUserDefaults.\n+ (GULUserDefaults *)standardUserDefaults;\n\n/// Initializes preferences with a suite name that is the same with the NSUserDefaults' suite name.\n/// Both of CFPreferences and NSUserDefaults share the same plist file so their data will exactly\n/// the same.\n///\n/// @param suiteName The name of the suite of the user defaults.\n- (instancetype)initWithSuiteName:(nullable NSString *)suiteName;\n\n#pragma mark - Getters\n\n/// Searches the receiver's search list for a default with the key 'defaultName' and return it. If\n/// another process has changed defaults in the search list, NSUserDefaults will automatically\n/// update to the latest values. If the key in question has been marked as ubiquitous via a Defaults\n/// Configuration File, the latest value may not be immediately available, and the registered value\n/// will be returned instead.\n- (nullable id)objectForKey:(NSString *)defaultName;\n\n/// Equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray.\n- (nullable NSArray *)arrayForKey:(NSString *)defaultName;\n\n/// Equivalent to -objectForKey:, except that it will return nil if the value\n/// is not an NSDictionary.\n- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName;\n\n/// Equivalent to -objectForKey:, except that it will convert NSNumber values to their NSString\n/// representation. If a non-string non-number value is found, nil will be returned.\n- (nullable NSString *)stringForKey:(NSString *)defaultName;\n\n/// Equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the\n/// value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString,\n/// it will be converted to NSInteger if possible. If the value is a boolean, it will be converted\n/// to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0\n/// will be returned.\n- (NSInteger)integerForKey:(NSString *)defaultName;\n\n/// Similar to -integerForKey:, except that it returns a float, and boolean values will not be\n/// converted.\n- (float)floatForKey:(NSString *)defaultName;\n\n/// Similar to -integerForKey:, except that it returns a double, and boolean values will not be\n/// converted.\n- (double)doubleForKey:(NSString *)defaultName;\n\n/// Equivalent to -objectForKey:, except that it converts the returned value to a BOOL. If the value\n/// is an NSNumber, NO will be returned if the value is 0, YES otherwise. If the value is an\n/// NSString, values of \"YES\" or \"1\" will return YES, and values of \"NO\", \"0\", or any other string\n/// will return NO. If the value is absent or can't be converted to a BOOL, NO will be returned.\n- (BOOL)boolForKey:(NSString *)defaultName;\n\n#pragma mark - Setters\n\n/// Immediately stores a value (or removes the value if `nil` is passed as the value) for the\n/// provided key in the search list entry for the receiver's suite name in the current user and any\n/// host, then asynchronously stores the value persistently, where it is made available to other\n/// processes.\n- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;\n\n/// Equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber.\n- (void)setFloat:(float)value forKey:(NSString *)defaultName;\n\n/// Equivalent to -setObject:forKey: except that the value is converted from a double to an\n/// NSNumber.\n- (void)setDouble:(double)value forKey:(NSString *)defaultName;\n\n/// Equivalent to -setObject:forKey: except that the value is converted from an NSInteger to an\n/// NSNumber.\n- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;\n\n/// Equivalent to -setObject:forKey: except that the value is converted from a BOOL to an NSNumber.\n- (void)setBool:(BOOL)value forKey:(NSString *)defaultName;\n\n#pragma mark - Removing Defaults\n\n/// Equivalent to -[... setObject:nil forKey:defaultName]\n- (void)removeObjectForKey:(NSString *)defaultName;\n\n#pragma mark - Save data\n\n/// Blocks the calling thread until all in-progress set operations have completed.\n- (void)synchronize;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/GoogleUtilities/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n================================================================================\n\nThe following copyright from Landon J. Fuller applies to the isAppEncrypted\nfunction in Environment/third_party/GULAppEnvironmentUtil.m.\n\nCopyright (c) 2017 Landon J. Fuller <landon@landonf.org>\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nComment from\n<a href=\"http://iphonedevwiki.net/index.php/Crack_prevention\">iPhone Dev Wiki\nCrack Prevention</a>: App Store binaries are signed by both their developer\nand Apple. This encrypts the binary so that decryption keys are needed in order\nto make the binary readable. When iOS executes the binary, the decryption keys\nare used to decrypt the binary into a readable state where it is then loaded\ninto memory and executed. iOS can tell the encryption status of a binary via the\ncryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is\na non-zero value then the binary is encrypted.\n\n'Cracking' works by letting the kernel decrypt the binary then siphoning the\ndecrypted data into a new binary file, resigning, and repackaging. This will\nonly work on jailbroken devices as codesignature validation has been removed.\nResigning takes place because while the codesignature doesn't have to be valid\nthanks to the jailbreak, it does have to be in place unless you have AppSync or\nsimilar to disable codesignature checks.\n\nMore information at <a href=\"http://landonf.org/2009/02/index.html\">Landon\nFuller's blog</a>\n"
  },
  {
    "path": "Pods/GoogleUtilities/README.md",
    "content": "[![Version](https://img.shields.io/cocoapods/v/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities)\n[![License](https://img.shields.io/cocoapods/l/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities)\n[![Platform](https://img.shields.io/cocoapods/p/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities)\n\n[![Actions Status][gh-google-utilities-badge]][gh-actions]\n\n# GoogleUtilities\n\nGoogleUtilities provides a set of utilities for Firebase and other Google SDKs for Apple platform\ndevelopment.\n\nThe utilities are not directly supported for non-Google library usage.\n\n## Integration Testing\nThese instructions apply to minor and patch version updates. Major versions need\na customized adaptation.\n\nAfter the CI is green:\n* Determine the next version for release by checking the\n  [tagged releases](https://github.com/google/GoogleUtilities/tags).\n  Ensure that the next release version keeps the Swift PM and CocoaPods versions in sync.\n* Verify that the releasing version is the latest entry in the [CHANGELOG.md](CHANGELOG.md),\n  updating it if necessary.\n* Update the version in the podspec to match the latest entry in the [CHANGELOG.md](CHANGELOG.md)\n* Checkout the `main` branch and ensure it is up to date\n  ```console\n  git checkout main\n  git pull\n  ```\n* Add the CocoaPods tag (`{version}` will be the latest version in the [podspec](GoogleUtilities.podspec#L3))\n  ```console\n  git tag CocoaPods-{version}\n  git push origin CocoaPods-{version}\n  ```\n* Push the podspec to the designated repo\n  * If this version of GoogleUtilities is intended to launch **before or with** the next Firebase release:\n    <details>\n    <summary>Push to <b>SpecsStaging</b></summary>\n\n    ```console\n    pod repo push --skip-tests staging GoogleUtilities.podspec\n    ```\n\n    If the command fails with `Unable to find the 'staging' repo.`, add the staging repo with:\n    ```console\n    pod repo add staging git@github.com:firebase/SpecsStaging.git\n    ```\n    </details>\n  * Otherwise:\n    <details>\n    <summary>Push to <b>SpecsDev</b></summary>\n\n    ```console\n    pod repo push --skip-tests dev GoogleUtilities.podspec\n    ```\n\n    If the command fails with `Unable to find the 'dev' repo.`, add the dev repo with:\n    ```console\n    pod repo add dev git@github.com:firebase/SpecsDev.git\n    ```\n    </details>\n* Run Firebase CI by waiting until next nightly or adding a PR that touches `Gemfile`.\n* On google3, run copybara using the command below. Then, start a global TAP on the generated CL. Deflake as needed.\n  ```console\n  third_party/firebase/ios/Releases/run_copy_bara.py --directory GoogleUtilities --branch main\n  ```\n\n## Publishing\nThe release process is as follows:\n1. [Tag and release for Swift PM](#swift-package-manager)\n2. [Publish to CocoaPods](#cocoapods)\n3. [Create GitHub Release](#create-github-release)\n4. [Perform post release cleanup](#post-release-cleanup)\n\n### Swift Package Manager\n  By creating and [pushing a tag](https://github.com/google/GoogleUtilities/tags)\n  for Swift PM, the newly tagged version will be immediately released for public use.\n  Given this, please verify the intended time of release for Swift PM.\n  * Add a version tag for Swift PM\n  ```console\n  git tag {version}\n  git push origin {version}\n  ```\n  *Note: Ensure that any inflight PRs that depend on the new `GoogleUtilities` version are updated to point to the\n  newly tagged version rather than a checksum.*\n\n### CocoaPods\n* Publish the newly versioned pod to CocoaPods\n\n  It's recommended to point to the `GoogleUtilities.podspec` in `staging` to make sure the correct spec is being published.\n  ```console\n  pod trunk push ~/.cocoapods/repos/staging/GoogleUtilities/{version}/GoogleUtilities.podspec\n  ```\n  *Note: In some cases, it may be acceptable to `pod trunk push` with the `--skip-tests` flag. Please double check with\n  the maintainers before doing so.*\n\n  The pod push was successful if the above command logs: `🚀  GoogleUtilities ({version}) successfully published`.\n  In addition, a new commit that publishes the new version (co-authored by [CocoaPodsAtGoogle](https://github.com/CocoaPodsAtGoogle))\n  should appear in the [CocoaPods specs repo](https://github.com/CocoaPods/Specs). Last, the latest version should be displayed\n  on [GoogleUtilities's CocoaPods page](https://cocoapods.org/pods/GoogleUtilities).\n\n### [Create GitHub Release](https://github.com/google/GoogleUtilities/releases/new/)\n  Update the [release template](https://github.com/google/GoogleUtilities/releases/new/)'s **Tag version** and **Release title**\n  fields with the latest version. In addition, reference the [Release Notes](./CHANGELOG.md) in the release's description.\n\n  See [this release](https://github.com/google/GoogleUtilities/releases/edit/9.0.1) for an example.\n\n  *Don't forget to perform the [post release cleanup](#post-release-cleanup)!*\n\n### Post Release Cleanup\n  <details>\n  <summary>Clean up <b>SpecsStaging</b></summary>\n\n  ```console\n  pwd=$(pwd)\n  mkdir -p /tmp/release-cleanup && cd $_\n  git clone git@github.com:firebase/SpecsStaging.git\n  cd SpecsStaging/\n  git rm -rf GoogleUtilities/\n  git commit -m \"Post publish cleanup\"\n  git push origin master\n  rm -rf /tmp/release-cleanup\n  cd $pwd\n  ```\n  </details>\n\n## Development\n\nTo develop in this repository, ensure that you have at least the following software:\n\n  * Xcode 12.0 (or later)\n  * CocoaPods 1.10.0 (or later)\n  * [CocoaPods generate](https://github.com/square/cocoapods-generate)\n\nFor the pod that you want to develop:\n\n`pod gen GoogleUtilities.podspec --local-sources=./ --auto-open --platforms=ios`\n\nNote: If the CocoaPods cache is out of date, you may need to run\n`pod repo update` before the `pod gen` command.\n\nNote: Set the `--platforms` option to `macos` or `tvos` to develop/test for\nthose platforms. Since 10.2, Xcode does not properly handle multi-platform\nCocoaPods workspaces.\n\n### Development for Catalyst\n* `pod gen GoogleUtilities.podspec --local-sources=./ --auto-open --platforms=ios`\n* Check the Mac box in the App-iOS Build Settings\n* Sign the App in the Settings Signing & Capabilities tab\n* Click Pods in the Project Manager\n* Add Signing to the iOS host app and unit test targets\n* Select the Unit-unit scheme\n* Run it to build and test\n\nAlternatively disable signing in each target:\n* Go to Build Settings tab\n* Click `+`\n* Select `Add User-Defined Setting`\n* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO`\n\n### Code Formatting\n\nTo ensure that the code is formatted consistently, run the script\n[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/check.sh)\nbefore creating a PR.\n\nGitHub Actions will verify that any code changes are done in a style compliant\nway. Install `clang-format` and `mint`:\n\n```console\nbrew install clang-format@12\nbrew install mint\n```\n\n### Running Unit Tests\n\nSelect a scheme and press Command-u to build a component and run its unit tests.\n\n## Contributing\n\nSee [Contributing](CONTRIBUTING.md).\n\n## License\n\nThe contents of this repository is licensed under the\n[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\n[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions\n[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXAggregateTarget section */\n\t\t072CEA044D2EF26F03496D5996BBF59F /* Firebase */ = {\n\t\t\tisa = PBXAggregateTarget;\n\t\t\tbuildConfigurationList = C6E4A38F24896DABC7A364E6DB2C7A7F /* Build configuration list for PBXAggregateTarget \"Firebase\" */;\n\t\t\tbuildPhases = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t60B836A00436698D56971C2DF9FACBD3 /* PBXTargetDependency */,\n\t\t\t\t07F7AACA5DCE705327010DA25FBEF165 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = Firebase;\n\t\t};\n\t\tB53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */ = {\n\t\t\tisa = PBXAggregateTarget;\n\t\t\tbuildConfigurationList = B703E077B86E18E406CBE29C0DBD8D5F /* Build configuration list for PBXAggregateTarget \"GoogleAppMeasurement\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCB5AF08085F7665FEB6F74BC117BDB28 /* [CP] Copy XCFrameworks */,\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t7DA3592F4AED73F685BA39AED564AB8C /* PBXTargetDependency */,\n\t\t\t\tD4BF4589DADC31160B77BB8112E61B37 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = GoogleAppMeasurement;\n\t\t};\n\t\tC49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */ = {\n\t\t\tisa = PBXAggregateTarget;\n\t\t\tbuildConfigurationList = 252336D783BCD0B4415B0521B0962F14 /* Build configuration list for PBXAggregateTarget \"FirebaseAnalytics\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t36517C47DEF3A4F55B4079EB176CAC62 /* [CP] Copy XCFrameworks */,\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tE7A21F113AF491DD9E75451709813C86 /* PBXTargetDependency */,\n\t\t\t\t7AFDA11FCD515215D24F9BDC345530D3 /* PBXTargetDependency */,\n\t\t\t\tE57689F1671B9303E2E6FC780D60D89A /* PBXTargetDependency */,\n\t\t\t\t17945370CE1B53AF222677EE98E01A93 /* PBXTargetDependency */,\n\t\t\t\t12F6562F185F60896BBCDADD4019778E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = FirebaseAnalytics;\n\t\t};\n/* End PBXAggregateTarget section */\n\n/* Begin PBXBuildFile section */\n\t\t007F57C0030B0CA201A359FD816A3CE1 /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = F2EC88E51FC34B63E85F84778E9C618A /* SDImageFrame.m */; };\n\t\t0184B6B56F7F8EC2CAA4300B5344B419 /* GULKeychainUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A75B93924C163BDD4BFE27BE82320E0 /* GULKeychainUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t01CB8221A492BC65C076670906A3D08E /* GDTCORReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 87BD1262A5EDC0CE9D84214096454004 /* GDTCORReachability.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t02252699D8D416E0AD793B30C95C4BD6 /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = BD01D4D2C9BD8D230AC07E17D1BC2580 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t0311D5903A8C13AE6158796BC69AD994 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B4DFE57A7C5FC68155C295484A72007 /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t036B849251F9D940A08CE9945DF158D2 /* GDTCORRegistrar.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DB1409CD0C3B140ECAB6006D2DAD8BC /* GDTCORRegistrar.m */; };\n\t\t03860676C8B2758B55FA5C92421B12FC /* FIRConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7055DAE8B926D478FFCB05DC46E7F844 /* FIRConfigurationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t03C3E562593A65D5184DAE4A6DDD883F /* FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C2FEB053783A6171CE3DECCFF936A28 /* FIRApp.m */; };\n\t\t044993D3D534546E1F168C7CABEFD382 /* FIRCurrentDateProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = B17DB1B80794FEE3D7DC12CB3641AB30 /* FIRCurrentDateProvider.m */; };\n\t\t047DCD22E37D894B69D095C8E537819F /* FBLPromise+Then.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 8D85590DB78FA3CE98F5876D319CDC9F /* FBLPromise+Then.h */; };\n\t\t04AA4C56A3620BE2A70364D47CE08AF3 /* FBLPromise+Wrap.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 47F2FC011CE490B793305158ACB2048E /* FBLPromise+Wrap.h */; };\n\t\t05102BD9E7BCB80DC7B64A34D0E7850B /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = EA1C659029357A11E03301278FD8D706 /* SDWebImageCacheSerializer.m */; };\n\t\t05133941F28BBE0615644D0AFEC73AF3 /* FIRInstallationsItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E08253131AF6EBD5597DF21EBF9B98D /* FIRInstallationsItem.m */; };\n\t\t05214C0A74E896C781C8CB7719A9984C /* FBLPromise+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = F0647D92B0FBA5FC4BF6371012FEE181 /* FBLPromise+Testing.h */; };\n\t\t052F793DE768D1EDB5C1EC87A5A21F58 /* FIRDiagnosticsData.m in Sources */ = {isa = PBXBuildFile; fileRef = FEA2BFC7C6DBDD183F3EC0220976D86F /* FIRDiagnosticsData.m */; };\n\t\t05D76FA82DD3C37B76FFC1689CEF9981 /* SDWebImageDownloaderDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 65F9EFAA484830CADC6FE4DE20867D8D /* SDWebImageDownloaderDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t06A3ABB4421B935533DD7D039442ADCF /* GULHeartbeatDateStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = F36DCFF7B72CE2940864E1364072151A /* GULHeartbeatDateStorage.m */; };\n\t\t07A41F67B40B3C6C6C3DB862F1F633F8 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD491CEBE34A4FF9B067D4431A9525D /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t07E6B04D64953307335FF701FF858427 /* FIRInstallationsItem+RegisterInstallationAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = BAB945382DE7BCE1238478DF4341D1C3 /* FIRInstallationsItem+RegisterInstallationAPI.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t0A251DC0DF1E1EE8AC74D44C769312C3 /* GDTCORAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 813CEE72D58D250DD2A09A4157C51303 /* GDTCORAssert.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t0AA4EFD2D280F30CA93FD51643349602 /* uk.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FEE086E4BCB7B965DFED58170011ADD2 /* uk.lproj */; };\n\t\t0B63C55C547C48DEE7EBAE9C9DFD3675 /* GULUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = D69D4E5A3DF64985BBF9D3080CCD6144 /* GULUserDefaults.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t0BFA90EFCD3407716FFC60D140325188 /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = D519F9451A80C810AEF071E0A50F225E /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t0C663893D044728B8050AD706689AA09 /* FIRCoreDiagnosticsInterop.h in Headers */ = {isa = PBXBuildFile; fileRef = D605D91349EBFFC6D84A254293FFF56F /* FIRCoreDiagnosticsInterop.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t0C76BA74E22A5CFD8207C10026401D80 /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 17A959EECDBC8B53DAF62371054DAAE9 /* SDAnimatedImagePlayer.m */; };\n\t\t0C80C3D7BC320914043FB768C88C8587 /* FIRInstallationsStoredItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 9484BA52176E0E66CBDC23122D2948A2 /* FIRInstallationsStoredItem.m */; };\n\t\t0C8BD39D8D79C1A9BEFC904C457DCE89 /* FIRInstallationsAuthTokenResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D54DA10983EF09ABC480187282A87A58 /* FIRInstallationsAuthTokenResult.m */; };\n\t\t0CC10185DD0B362B0934EDE2C557D7E0 /* FIRDependency.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9B5348D8E36B88FD0E3329BCF4479D /* FIRDependency.m */; };\n\t\t0D0AF4DF934B7BE39EC6E287B003BBA6 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = EC28ED48C1E6F76572193AD374027BB7 /* SDMemoryCache.m */; };\n\t\t0D2B3D451D64A5A0AE5CE51E975D7494 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DEBF0EE7331EEAD283D9D6370A2B3FF /* SDImageCache.m */; };\n\t\t0D4FBF072F6431A5D5324C83FC2E5DE7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F030A051DB2F7C17CB74A9C0FBD7B56 /* Security.framework */; };\n\t\t0D7F532169AFF271D684865CF89DA8A7 /* FIRAppAssociationRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBCB878C4026B383CA6687B4DC52D58 /* FIRAppAssociationRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t0DEECB4887F8ED8A8304156D1C440639 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6BFCD79351B8CDEDCAB2DE6EDB89AE /* SDWebImage-dummy.m */; };\n\t\t0F4322740A001E3D7BFD2C333BCF907D /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B66ADF3FBC020B8BAE5E1C0C6EA3C650 /* SDImageCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t0FC35E1D19F49ACD5B5957B86D32D4EA /* FBLPromise+Wrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 47F2FC011CE490B793305158ACB2048E /* FBLPromise+Wrap.h */; };\n\t\t0FFA0C960F26666918569059FB8E92BC /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A88BFB19C447C4ED3DE4168952FE80 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t1058BF78DCB651C56D33B7198AA0D355 /* FirebaseCoreDiagnostics-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 34A40FBEB8C0F4629E017EA065211E5C /* FirebaseCoreDiagnostics-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t10E9E4249C8C22A571EBFECF3C0676CC /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FDCDC0DC5EBD4242B3B44E167355E955 /* UIImageView+WebCache.m */; };\n\t\t116DB4571C6E70C54479C15F140245AE /* GDTCORReachability_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = C1150A7649D44398A5F001918CBE0C16 /* GDTCORReachability_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t11A2D8485890983668BBBDB3BE7602AC /* GoogleUtilities-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 71783D9D8F34A0AB09F92BAF64FC155E /* GoogleUtilities-dummy.m */; };\n\t\t11E79385CD0DA86166E63D21E7E078E9 /* SDImageIOAnimatedCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = BB81C8F74DB13FEF4D842A7A4127FEBF /* SDImageIOAnimatedCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t138DFC533930F784B55D9BB8AACC0E06 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = FF3EF4B23861192F1BF203B7E288A145 /* SDImageCacheDefine.m */; };\n\t\t1471F3BFCD49A1FBD39DA3CD4C3DA8B9 /* FBLPromise+Timeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A93FB313CA659376FAA369092F2D036 /* FBLPromise+Timeout.h */; };\n\t\t14B49802A4BD5C9EB648342B539ACC0E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\t153AB0D2CFAFC43A733B6B2A551FBE76 /* GDTCORTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBC03DFAC32230F28CDE2D8E913A269 /* GDTCORTransformer.m */; };\n\t\t1554350BBDCB525AA477C1F345852437 /* FBLPromise+Do.h in Headers */ = {isa = PBXBuildFile; fileRef = ECF677E408094637A67960F364C6FA0D /* FBLPromise+Do.h */; };\n\t\t164DEB7B33A09DD8663942511488AD16 /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A08E238C0EA041AF882D5F75E6C3C9 /* SDImageGIFCoder.m */; };\n\t\t168AB5EA0EBEB75D0434B55D0B97AD47 /* SDImageIOAnimatedCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A243783F2DB10CD105EA1B585E02DF32 /* SDImageIOAnimatedCoderInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t18191A26B494BB7777A6420722A46B29 /* FBLPromise+Await.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 1F96A93009C7CAECE802F2AF89962662 /* FBLPromise+Await.h */; };\n\t\t18303B692A81A7D708973A6B9CBA75D8 /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0440093C278700F6A5362B45AD5DBC91 /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t19BDF52B1C43F4A0EDAA7FA633B9BA88 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 82AAE98FB8E850A8ECBA43F727AD3F4B /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t1AF4F328009E37FD64DA9CA51CC90932 /* FBLPromise+Do.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = ECF677E408094637A67960F364C6FA0D /* FBLPromise+Do.h */; };\n\t\t1CBE26399B4391159FDD5EF576CA6592 /* FBLPromiseError.h in Headers */ = {isa = PBXBuildFile; fileRef = E76B8095179CC1855E5CFA2FF2597A24 /* FBLPromiseError.h */; };\n\t\t1D635C91D8BC72532AAD16B6C063D7C0 /* FIRInstallationsHTTPError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E3D719558B6C623CB196272CE80D92B /* FIRInstallationsHTTPError.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t1DD6D013806F64DED16DD22BAED3C369 /* FIRFirebaseUserAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = F34C30C677383D5895A28720200014A4 /* FIRFirebaseUserAgent.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t1E1FF13F9AB197201C44EEC0D4E9E9EF /* FBLPromiseError.m in Sources */ = {isa = PBXBuildFile; fileRef = FCA00A91EC23FFE0892B9D0F0B84F617 /* FBLPromiseError.m */; };\n\t\t1E49C6EF4C021764307A50165CAA713A /* sv.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 030D92BA7629B33D7DEDDD755B2FB34B /* sv.lproj */; };\n\t\t20004B99F5050F59E747AB8DFAD7E891 /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 22CACEEBCAA12953A3BA4DB2820EB06A /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t21D05279AA20EE7A1707A76C11BBCC00 /* NSBezierPath+SDRoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFCA2753EDD74C8B7D46CD39BC4F756 /* NSBezierPath+SDRoundedCorners.m */; };\n\t\t22A29883D6BD2C46CFCB90EFE1E6B1B6 /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D2D3BD16668BB31898CA2909AB1211CB /* ja.lproj */; };\n\t\t23490DF877054EEA5F983AD117033631 /* FBLPromise+Await.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F96A93009C7CAECE802F2AF89962662 /* FBLPromise+Await.h */; };\n\t\t23D8684E3F488264A90E5954D59B902C /* GDTCORStorageProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F3BFEC70D8BA82BE6E262B3750543AC /* GDTCORStorageProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t242A43C50C10362A01FA1F662EF7CF2A /* FIRInstallationsStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 33282DA51418F8E945CDA2BC7DDA734E /* FIRInstallationsStatus.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t242C08FFF99332102B7BF8E2590DA079 /* GULLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 82EAA36E76AE8F4E664A68EC8EB36298 /* GULLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t24DA814C2F7EA7C4187E2BF0B6466E9A /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = EB886795A3DF2E63330CE092DB9B5F46 /* SDAnimatedImageRep.m */; };\n\t\t25FE5A4220B051E800D649E94BDCF418 /* FBLPromise+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = 490C3A82D71E20AB4B5BC07D75101D21 /* FBLPromise+Catch.m */; };\n\t\t26BF15D648EFA59FCA18AE285AC5B2A1 /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = 44E9E3AB162F34A2457874535E2D437A /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2711092C95505064BFF763747C805405 /* FirebaseInstallationsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EAF64B24EEF15C83158B0A1B832978D /* FirebaseInstallationsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t2749C745E4CCB505CACD055CAAF7B51A /* GDTCORUploadBatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFBDA1EBD167AFD2083DC8D9D565001 /* GDTCORUploadBatch.m */; };\n\t\t275F99E74511043432C892810081DCAF /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B960865AD112FB963F482E45E567B56 /* SDDiskCache.m */; };\n\t\t276A3E64698148850F514C10F440DDD0 /* FBLPromisePrivate.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 278F2C97E692BBEB7227CFD22EE4333A /* FBLPromisePrivate.h */; };\n\t\t278F5B2C01E923AA0C691D79BD0F321F /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C1F9B1C56AC542B7695BF945F7E8A5A /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2797DBBF0C00C0C9AED6C496F1AA1CB8 /* FBLPromise+Wrap.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BEA3009F10DE79DB402A683F6839FC8 /* FBLPromise+Wrap.m */; };\n\t\t28532908E40E423052AA43B0000028BF /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BC48CD5B43C672FF7213F9BE34110DB /* UIImage+Metadata.m */; };\n\t\t2A43AC77BE9EF6259E27876705069383 /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = C18C4496C07F34201871F99AD27069A0 /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t2A866696A7C9DB4CB42A963DE9551B40 /* FIRInstallationsIIDTokenStore.h in Headers */ = {isa = PBXBuildFile; fileRef = E43C759DC1C3554D8988244726FFB280 /* FIRInstallationsIIDTokenStore.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t2AF06216CDA7D6C38831BB201F73B566 /* FIRInstallationsItem+RegisterInstallationAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D885B6C37485841C093413F8E4B5CE /* FIRInstallationsItem+RegisterInstallationAPI.m */; };\n\t\t2C4D5AB870A681E4EA5340FBD70FA010 /* FirebaseCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E666E3C34AF4E53A131BD4AF0F6ABA47 /* FirebaseCore-dummy.m */; };\n\t\t2C4FBEAF9B8A4CEAF32D5EA477EB6531 /* PromisesObjC-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BF54C90D1DF4DD3950B8DCD5C09D18C /* PromisesObjC-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2C762E5C654B718C19CC98FEB27C2DA4 /* SDFileAttributeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EACF04048B0827BDA828E835A7EA14C6 /* SDFileAttributeHelper.m */; };\n\t\t2CC0D5EBD928AAABF1DB1AE58E8710B3 /* FIRInstallationsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CAFA66ED08EE2214A12519DB72F11801 /* FIRInstallationsLogger.m */; };\n\t\t2D3E6969DF4465FC38E09B23A2562DE2 /* GULReachabilityChecker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6FE3762E8CAD647386716CD1698F48 /* GULReachabilityChecker+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t2D5F3E52A136C35D74B92551B645D588 /* FBLPromise+Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CD99347EC1D85D2C2FDDB3D1F9DF393 /* FBLPromise+Validate.h */; };\n\t\t2D7E7D5F025A1006C0D373B5884B6E52 /* SDWebImageDownloaderResponseModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 233FC59CE7BD0ABCB6EFD98AF26F4228 /* SDWebImageDownloaderResponseModifier.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2D874A9744A25E43B747743945547339 /* GDTCORRegistrar.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FD16FE46197F77B6D4E28CDE644CC73 /* GDTCORRegistrar.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t2DD7B33B4FB4F06F6BDB9FDE23463CCC /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90E823CCF25045F00FF4E98E871586A6 /* CFNetwork.framework */; };\n\t\t2E1CFA6F381B7FD85B94D8043BA56219 /* GoogleDataTransport-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 932BDDF177FD04B28E9285096E7D291C /* GoogleDataTransport-dummy.m */; };\n\t\t2E30ED9EE4AA861FAB2BD7E875BFFCC2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7887F0BAB621B4623BFE017BC5FA339D /* UIKit.framework */; };\n\t\t2E658D649B1C8158B79BC43FFC5B298E /* GDTCORConsoleLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 22B6E2A2A128A5A1F1B6F8D6C0EF4BBE /* GDTCORConsoleLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2F85FF5597762E2E3C6961C6DD690A60 /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A2FCE7B47213F9F0585EA70EA2024A /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t3015C91C523C5133A639F57DE0425100 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D4D1C90894E8A533206E5679B1871 /* SDImageAssetManager.m */; };\n\t\t3098423E501E28F376604CE13D8CD5E0 /* FIRCoreDiagnosticsConnector.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7ED49344AE0AC6AD92262E047201BD /* FIRCoreDiagnosticsConnector.m */; };\n\t\t326BA8EC7036E90AE3AE390C40069CAA /* cs.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D52688E7BC72717ABC1A8FD85DD32AE4 /* cs.lproj */; };\n\t\t32DD9B533A167E3D45FB7C01D4157D5B /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 92EA46401122BB560F222964810DAE14 /* FIRComponent.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t3339C7240948FC777912F0CCA95C3073 /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 98A2C33C3CFB15DFB0AD91D948975967 /* ko.lproj */; };\n\t\t336BA7F271A33087B951BA4C6C6B2C6F /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BB1D1192CEC6C26D481BAB47C75BCA56 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t33C0E2EFD1C8046A2020D25FD1F1611F /* SDImageAWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DFF930E1A1EF9818E6781AA056A03AD3 /* SDImageAWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t343B53EB998CC5B609B8DE84BAD882E0 /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A4FB500E6FBEE5F4910B4E4F3894E917 /* SDWebImageIndicator.m */; };\n\t\t3464ADF2B770D2FE01006027F4882723 /* FBLPromise+Recover.m in Sources */ = {isa = PBXBuildFile; fileRef = BE65A7532D1E92D1171FAB3E3DBF0EC2 /* FBLPromise+Recover.m */; };\n\t\t34816FB2D38145B7EC7D7A14CF5C93D8 /* FBLPromise+All.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D110B53C055335FB5D62021AD131E9F /* FBLPromise+All.m */; };\n\t\t36F35669F3AFF65477B2366FC09A1B3F /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 73F76A840EAA1BA85CD5CE2578134A93 /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t377AF2CA4D196DF568CEF1FB627B9B51 /* FIRInstallationsErrorUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E7EB7DF29D03415C41C56734E0C9017 /* FIRInstallationsErrorUtil.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t37E3C820BC838123661E1391BEAF8092 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = DA01E7E21E39AD745F362344A6F1CA3D /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t388894A87C75381A940680CDD02C263E /* GDTCORReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 5352D3BC21FF5229DD4FC39829C48E7C /* GDTCORReachability.m */; };\n\t\t38B61754E5D4BFD359FDE9EF1BE4A661 /* FBLPromise+Delay.m in Sources */ = {isa = PBXBuildFile; fileRef = 239EF7C666D42E75FB20E65D3491B74A /* FBLPromise+Delay.m */; };\n\t\t38CF7D5EE6C28780FE3F9C1E63CFF3D4 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 615A6102144F4931AF689AB96C01D719 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t3919CF80EC56ACAB6A3808C398ED1968 /* FBLPromise+All.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D82EC7D361BCA9009FD349978107D1C /* FBLPromise+All.h */; };\n\t\t3A899B9C5A8C258ED40829D2BBB6CF78 /* FBLPromise+Reduce.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = F1A5B63B766812910C3FC66A4D5BD359 /* FBLPromise+Reduce.h */; };\n\t\t3B72C235C1AB8944333C2322F08B6B46 /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 09F19A6EF0F8A7D0CDEEA09F1E90D4A1 /* SDWebImageTransition.m */; };\n\t\t3BA8E6BD1A15686C195985599A525C84 /* GDTCCTUploadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 11DC645818CEA0B49FB41D10974587E3 /* GDTCCTUploadOperation.m */; };\n\t\t3C1CC94B45A08AF7DC9A6DAF03574A52 /* Pods-Spotify-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F124022073EADCF94FCBED857E5EABBB /* Pods-Spotify-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t3C22E2D2D6CDBD066DEDBEA8CEB50170 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 700956653190B059B98E6D0401813D2F /* nl.lproj */; };\n\t\t3CDE39AF868FA2AFB18B9739A7F71A7F /* GULMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = BD3097914838C55DE30D9D377048A664 /* GULMutableDictionary.m */; };\n\t\t3E24B31FF1BB232157618DC8EE918071 /* tr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 45A1925DBA110CDCB56C30C2AEC79D96 /* tr.lproj */; };\n\t\t3E5A84FD8D62B473AF24D16F36112D81 /* FBLPromise+Testing.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = F0647D92B0FBA5FC4BF6371012FEE181 /* FBLPromise+Testing.h */; };\n\t\t3F567CE353442AE137B71B258409F5DA /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5304860EBF8FA61DE4A892566862746D /* SDImageLoadersManager.m */; };\n\t\t4075297FF5A21C84EF513521FD7B34EF /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB675D419ACF104AD5C8F2619C4FCF5 /* SDWeakProxy.m */; };\n\t\t407A10BF833B480FECDAFC51A259D6D4 /* FBLPromise+Retry.h in Headers */ = {isa = PBXBuildFile; fileRef = C869A091C5104F60176DCBAC53E9FCD6 /* FBLPromise+Retry.h */; };\n\t\t41286FFA3116FB4073CFA821DFB09A03 /* AppiraterDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4687296E13EF95A9B5206235744E21EC /* AppiraterDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t412EE262DCED176A73591124DBDBA97C /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = 35329B868A55A887B96B3891C90CE411 /* UIImage+MemoryCacheCost.m */; };\n\t\t41382DAAC306E1762433B4D291DAD21D /* PromisesObjC-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 36C228F973FB461AAC3DE1B3CAC5533C /* PromisesObjC-dummy.m */; };\n\t\t41522E9AD19ACF8675C10B4035405E95 /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 668CE7FB58FBCA03E7BF9FFA7D4AEA8C /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t41EB77C2185B44AC4251285C57FD024F /* GDTCOREndpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AE71CC3E7412E1F33D2D46AB258531C /* GDTCOREndpoints.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t421ADEBE65337F1EB365DD161EBAC21C /* firebasecore.nanopb.c in Sources */ = {isa = PBXBuildFile; fileRef = 495F9A8ED0CBC83C181879060E49F21E /* firebasecore.nanopb.c */; };\n\t\t425F70D9B529938D9F19EE92FDBAA4E5 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 255E93987C91799073F418C741D2F912 /* zh-Hans.lproj */; };\n\t\t42822E48A1441AD8E0011D37C1625B36 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CF04F211D2AE46EEBF166D2CC374B517 /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t429E5CC928985357D07058FDEE8069FA /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = EE2390C8AD53927134B524CBC997D50E /* UIView+WebCacheOperation.m */; };\n\t\t42C1C2FC054DE4C8F98D5D9EABB99732 /* GULApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = B134BD979A35DB81CA4CBD64BE86AAC5 /* GULApplication.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t44C7A4ACB41F2B0E588E01C98A0BBE31 /* ar.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EE0CECAF5DA5AAE13E1615E7B14147CB /* ar.lproj */; };\n\t\t457289616B6777C1D443FBC91A2F0325 /* GDTCORLifecycle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CD317B6F97D4204C18D7618DBB86C03 /* GDTCORLifecycle.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t4623448C58E0E271F0DF5F4CC6CAFD0D /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BFEAB29224248CA276353656139D1668 /* SDImageCachesManager.m */; };\n\t\t4634DFDEF1A08A4C90EF8CCDBEF04003 /* FBLPromise+Always.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = FB9896C32514099F18D7AA422602FB04 /* FBLPromise+Always.h */; };\n\t\t4649E8C6659D310A609EF296697D6C4F /* GDTCORDirectorySizeTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 606B14BF9E8B55AA634896F3FE6C2102 /* GDTCORDirectorySizeTracker.m */; };\n\t\t474163E6CF20CA1AC3698759F2B6D51B /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0BC2BA98097A46FED66139FADDB5C2 /* NSButton+WebCache.m */; };\n\t\t475453293C1679D47716F8E17703824E /* Appirater-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD9056754A12ED3E38D68945FE70B586 /* Appirater-dummy.m */; };\n\t\t4795853F6479422BFD716A20342E99EB /* FIRInstallationsSingleOperationPromiseCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7387A62B07188200FF8487FD3A2CF2A5 /* FIRInstallationsSingleOperationPromiseCache.m */; };\n\t\t4844A5C12A400CAABFD7CF2283FDAEAC /* FIRInstallationsIIDStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D5FB0717B52FE2A1C59CA75D8CE483EA /* FIRInstallationsIIDStore.m */; };\n\t\t48920AFFC7C0E2FEA632DAA2BD63287D /* SDWebImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A6344AC78A87A0720BE33CE02655D669 /* SDWebImage-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t48CB1FD2981BA256E4F2582237164A2F /* FIRCoreDiagnosticsData.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D509EE7C37DC62C5F5119B2692E792 /* FIRCoreDiagnosticsData.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t493EEC1796ACFA77A28E7630060A059E /* Appirater-Appirater in Resources */ = {isa = PBXBuildFile; fileRef = 1E9CD753F6BD26760EFAA1DF57482D50 /* Appirater-Appirater */; };\n\t\t498AB54D6531F0B57EAAD113AA0CF0F9 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DED0CE98C3CC1D5B1BEBB3F2409DF55E /* SDAsyncBlockOperation.m */; };\n\t\t499C6F529CC2F5D8A828374ED7DE1069 /* FBLPromise+Race.m in Sources */ = {isa = PBXBuildFile; fileRef = EFD6BF26B215DD780EA6145DFEEC525A /* FBLPromise+Race.m */; };\n\t\t49F97D8BA4E81A5E0EF866A293392AF2 /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F4695D22C004206B1EF601650EB58F1 /* SDWebImageDefine.m */; };\n\t\t4A27F890C33243C4548A25318264B375 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCDB01EEB669605F883EA4E79E56AD2 /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t4AD40F5B3B6CBC790C65872ACCC69B0B /* NSURLSession+GULPromises.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C15E699851C928BE91C72A5169AEB2 /* NSURLSession+GULPromises.m */; };\n\t\t4D9A4DD4DA000DB1A7233197AB5C9998 /* GDTCCTUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 018833202B971E61CF36DA9775AED769 /* GDTCCTUploader.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t4E024B5A716EC026E33AC8EF18023F4C /* Appirater-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D2771347E37390095BF7D36EB989050F /* Appirater-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t4EDE67DB34FEC06E0EC09F4CCC914EF8 /* FIRInstallationsAPIService.h in Headers */ = {isa = PBXBuildFile; fileRef = F1DFF11C55F9B1D83DF7C7397FDACBA2 /* FIRInstallationsAPIService.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t4F5982101CB9FB68613E826F137B5E95 /* SDAssociatedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 80FE85865E814FFFE9FC4BD1E92FF02B /* SDAssociatedObject.m */; };\n\t\t4F5CFA3002CC0285EAA22323D1E017B7 /* FIRApp.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B6C797B8E1770AE7FB92B865BB499B /* FIRApp.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t4FB353F2B2E7D7AE0811D7C538DA2B36 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = B95FF8BC5E40163C886E3DB1B394DD75 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t50FB78A15928E090B123F944AF92656A /* GDTCORAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 363CE7A6599529EED98580D11773BD01 /* GDTCORAssert.m */; };\n\t\t519B33DCAE0FB73CC313A2C2AD434449 /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A10001AFFFB54BB477050134573A9C4 /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t51F891EA712D8F14CF1DD77BF20B62A9 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C78361E6DA67CDEC2A04C25F1B40D31F /* ImageIO.framework */; };\n\t\t523861A018452CE8BB166B59A7872BDA /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = DD910C5803E3E0E5E17C5ED00AFEEEC0 /* SDImageFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t5331944436C43951CC5FA7788DEE9BCF /* FIRInstallationsBackoffController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E03F27C2DCF8DB117CBC29C875DCD95 /* FIRInstallationsBackoffController.m */; };\n\t\t536E9C0D3855A6AF7CADCB9FBAFC613D /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DD11686FB044C460680737D6E66EC0C /* SDImageIOCoder.m */; };\n\t\t551EE2BA0A3A93F089EF76F85871B5EE /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = EF3303042C21F9396439AB3DE71C7BB2 /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t55770A7793FDC52677664F24B19FC7C6 /* FIRComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 00287C1BECC76217689476B210B41A36 /* FIRComponent.m */; };\n\t\t55A09541F17B3F7BD4C62636A15F6212 /* Appirater.m in Sources */ = {isa = PBXBuildFile; fileRef = 0466C52ED49E6E1C863BAFB6E1AE5B92 /* Appirater.m */; settings = {COMPILER_FLAGS = \"-DOS_OBJECT_USE_OBJC=0\"; }; };\n\t\t565EF7659358278D993E12356980AE0C /* FBLPromise+Delay.h in Headers */ = {isa = PBXBuildFile; fileRef = B8633B4212F9E21E512835226D2BEC2E /* FBLPromise+Delay.h */; };\n\t\t56E2818C97A95CF9EC25FF22E92B0F3E /* GDTCORClock.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F6FA7F2B642E68ECD25BCCB0DDAAA75 /* GDTCORClock.m */; };\n\t\t573CBCA281A2BB0F097329EE28BCFE60 /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 90D9BC28AA40B8F7AAC5DBAFFFA2503A /* pb_encode.c */; settings = {COMPILER_FLAGS = \"-fno-objc-arc -fno-objc-arc\"; }; };\n\t\t57D8A29DA38A71184A984913BBC01CEC /* FBLPromises.h in Headers */ = {isa = PBXBuildFile; fileRef = 7283DD0E961B31F830AEB840A7B59650 /* FBLPromises.h */; };\n\t\t57E1C476BA5F8DD1ED740FE8DBC05D8A /* SDAnimatedImagePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA3607B121AEFB0595C76441513C64D /* SDAnimatedImagePlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t57F70A5C8A2F7A13B0E33409440F4ABD /* FBLPromise+Async.h in Headers */ = {isa = PBXBuildFile; fileRef = 7FDFC5FEAC4A550A50CD516405F6DFF2 /* FBLPromise+Async.h */; };\n\t\t58FAE3A59FBE896EBBDACB0808067CA5 /* SDDeviceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DB218DD71AD0570B0E339E5319F93B /* SDDeviceHelper.m */; };\n\t\t5911F99F8CABED05F9F701DC450E4BC8 /* FIRHeartbeatInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E16667A1668B640A863FF171D2CB5FB /* FIRHeartbeatInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t593E6264A36C1B39D5885E85304C8916 /* FIRLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = A4A6DED8C7023B5E793A748ED43129EE /* FIRLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t5A3E5B854E8188DDF4E958BBC9198600 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\t5ABA716A48A3468C5B83F83D69DDF5D2 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C9B0DD52D5C611E1AB4BB7A9A92DF5 /* pb.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t5B3271A67137276C4B2CD554BAB9F4DA /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AF89B1AE50DF562243E31C949BD5B3 /* UIImage+MultiFormat.m */; };\n\t\t5B69919844A3BD774BAABB186D6A524F /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 370CEA1E37CB5E0D01FDBFF39E1020BE /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t5BBE7719912593F1DEFF8E763EAD4ED6 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5852FC7ED30AAEEA07547AF6D71F3D85 /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t5C10B5CF2AEA5FB4A63F282ECA9F7CB7 /* ro.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D053D0A9CE99EC16E5ED88D7BA8C3A65 /* ro.lproj */; };\n\t\t5C4E850422971D9660A700996C75898F /* GULAppDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C5DD83B8521D66EB85A5A45A92F810F /* GULAppDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t5F1DA411EF4EF25F7278116F9DBD8FB8 /* FIRInstallationsStoredAuthToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F25465DB16E55EFF41F24C620E24E05 /* FIRInstallationsStoredAuthToken.m */; };\n\t\t5F49C3C9A3733CD50642E0B57D405D44 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 079B6435FC4625DBC4A439EDF7FD5844 /* SDWebImageError.m */; };\n\t\t5FCA234EC54B026FF4FE2CCCFCB1EE7E /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 983C23FA76E7A245275E7A252B67A2A0 /* pb_common.c */; settings = {COMPILER_FLAGS = \"-fno-objc-arc -fno-objc-arc -fno-objc-arc\"; }; };\n\t\t611CE969CEC379BB77D8885D915A8095 /* GULSceneDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 56EBF81C7BB707870CF8F18F19C219BC /* GULSceneDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t61CD5A24511DC980EFF397CF57AC50F5 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = C48BA4C3D0C62019243E819DD277C007 /* SDInternalMacros.m */; };\n\t\t620EBEBCDCF8233A6CED99BD83B4C8D1 /* FBLPromises.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 7283DD0E961B31F830AEB840A7B59650 /* FBLPromises.h */; };\n\t\t62A22A4C10675F9B65C7677CFD6C4676 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E7185858699874B61C27769747820E1 /* SDWebImagePrefetcher.m */; };\n\t\t6337C7DF0D550595E0FC08E973C61709 /* GDTCORUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FC875B27ACA63CA271CA0D921CF94C3 /* GDTCORUploader.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t64CDB33E49BDBE16653C88756E26B8CB /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D8AA9949B871C5C08476B12041D2D99 /* SDImageCoder.m */; };\n\t\t64DF55F7B991438E693B9A078807E55B /* FBLPromise+Do.m in Sources */ = {isa = PBXBuildFile; fileRef = A6888DFA1022D0AF9FB4109175558CEC /* FBLPromise+Do.m */; };\n\t\t6503E1414B68019CD76455273240A263 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BBDEBAD931B605980FE3DCE9FA337AE /* SystemConfiguration.framework */; };\n\t\t658CF66D84C572191E43DBCA78450144 /* FIRInstallationsStoredItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D0D7E32DDD7AE56C23799445C13A57 /* FIRInstallationsStoredItem.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t65F85B6A937820FAA8F2ACA55AAC93D7 /* GDTCORStorageEventSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BE80A247D8376A910A19BFB10B99430 /* GDTCORStorageEventSelector.m */; };\n\t\t67337806BBF45E0F89460C0ECB98F7CC /* FIRInstallationsAuthTokenResult.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ADAB8E982AFC5F2BD545EB091C78BD /* FIRInstallationsAuthTokenResult.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t67B0CAAD8E88B9A2357C41E73EA2EB48 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DD6F50E5F16B3EE2AFBBBA48053FA5 /* SDWebImageCacheKeyFilter.m */; };\n\t\t67B3965694762B918FFBF665F842D881 /* FIRConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = A3142D0BC0A7099D82BA56A3FD637656 /* FIRConfiguration.m */; };\n\t\t67B3DCBA30FDEDA18E0D4E3B2C16C911 /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = F538296E4FA1BF861A19524F47E7A6D5 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t685481CA7A154E8AAE00089FC07BDC74 /* GULAppDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 16A5A619D3393C3652027A63F8D6406E /* GULAppDelegateSwizzler.m */; };\n\t\t694921E04F46359CCC4C2A3DF0ADBD04 /* FirebaseInstallations-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EDF07392617868FE264D5E58788D279F /* FirebaseInstallations-dummy.m */; };\n\t\t6A60904A4A5C9CB728F36E68131A5629 /* GULURLSessionDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F2853ABAFCEFBF960A5040D649074EC /* GULURLSessionDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6A9D73033878EECC7CAD51C2C82AF26B /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = C76E61D46C6D64C4743B6A7256A286EF /* FIRLibrary.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t6ABBB7192F4FA78A90D45CA78172AC86 /* GDTCORConsoleLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 93498C80BEE42599CD4B49D1DCDE8DAA /* GDTCORConsoleLogger.m */; };\n\t\t6B83391B3231B704CBEADFE1F3ABE0F1 /* firebasecore.nanopb.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A58961C9BBD35E7B60ECDB62E56F7DC /* firebasecore.nanopb.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6BDCB1B9157D9AF6B3A78C0E0619FFA2 /* pt-BR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = C3AECB4945D348C50164B9454BA98CB3 /* pt-BR.lproj */; };\n\t\t6C301FF2C25C6329F7EA45C87F96C660 /* FIRInstallationsIIDStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 703B93588CDC01E3116988AAD425A74D /* FIRInstallationsIIDStore.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6C93ABDF963DDA7C78AADD9F22CD5CB1 /* NSBezierPath+SDRoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = E06211AF2F4E3047043DD4BCDC40403C /* NSBezierPath+SDRoundedCorners.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t6CFA7E848AADCF3237F5D70EB4019775 /* FIRVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 724419369F9B475400E63E05193D0394 /* FIRVersion.m */; };\n\t\t6DA57657B2030D8076B7B341150BC06F /* GDTCORDirectorySizeTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E791BF8C770CDCE827420B1959B849 /* GDTCORDirectorySizeTracker.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6EFEF0AC86E0308D25D125522708DD7F /* FIRInstallationsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 99108619FD685C7E04AA2798D8184E88 /* FIRInstallationsLogger.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6F030A5B151E155313EFC0C843C68018 /* GDTCORUploadBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = EC47234C0173B2827334091E5C04C152 /* GDTCORUploadBatch.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6F333D5505E952CF9C517DAE5114AC2D /* FIRInstallationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = B46C4D5C2FF1FB2417D06ADB91D1CEBA /* FIRInstallationsStore.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t6F4B172730B7293C1D988FBE34B45E20 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = FF32D6A22D56F5787F289A4BEA15E6A1 /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6F7307112195D5B6083F450AB2657AE2 /* GDTCCTNanopbHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CBEB10B215FDB65E86331667E87AE84 /* GDTCCTNanopbHelpers.m */; };\n\t\t6F9B1AAD95146EC2AE89F5B821D611D6 /* FIRCoreDiagnosticsInterop.h in Headers */ = {isa = PBXBuildFile; fileRef = 5805E31EC45A505EEE3457FA2B9FA351 /* FIRCoreDiagnosticsInterop.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t701F3C59F0434AC67482392B26FB6F0A /* FIRBundleUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 303FE2537CE3769B58923B71632FED1C /* FIRBundleUtil.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7061D35639F93885B8A80B3B7FE090F7 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BBDEBAD931B605980FE3DCE9FA337AE /* SystemConfiguration.framework */; };\n\t\t7100C2CFC22D1689ADA78A36E65B697B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BBDEBAD931B605980FE3DCE9FA337AE /* SystemConfiguration.framework */; };\n\t\t71093AA6681FFAD2FA263E3FADE983D1 /* GDTCORRegistrar_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0338A87088B87F5A5D1BB03CA2AB274B /* GDTCORRegistrar_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t714EB6036BF393E60ADE1F6F2C7E8A1F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\t71A8CC130B0CB8E978F51381AFD722C7 /* FBLPromise+Always.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DFCC2FB818BA3289E85B84DD2F068A3 /* FBLPromise+Always.m */; };\n\t\t72BE14CDABBE9D94A85828F987136A6E /* FBLPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = F35AA80907A78AC92F34C61F368248E7 /* FBLPromise.h */; };\n\t\t72C3E949015B30F289F28DEDE6BA8F84 /* FIRCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = B349AD374EBA10C2D49FC4BA8A53F0CF /* FIRCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t73F2DE8B48DC2F7C87529AB3901B9E94 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 859F0A43E3649885E17F4D515A86A159 /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t74849A92CED98D844690D9779D6F6DD1 /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B185568A19C67E5278D6DB507473C2B /* FIRComponentType.m */; };\n\t\t74B90EA2A2E4ADC58C8693B6FB534D85 /* GULLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4468F16CABC244B58ACDC50E87F8B3C4 /* GULLogger.m */; };\n\t\t74C6F951FCB4661E545409C0AF80D2E7 /* GoogleUtilities-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F54F5C198006F0294B0657489850E48 /* GoogleUtilities-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t762A59E0FF6F1A92B360C6E0A5E4A7CA /* nb.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4F72FBD1344FC32D12AA727F983904D6 /* nb.lproj */; };\n\t\t773B2DCA4762991C7F8FAE2FC860253D /* GDTCOREvent.h in Headers */ = {isa = PBXBuildFile; fileRef = BBB794E91F141A51A62086A95A79B3B0 /* GDTCOREvent.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t77B7C664156789B282A6AECEB7F380C7 /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 66B0B7773B93F50516AFA7A4AD80001F /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t78AE96580BD551EB905F72C21AB81E97 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 99AC313325A72709F61AD9B82245FC4F /* SDImageCachesManagerOperation.m */; };\n\t\t78E730C2966F82AB15136ED2AFC85095 /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71B48D7039219AEB311FB0DA2E1E389 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7975CB02E10D105FA23A30B254C25F4F /* GULNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 0502AAFCB22CA8A06A21C20517BE89B4 /* GULNetwork.m */; };\n\t\t79B821DE59EE806496A9FD4FF3FEDAB7 /* FBLPromise+Then.m in Sources */ = {isa = PBXBuildFile; fileRef = 18637DFB49F868B5320F06FCD27ABD99 /* FBLPromise+Then.m */; };\n\t\t7A0703CD6D58504249D27BB436F68B39 /* FBLPromise+Validate.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 2CD99347EC1D85D2C2FDDB3D1F9DF393 /* FBLPromise+Validate.h */; };\n\t\t7A1EBC1F342550748C7D0A21F7BFA7D6 /* FIRInstallationsItem.h in Headers */ = {isa = PBXBuildFile; fileRef = D29D1ACD3388DF30F5213782D0089AAE /* FIRInstallationsItem.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7A424FED21A399FE2610DCB710A4A3FB /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BBCA689ED4AD568D1203A32DDCB2654 /* SDWebImageOptionsProcessor.m */; };\n\t\t7A6E617487687A7EC3ED28D9090EC0E4 /* GDTCORTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = F589BA173CD44451894C642200BAD5A9 /* GDTCORTargets.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t7AE82F1B24F7A2E9B28BAF431611111F /* FIRHeartbeatInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CDC11191CD5FAC6E9AA96E2BC7DAD05 /* FIRHeartbeatInfo.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7AF1433C05B27E85A58B5222B73620BB /* FIRInstallationsSingleOperationPromiseCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A55020CA6EDE9396075075D402E84AEC /* FIRInstallationsSingleOperationPromiseCache.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7CA7517C4920C00FDAB34D5152390BA6 /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EF7A55F92FBA10C1CA52F98BF5B091C9 /* es.lproj */; };\n\t\t7D41A53C422B8849362A0A50C943F0E1 /* GDTCORTransport_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 67A976AAF1EAC9BADF423E17C96B88FE /* GDTCORTransport_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t7D9E8F8A5D02148FCC2DBD6319BCC3D1 /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 91D7D93CD15EE8BBB672073A9EE9172E /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t7E6862A73246BB1A0E7BCEBAF50FFBE1 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = BA37D2C1168173A7796B05F93479A231 /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t7E7E08BEE28A0144B41743F4C265B0AC /* sk.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 573447DBCFF573125A97AC8FE08CF8FB /* sk.lproj */; };\n\t\t7EF58E7AF295CBE99496A96A5D8C13EA /* FBLPromise+Any.m in Sources */ = {isa = PBXBuildFile; fileRef = A1B2BE9FCAE442C062B1070B5F83D9D9 /* FBLPromise+Any.m */; };\n\t\t7FC014E10F04D9761116EE2481087F70 /* GULOriginalIMPConvenienceMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = C2439987FF247C8C084181EBCF11641F /* GULOriginalIMPConvenienceMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t809A09224ABB6A00BEF6B72EFAB30B4E /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B1C3F5E1F2DA4D224862FC3F811D0917 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t80D4A72C26C2EF865F9DCA400D2F1E70 /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = B195FEEB2B6FD768A1270ABE2938AA39 /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81534784497FC1ECE74D5C18D43AF3EB /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = FC22CB2FD3FE9BC3D607B5CA39155B83 /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t832067DBD9BAC003B8E5687562E6BBCE /* FBLPromise+Retry.m in Sources */ = {isa = PBXBuildFile; fileRef = B0893F86784B88FBEBDDAD469BA72394 /* FBLPromise+Retry.m */; };\n\t\t83747CB2CE756E6DE235E7A419CE6B64 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4958CF39D5BE0CE693F9BABAB470D5A1 /* it.lproj */; };\n\t\t83ACE2DB5F2F7F9352D11E9BD334AD96 /* FBLPromise+Any.h in Headers */ = {isa = PBXBuildFile; fileRef = 70FBB40CF13B29C7EC31294E2767F546 /* FBLPromise+Any.h */; };\n\t\t83F5B3ABAFBB47CDA2E64D9C879F2167 /* FIRInstallationsIIDTokenStore.m in Sources */ = {isa = PBXBuildFile; fileRef = DDDFE2B6438138D00D92226D62FA76AD /* FIRInstallationsIIDTokenStore.m */; };\n\t\t842007158292E13DF5B3878A89BD4727 /* FBLPromise+Race.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 447B191325C26D8C11C3D317EC3FBAA8 /* FBLPromise+Race.h */; };\n\t\t8433F353F3016EFF0316F48188D6B651 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 804DFCC909792374DF921D69BE1F1C18 /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t84B624227D73D3746CEFD48E49D74635 /* SDAssociatedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A1BDEE41C3F181B6BAC16ADB84601E /* SDAssociatedObject.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t84B818EEE3E3EE948F29B61A752BFC0B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\t84F3CB5D0530A295C9D23F675A5904B5 /* FIRLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 0720E29DA86F4D52C08D6942FFEF190A /* FIRLogger.m */; };\n\t\t854D7A4A2872566E4D06870518053225 /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 37B1C403940FAFD0BDA8092C0726458A /* SDImageAPNGCoder.m */; };\n\t\t85DBD9AB9CEC227EB078B8EC52906809 /* GULUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = CF805F43FFDD645D95C1ACEABC114049 /* GULUserDefaults.m */; };\n\t\t868244D3347466936301E48DA39BE842 /* fa.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A86DA94DC9AB6D6E95B73BF4F59C3EF1 /* fa.lproj */; };\n\t\t86A4EDC386D953055E2EFD288F8549E7 /* GDTCORFlatFileStorage+Promises.h in Headers */ = {isa = PBXBuildFile; fileRef = E9E0C507183FA6B14B3FED0BB9BFE8E5 /* GDTCORFlatFileStorage+Promises.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t86DDBF748A2FAB2E5426D9C62F4E97B6 /* GULAppEnvironmentUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B538C0DED9A96F51790585E9AF03D97 /* GULAppEnvironmentUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t878C1E830C12ED8A433F6FD3DAC38946 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA2A90BF46E4D5796820E1A900E2C0B /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t87EE04B662C6A6A6E3731E657170FBB8 /* GULReachabilityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82E76BE97070A77C122D8CD5A2A852 /* GULReachabilityChecker.m */; };\n\t\t8821E3636BB86560FC2F2D2CFF545F16 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1C27AE73C820EC4ACBF12FAEEA1D93 /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t888BEE4C3B238AC407C59D2194939AB9 /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D8A688C63FDD5533A68B0CD80B0501E /* SDImageCacheConfig.m */; };\n\t\t89A0AC3A2E24FDA5CEDF545C0050C90C /* GULHeartbeatDateStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 05850FDD1539ACB6AB1C9DB0142B8403 /* GULHeartbeatDateStorage.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t8B6E3CBB15DD0345506BCEA811AEAA43 /* FIRComponentContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE8073B498E3701A492F026966747912 /* FIRComponentContainer.m */; };\n\t\t8BFCDB90BD5C326BE36EE7599F016413 /* FIRInstallationsBackoffController.h in Headers */ = {isa = PBXBuildFile; fileRef = 382D07A53D722649DCAD5C5BC3BDCAC1 /* FIRInstallationsBackoffController.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t8C207CEE5189EAF1C9408F8FCE291E11 /* el.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 99C91ADC1F402BD8ABEE63EAB8134747 /* el.lproj */; };\n\t\t8C5D0B2A7B52DF68D03820244993E91B /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F824E440C097E5A5FE69CFBC7293F15 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t8C9D609988FE2993BB116B4B00FAC57B /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = B12CEE2C03EFBD7EBAF1717349B42067 /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t8C9EAF8201E92AB60FFE3A04A6A1D47B /* FIRCoreDiagnosticsConnector.h in Headers */ = {isa = PBXBuildFile; fileRef = 747BA4839026A5B48F78F7F2F59B01D8 /* FIRCoreDiagnosticsConnector.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t8D374E688F039AFD9D5F03C0A24DC4B6 /* GULSecureCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = AB007F418E0ED0E20061B9ED7D831C76 /* GULSecureCoding.m */; };\n\t\t8D3BB2AEBD692793E70D2D3A2BED2135 /* FirebaseInstallations-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 54D381D3559D8677EA0632FDB5EEA05A /* FirebaseInstallations-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t8E2FC561736D6CE4D3D7F50A4DE1A540 /* he.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D005D4ECC0D56EB73527C065B49D192C /* he.lproj */; };\n\t\t8F88549F032EFFEA9C281860520CC879 /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 43363A5F804039F569FD9ABD9433F07B /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t909CBA577868D6E976AC82340B50343E /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA6F310E602B6F29B722C01961258A4 /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t90A7255991F8B76C78A1C6A47F0BD3A5 /* GULSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C61DBDC1219C0AC0AD0FF84A0133692 /* GULSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9173483B65737D0C0DD2D1F3427AFE45 /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15F02952828900F1CC5E66B83274F6E0 /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t92851B2DB4A4C54E24A1720ADEC60E84 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = B3DC2C81260A550A30B6C664556BAD8A /* FIRDependency.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t92B70011891306D90A55DC048EEE2DCC /* fi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = AF5AFDC2F2B6C3E31AFC75FE3430CA49 /* fi.lproj */; };\n\t\t940AEABD2B727E9478DD58CB3EF383F6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\t95D0E52FDA5F7738F1D6F56696279BF8 /* FIRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 38A7BC4B65A58A155D087DA3EFFC1D79 /* FIRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t96479C9C76FDC513C03ADD58168F6911 /* SDImageIOAnimatedCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = A9A5B5BEF1CFAFF4AEB69AFD4C20968A /* SDImageIOAnimatedCoder.m */; };\n\t\t96E8F1107963D738A8DD84FF5D7C4563 /* FBLPromise+Recover.h in Headers */ = {isa = PBXBuildFile; fileRef = 6806286AE468436D210DE24F56FFD7A2 /* FBLPromise+Recover.h */; };\n\t\t9749F5178C242B199D8F80DBC55F1041 /* GDTCORTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = FFC85887576AED4EB7D6127CC1FDC955 /* GDTCORTransport.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t975390A7158A9A542B397F21D63DDE3F /* FIRInstallationsIDController.h in Headers */ = {isa = PBXBuildFile; fileRef = EE06EB2E171945BC2050FB3D4A038D02 /* FIRInstallationsIDController.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t97E10B0D702DED48D5FD1062AA27E9AB /* hu.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 90548723A968948DA9E270815D5DFEA2 /* hu.lproj */; };\n\t\t9917CEAD8CE1CEB7FEC031255AED8FA8 /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = C41FA4729FC85108299943DF13BE21D7 /* SDWebImageError.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t994327308CC7ECE7850C804FA0EA5F21 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D2E7ABE07934F659148C41C852087FD /* NSImage+Compatibility.m */; };\n\t\t99709E1C4991C49EE5601FF9461B2969 /* SDImageHEICCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4600B5D11E621BE294D5D7A8106BF312 /* SDImageHEICCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9ADF36BDEE9C92870ACB3F6E17CB0136 /* FIRInstallationsErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 46849267116D15C2F916F95AF7ED6264 /* FIRInstallationsErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9B9D9E2182957C42538AD42CF824823B /* FIRBundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DD42FC19A2CC2BEA3D2DBD52D86D8F36 /* FIRBundleUtil.m */; };\n\t\t9C096C865369C21D252A0F4F90BE21D9 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 415A874BEFEAB372A795B3F77C86139D /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t9CEB5B454088D6BCC3A11C759A76161A /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = D75DB99AD94B959D922B1BF144AEFE15 /* SDAnimatedImage.m */; };\n\t\t9D7EBB3A7377C116526B8A511F8CE245 /* SDDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 33802E944806D1B99AD085FE7F697A74 /* SDDisplayLink.m */; };\n\t\t9E6AB9E70A18A858DCBC3B7D57575F47 /* cct.nanopb.h in Headers */ = {isa = PBXBuildFile; fileRef = AB33B7FB74C324A4584D1D93AF8B1DB5 /* cct.nanopb.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\t9EBE4FF936493E44E9CF7A19860170A8 /* GULHeartbeatDateStorable.h in Headers */ = {isa = PBXBuildFile; fileRef = 447875125DF9F0D89F9C6EF9340E1570 /* GULHeartbeatDateStorable.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9F4966331D34AA8CE85C4E7161B8D732 /* FBLPromise+Timeout.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A8A40185ABE648F7A15E613D0C0559F /* FBLPromise+Timeout.m */; };\n\t\tA083AAC3481062E5DE223D480757A83B /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = D53EBA2326B86A037D7D89C9C9849AB1 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tA0857AD2616E974FC2D53A08EC963D28 /* GDTCORTransformer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0ADF13875C4D61EE62B5265D074DB171 /* GDTCORTransformer_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tA179E49E5148E014ACB35B3234A79829 /* pt.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FC3C259DB11E51E08F2D5630A5145839 /* pt.lproj */; };\n\t\tA20FADF8B2F5E792711B7E906B93E692 /* GULKeychainStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B8AE32764C24267738A026CE787CE667 /* GULKeychainStorage.m */; };\n\t\tA24B4B60656BA387B9979BD877A23983 /* SDDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE88DC6249A53E194E886FD268B4F22 /* SDDisplayLink.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tA2CE92DE43AB450DE1AAA129BFBADCBE /* SDGraphicsImageRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B207171596C8E59567CB49A2BC0B7C9 /* SDGraphicsImageRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tA331C78D95C334AC3C328874419FB071 /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8C5EE75C53160A323F9D43000C9258C2 /* zh-Hant.lproj */; };\n\t\tA3BFF0CDB72BC173BEA1C8ADDBDB0D1D /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E45C724EB1ABA21537759F2AA0CDBF /* UIView+WebCache.m */; };\n\t\tA3F8A995C1C713901F9B4503D4103A47 /* GDTCORStorageEventSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = FFBEACDBC00E47FDCE130333C01BDD52 /* GDTCORStorageEventSelector.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tA4AA6C3C19244F1FF335C090930C609A /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = C887379F2FAEEA195D743E2A7E8695B2 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tA5D6F583F2BCDF15588F8BA972A682CE /* FIRInstallations.h in Headers */ = {isa = PBXBuildFile; fileRef = F463B32358D0340C851CB2FCB8E3B0A5 /* FIRInstallations.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tA65D64846FFDD7178C8708AF52B5CECF /* FBLPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = B21C4B6B899118FE97F08797C6CC6D78 /* FBLPromise.m */; };\n\t\tA70259457F23AD83937DF1CA0DAF46D0 /* GULMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 73009AD0D7FBF3D5781BD8B87D5E1D98 /* GULMutableDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tA9A87DA629538D239C4B7401EB56AEB5 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 841780DAC592F44AB2E8D35D36E32285 /* SDImageTransformer.m */; };\n\t\tAA3AE0DF5E35D3E0D2CAE7972D69373E /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A138FFFD47F81003F3160EC8E9953 /* SDAnimatedImageView+WebCache.m */; };\n\t\tAB471FF0764CF95AAC04F43A451C54D5 /* FBLPromise+Timeout.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 2A93FB313CA659376FAA369092F2D036 /* FBLPromise+Timeout.h */; };\n\t\tABEAA41C35A6CD25C93E622FB129C379 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = B3522FD698E8EFD6BDE90D04D1ABC13D /* SDImageLoader.m */; };\n\t\tAC11317554C3B930BCC98EB6937EEC91 /* FBLPromise+Reduce.m in Sources */ = {isa = PBXBuildFile; fileRef = FF60EBD5E154FA9A791F0C421B4D9AEE /* FBLPromise+Reduce.m */; };\n\t\tAC551E9186602377EC1751E316CDCEC2 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F030A051DB2F7C17CB74A9C0FBD7B56 /* Security.framework */; };\n\t\tAC76D5E67DCEFB22BE84148317D7B5A5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\tACC1D2855B9D8168F64EAAB7869DE334 /* ca.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4E579AE58A2F6343FA943DA78FDA6A24 /* ca.lproj */; };\n\t\tACFBB1893DBF761BB053683178D43A45 /* FIRInstallations.m in Sources */ = {isa = PBXBuildFile; fileRef = 07E9568C4EE8BF77740269310C486888 /* FIRInstallations.m */; };\n\t\tAD0CFDA140E346502935BA58225E6EF3 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = D9304F4CFD273BA0BC3D8FD8EA8CE973 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tAE1F2017E0DEFDFDFA2143A647D2BC15 /* Pods-Spotify-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A27A53F9FCBFE297E53C77376ACB64D1 /* Pods-Spotify-dummy.m */; };\n\t\tAE89C60F9CD4D6E1400DD304CE2A2B9E /* UIColor+SDHexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 14DB6413E93A38460FE253FC259C28D5 /* UIColor+SDHexString.m */; };\n\t\tAF8528758C11B8B5E020066DE3EF45B8 /* GULHeartbeatDateStorageUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F86D0619F7550A5DBDF634B8413E25F /* GULHeartbeatDateStorageUserDefaults.m */; };\n\t\tB04279CC3476C6D75EDE63B360B89DEC /* SDWebImageTransitionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9487AD43770C35ED6D6CF71B197AE775 /* SDWebImageTransitionInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tB128DE666CCA7CF6B0F09411D8209A92 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 296AEDDAB76C6DA79B00DFB17FE94B13 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tB1F3BDEEBCD13FE138D33F45470AFA71 /* FIRComponentContainerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EDD3FE368044C57FFE267748AD31CE /* FIRComponentContainerInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tB233AA226EBC0EB5843452893330638B /* GULNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = EDF0E36BC33BC1C752AA5C64455974C1 /* GULNSData+zlib.m */; };\n\t\tB309A5100D011205E23108FA864CEE9F /* th.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8A0DEDA4144F466B62361967B86ACC25 /* th.lproj */; };\n\t\tB3580A5C39E7E3B32DE3AC015B6DA74A /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = D2DC9C0FCEB534D5193B9600BF0552FC /* GULAppEnvironmentUtil.m */; };\n\t\tB48A893A8058A155BCFA6211E8BBAEE4 /* id.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4AC80933AD4E17DC2DDD4A5156E1FADB /* id.lproj */; };\n\t\tB48E2B8546BDCA558F808B1CB4849CEF /* FIRInstallationsIDController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBED0511F929D50127372614C07E38 /* FIRInstallationsIDController.m */; };\n\t\tB502D35637FD94ED622BFEE8D65D2E14 /* FBLPromise+Delay.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = B8633B4212F9E21E512835226D2BEC2E /* FBLPromise+Delay.h */; };\n\t\tB519045D5C102170273EDD0B9D141F94 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\tB595EBF813D80EAD2870F0D888B6F1DE /* FIROptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BF0F7EE147A98C2F11F7C4C32C5B6E3 /* FIROptions.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tB5AFC5251D252C4CF6AC6A609E167BFF /* GULNetworkMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 54836C20C54693641AA8386E05C05C5C /* GULNetworkMessageCode.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tB5C56C4D45E7E7A9630F9417A6E39C1D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\tB82109186D3614122E6130F9710A241F /* GDTCOREvent_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CEB2E6515F73C730A4DE300BCA32CE76 /* GDTCOREvent_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tB88C351562CE8FA4255EA9023213BE4E /* SDGraphicsImageRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FC4393F5EB9D10CAC25D438B9ECB2A3 /* SDGraphicsImageRenderer.m */; };\n\t\tB98DAA42533894F17AD50F5DA1EFD347 /* GDTCOREvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 74B387BF4963DADE929360BC4D95BF9F /* GDTCOREvent.m */; };\n\t\tB99344EDD10321BF98BD222F9CA56993 /* FBLPromise+Retry.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = C869A091C5104F60176DCBAC53E9FCD6 /* FBLPromise+Retry.h */; };\n\t\tBAF01AD02AE3A4066A56C40095FE11F6 /* FBLPromise+Async.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 7FDFC5FEAC4A550A50CD516405F6DFF2 /* FBLPromise+Async.h */; };\n\t\tBBB3C52BD5CE5A8F90FBD5650B283EA1 /* GULReachabilityMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE20DA431EFAB6E9DE3F14B005CCF75 /* GULReachabilityMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tBCB7B61DB37BA3EDB8CBBF258DC66446 /* UIImage+ExtendedCacheData.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C98C55DA7C8E2B36CE7527095DED78 /* UIImage+ExtendedCacheData.m */; };\n\t\tBCD010E21F3444C11F5F87821E7F832D /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 45405CBF1024B18B4589ED32B6B9D343 /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tBD074722CD72470954ADB5B1198E01C5 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 31527FC5A967FDE9F076D544F4923295 /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tBD5380B89F6EA6442F55F457CB377251 /* FBLPromise+Then.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D85590DB78FA3CE98F5876D319CDC9F /* FBLPromise+Then.h */; };\n\t\tBDE45185614935653E3E24E4F8AE8812 /* GDTCCTCompressionHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B56D652DA90C728A3D4AA16170D7FA2 /* GDTCCTCompressionHelper.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tBE141B44BBCE0650A03846E0D38F86EC /* FIRHeartbeatInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8454F0C4E786C6A2499ED8DA5879A808 /* FIRHeartbeatInfo.m */; };\n\t\tBE649A29E5FB32C54FDAE55994804F6D /* SDWebImageOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F848EBF5A77518F1437E59128B898ACE /* SDWebImageOperation.m */; };\n\t\tBE6B23777B825686F33ED40AABA4F17C /* GDTCORUploadCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = F6FF94050EDDF80FD2501F4E30F18E4D /* GDTCORUploadCoordinator.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tBF9A6E2CB8F67686C4B7E04538664919 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 27B6AEBABD0DD760910C2037F73CBBA7 /* UIImage+Transform.m */; };\n\t\tBFC98970FF0DF6305A33A564BD19BF7C /* GDTCORClock.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEE4E5F9E2A1F4352E21C55CC500B15 /* GDTCORClock.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC02890A41D0AB13F90A47695B7F2867F /* da.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F4A7F01DAC8F3E158C6CB70DD5E60C24 /* da.lproj */; };\n\t\tC0EB460750BF5FBED872DD25D3B316CB /* GULLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 32B1014C844F5619D536DFD1800B11D5 /* GULLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC14230A8434F2DC9A5100B4DF5EDA4B4 /* FIRAppAssociationRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F0A5A8418FA40166272625AFB5330A /* FIRAppAssociationRegistration.m */; };\n\t\tC21AEB2BC0F95C132FDE2206B40199F9 /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 48972591E3AF0F13726EC5D4C6BEDFDC /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tC22DB2BCE626C82201E5409BD16B0C97 /* FBLPromiseError.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = E76B8095179CC1855E5CFA2FF2597A24 /* FBLPromiseError.h */; };\n\t\tC27BD8C6B4E713A8E7B7B76B80E45823 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = D92B4CC4E2762BD017DDAA71533D1487 /* SDWebImageDownloaderRequestModifier.m */; };\n\t\tC2D82385F4FDB67F6613CBBE8E2BD850 /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B722DB0B3C51C3645037E3399784B69 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC2FF212194FBD30D199C4958030720D1 /* FBLPromise+Any.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 70FBB40CF13B29C7EC31294E2767F546 /* FBLPromise+Any.h */; };\n\t\tC326A2B1DC92AC4C4C105C1D73C78E13 /* GDTCOREndpoints_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = EF8FCF0158C3FC321B0CCC8F87E286F6 /* GDTCOREndpoints_Private.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tC40413C3772DC573FF3086BAB7D1EE28 /* GULSceneDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = D327D14764B30DDEEB17666FA535871D /* GULSceneDelegateSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC4762BD85B320B9EBE199F7CDFBCED12 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = A259FD968B2F3F103051FCCB13D1EF8F /* UIImageView+HighlightedWebCache.m */; };\n\t\tC4A78B8FC2DC76FBCF43D9D53BF90767 /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F0A654F37AEA764934660E26E3BD2475 /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC4E92D0B4B466595D3F4649BD0827A15 /* GDTCOREndpoints.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D1FFD95B9DC7DB4011FC5445F7059CE /* GDTCOREndpoints.m */; };\n\t\tC50420FA308E51F5885CE0A2BA817622 /* GULNetworkConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C8ECB26C6DABE3DBF37DBC44D5A8C5C /* GULNetworkConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC55A2D001850D3F407D968CFF1C545E2 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F3DF4F3E573CB800D27E86168DD5EECB /* UIButton+WebCache.m */; };\n\t\tC6B19B09709899C1D9F1062017C9E497 /* FBLPromise+All.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 4D82EC7D361BCA9009FD349978107D1C /* FBLPromise+All.h */; };\n\t\tC6C08B108C2F5D3E6828AFC268E87341 /* FIRAnalyticsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B055BE0C98324B8E1EE0B588C14B23C /* FIRAnalyticsConfiguration.m */; };\n\t\tC6CF8D2EE14A91A98FC8E5BA749F6D3C /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 3446029F86E0312850EAC5C98A32C65C /* ru.lproj */; };\n\t\tC7E8A80BE6BE5452380D8CA71F278B8A /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7600C02A26CBAC1E67CFF0278A198D /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC8161051C207F9AECD0562B6B9E0E579 /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1CFCA4C81C90732F8DB42EA1F017A3 /* FIRLibrary.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tCA04A500A668FCCEB250C8A61F0643DA /* FIRCoreDiagnosticsConnector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DFB6F1D058B390F2A1340D6D90391C0 /* FIRCoreDiagnosticsConnector.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tCA050FC8C58FA008C11AB981F0AC4363 /* FBLPromise+Always.h in Headers */ = {isa = PBXBuildFile; fileRef = FB9896C32514099F18D7AA422602FB04 /* FBLPromise+Always.h */; };\n\t\tCA180BD40DFE51946C1F45D45D5E3784 /* GDTCOREventTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = EC2AA38D1492EE015AE393D7FCDBCDF1 /* GDTCOREventTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tCEBCB78AD6ADE2D0F18F7D9E07D5C4DB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\tCF4DAD38BC9565548EC08D14D2B6541C /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A55FC857FA4F7D9FE98F3B5AA514E8 /* CoreTelephony.framework */; };\n\t\tCF8968D878454B5BAE07037D28947D93 /* GDTCOREvent+GDTCCTSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EF33965A3795DEE7A531EC8C56300B4 /* GDTCOREvent+GDTCCTSupport.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tD00ADB6F62DCD79FF4AE5477907E4B08 /* FIRDiagnosticsData.h in Headers */ = {isa = PBXBuildFile; fileRef = EE1ABBBCF34996AB6FAD3A7099D80CF5 /* FIRDiagnosticsData.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tD0C26B55798A5A3824920D1D426AEE51 /* FIRInstallationsAPIService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A35F8BE947883A35C48CDFFF5BACB72 /* FIRInstallationsAPIService.m */; };\n\t\tD1D3F45D15F5C5775073C7747ED94B55 /* GULSceneDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = E19DD2593A51A0FEDEA7A4688C0D8645 /* GULSceneDelegateSwizzler.m */; };\n\t\tD288AE30D1159545D1E3CDB721EA5841 /* GoogleDataTransport-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 881ACDC9E0325D12479F43AD079D1CBB /* GoogleDataTransport-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD3212FE5382F2D56A8C80829D8780188 /* FirebaseCore-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FB1BA9182BB6D6E47E4DD049005A29 /* FirebaseCore-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD4D727FEE4399BCF942F3512A383917B /* FIRInstallationsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = A328CD57DBA12543441049EBF409F205 /* FIRInstallationsStore.m */; };\n\t\tD556C63635E7A83C7A9B04FB104F7339 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = CA1E5C47B1D161A6D7326A63F73039E1 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD5573400F45ACFA5316D7AC2BA779056 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = B3310E7F0BD29950EA79269F8864E7B0 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tD63055B89D739A7EA319FBE861ADEED5 /* FBLPromise+Reduce.h in Headers */ = {isa = PBXBuildFile; fileRef = F1A5B63B766812910C3FC66A4D5BD359 /* FBLPromise+Reduce.h */; };\n\t\tD6742E4A0E030524C50C7BFD7FEB7292 /* FBLPromise+Testing.m in Sources */ = {isa = PBXBuildFile; fileRef = 00F035755BD3D0F891EF8F32718F2E74 /* FBLPromise+Testing.m */; };\n\t\tD68F08F717E95BABFB43AE705D943426 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 18281399F797A6B19033D53D2B0992E3 /* SDWebImageDownloader.m */; };\n\t\tD7068278536821417BB567EEED782F73 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5514ED015845BE4DF10DF85BF4983A59 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tD7BA04ADFE3104907F100E9370184A65 /* UIImage+ExtendedCacheData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C388E0E2142C8BAB1FBE711F1A33688 /* UIImage+ExtendedCacheData.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD7D077F0FA5CAC32ACB65372453C701F /* SDImageAWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = F59DA2817374C9606A05E0D57A6993AB /* SDImageAWebPCoder.m */; };\n\t\tD88076DA0593D2835645CA5A92FFA37C /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = B4A0C1F3F59FF0ECC737E3A22B64F7F0 /* SDAnimatedImageView.m */; };\n\t\tD88E2E3BC8A27A085ABC3AF8AF4C7F86 /* GULSecureCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 476A318EB831BFCD3B77190E73149735 /* GULSecureCoding.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD975B260AB44081399BCB612916CE675 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C8CC6A0CB955A36A57FB8DC86DC7122B /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD9B8E5DA0091D211AACED8612BA1153B /* GULNetworkLoggerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DC79300A6D291A17A3804A3511C41D9B /* GULNetworkLoggerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tD9CFDF531DF1146A1A3E694A360CB0A7 /* FIRInstallationsHTTPError.m in Sources */ = {isa = PBXBuildFile; fileRef = B5E3DBB2F100E0A299BCFC77EBC69A7E /* FIRInstallationsHTTPError.m */; };\n\t\tDA16EA1A389CE66496E2FCBCCDA0D0ED /* GDTCORPlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 809CE53E4184869CD1D4910C0A359884 /* GDTCORPlatform.m */; };\n\t\tDB048A769D5DB1BE84466C9EA4EBBF1B /* GULLoggerCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 08586FD84613D5B8D0037AF3714A8D9F /* GULLoggerCodes.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tDB61822BEA875B413C858E1166590C9F /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1925BCD73D2687C697D5448145F92862 /* SDWebImageDownloaderOperation.m */; };\n\t\tDB68D9AFA817850ED9EBBE7F3F378AF5 /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C87340AB40E7872EBB32D3E37F151B98 /* SDImageCodersManager.m */; };\n\t\tDBBAC864AD405BED53782364E0F0D5F3 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A023925AC3740397148C89A37EA72B8 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tDBCEB21658D3825FA81F27822AADAD11 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8C7297F9F351E0DFB107547CC454F81B /* en.lproj */; };\n\t\tDBDF09CBE34BC99BD85677273C4B6296 /* GULNetworkInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 18D28D4E30FB28D835221C737B53B7E0 /* GULNetworkInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tDC8E06FD7CA80D1461C4E73105FD45AC /* FBLPromise+Catch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BC2750E276CE3D6725F398532CEB28B /* FBLPromise+Catch.h */; };\n\t\tDD5D476FF518ACB3772717620E7D393A /* pl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0A31AE9C96B6817F39D60A3B4CB0E787 /* pl.lproj */; };\n\t\tDD9CF5BA0F1AF0448E29B8E7FE427C20 /* GULNetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = BA44BA3AD4121BF4B3BA03128355DA0A /* GULNetworkConstants.m */; };\n\t\tDE0BA471FB4FC10C0B25BDE4F22F5B76 /* SDWebImageDownloaderDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 68332238690458AE7A254B6097B8BD22 /* SDWebImageDownloaderDecryptor.m */; };\n\t\tDE2AB52CD8EFC8E819452F737447F4B0 /* FirebaseCoreDiagnostics-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D955AAA9A402178AFCBD9F07B289BECB /* FirebaseCoreDiagnostics-dummy.m */; };\n\t\tDE3AC691EE0E078459ECBE58059F1260 /* NSURLSession+GULPromises.h in Headers */ = {isa = PBXBuildFile; fileRef = 2494BB0409778ADBC0785D40DE703573 /* NSURLSession+GULPromises.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tDECA57AF64C5C257919649ECBB75F0B9 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 57A489F83B821E73C9F898D59FD839D5 /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tDEE74CD0E78DE0DB4056A8A3244B6ED1 /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 2186649006C5A621B8BA7DDCC5C27AB4 /* UIImage+GIF.m */; };\n\t\tE20DFCFF1B1EA67C678445D94AFC6782 /* GDTCORPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = DC55F3B02A125C1D8CBC59176095F043 /* GDTCORPlatform.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tE2657EA2FA2825ED6DBE1C1BFEA5907C /* GDTCCTUploadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F469B9832F15DBDE81EB155A43226B /* GDTCCTUploadOperation.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tE33A7CDF3107CD3426ADD0D906100CD4 /* SDImageHEICCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 483340B3D5102879F6C45F55BD02FF1E /* SDImageHEICCoder.m */; };\n\t\tE4153F4FB8707C1B1B62815836B8F358 /* GDTCCTNanopbHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8190044D8F103421DED7166A530383 /* GDTCCTNanopbHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tE41BE1E98D3A9AADCA187D34E0A0F1F0 /* FBLPromise+Recover.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 6806286AE468436D210DE24F56FFD7A2 /* FBLPromise+Recover.h */; };\n\t\tE4AF87F8012F919F00E2E8698A1A3C33 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = D6368995E44A12ED775E22745EE36796 /* SDWebImageCompat.m */; };\n\t\tE4CA0B80D962B7042730CCA24DF7A6CE /* Appirater.h in Headers */ = {isa = PBXBuildFile; fileRef = 350451991B16222891CB7702FAA4C26A /* Appirater.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE50990C8CCC727688A0EC4D123CDD295 /* nanopb-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 29AE365492E6E96E5708A9AD6E31746F /* nanopb-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE515780850EBAD40342EBF2997BFC2D2 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 62E087DDBCC7CE3CA61BACD11EE3931E /* SDWebImage.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE556832E0C191FCFABB9E97C87D243EF /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 579C123C87D8545B91CD64649918A148 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tE5C6051933677CDF392BF6356271A92E /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1416C43E8091C630E21516532F691796 /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE5C7FA5788C38AD0308CC3B712DD53A2 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = E80E4257A841B7AA5C92B2CB19B16F0B /* fr.lproj */; };\n\t\tE62B328C763183320A9105E6E8EB1860 /* GULHeartbeatDateStorageUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = BB06018D1785388A5C83E9EF4D57ED16 /* GULHeartbeatDateStorageUserDefaults.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE78F445F25943A96E2AE21A4AD7EEA67 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F0F742A22FC71CED5A18A108E514A8B /* pb_decode.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE7AB534DD8C859013ADE863B6D2CBA7D /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0323C2AB5A72DF893829A51D8F181F49 /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tE7FA1E1CD066D0335A95376C73E3F8ED /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = B83BA9762F2888371B5ADE95B066DCB4 /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE8CE28499C17965A931605D4F47AAEBF /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 2264D3828F48F1D2D87C73BE181475A2 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE8D519B63C2077979F799769F9A35072 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 98368FFE6F3A2C1CB4B79C360D245377 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tE8D668C3BC3581332C51EAE1359D2022 /* GULKeychainStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = A40C76162676EC9A3E0C33C1F29CB93F /* GULKeychainStorage.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE92BFF50D3F84D5D8BA6E845FAEF8DA3 /* FBLPromisePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 278F2C97E692BBEB7227CFD22EE4333A /* FBLPromisePrivate.h */; };\n\t\tE9358141369A46CD15097FD5B56279AC /* hy.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9FB349B1B1D5B036FA774AC001CEBCB4 /* hy.lproj */; };\n\t\tE96C68381CF2BD5D022DE8DC47200C53 /* FBLPromise+Async.m in Sources */ = {isa = PBXBuildFile; fileRef = 068EFE7F14EBD412EB944B5B38CE3CB3 /* FBLPromise+Async.m */; };\n\t\tE9AD74230A2E90C1FE84024CA1917ACC /* GULNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B52265053B7A072C3CFD52774A4E64 /* GULNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE9BF3DACAEE3509B06DBDA16478ED73F /* GoogleDataTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = 28859EE1F335E36BD76813D7AC4608D9 /* GoogleDataTransport.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE9CF46857D61D2A8AF4C3722C27C61C6 /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E3D624D33EC772ADA4910D9A6A067AD /* SDImageCoderHelper.m */; };\n\t\tEAABECDA1C6109F989C004C1DCEBE07E /* GDTCORFlatFileStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 736D3261A8A25DCBBECD54A6C5C48166 /* GDTCORFlatFileStorage.m */; };\n\t\tEB3A214553ED6CFAF04498A2DBAFE0EF /* GDTCOREventDataObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C31DC7C6755337262C1BDDB6677C635 /* GDTCOREventDataObject.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tECB05ADC1FE7A52E0D9ACCB9B027EF2B /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDF404E683FC3DE61DCE91FF8B1E0842 /* pb_encode.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tED39F6A91DF2FC44DD73DEE50BF7D393 /* FIRInstallationsAuthTokenResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA30DDE545C3AB8E5A8BCD08CA5B923 /* FIRInstallationsAuthTokenResultInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tED9E9EC31A5AC510BBF8568956DCA102 /* GDTCCTCompressionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 219546DB6A6974432E1E0283F24A3329 /* GDTCCTCompressionHelper.m */; };\n\t\tEDDBA077EC19453A85E90DBC87AB8C2B /* FBLPromise.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = F35AA80907A78AC92F34C61F368248E7 /* FBLPromise.h */; };\n\t\tEE207039B394C5D8BBA475814B4E9830 /* GULNetworkURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 142559AF1A21A92BBB53100F317735FE /* GULNetworkURLSession.m */; };\n\t\tEF17DB58C7BE9A3304D466EF87041014 /* FIRCoreDiagnostics.m in Sources */ = {isa = PBXBuildFile; fileRef = 45D88DFE4BAAB878102C9DB69C90E1EE /* FIRCoreDiagnostics.m */; };\n\t\tEF75B2C28FA102334A044548123860E2 /* FIRCoreDiagnosticsData.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC1202619BDEC6CB408DEFB276233E1 /* FIRCoreDiagnosticsData.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tEF78F3AE3374BED3DC0FBF7B944B9057 /* GDTCCTUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = DEEA9E90B955F3FF75BD5CC9F8F49886 /* GDTCCTUploader.m */; };\n\t\tEFAB05A7F5A8FC35E27F219708D544AD /* FIRInstallationsStoredAuthToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 4187F6DA61736F8AD4201616D23D8061 /* FIRInstallationsStoredAuthToken.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tF02178012C14330925DC2AB2DF60482B /* GDTCORTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = 193B43A46E5628F605735E9C2EB9C5B1 /* GDTCORTransport.m */; };\n\t\tF077E74D9855D0D7FCF570F8E8ED4A1E /* SDFileAttributeHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE29B50BED2D3B4F195FBAF219817D9 /* SDFileAttributeHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tF0E28CEF30861F3589A4A662CEA76D80 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F2CD38DB179EE57D03D1E4AE0BBA047 /* SDImageGraphics.m */; };\n\t\tF10FCC767B08C019DEE8FFB1516299EA /* GULAppDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C35CA5CB6C0053B485FCFDFD30A1662 /* GULAppDelegateSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF1372E076B4B28D2923EA22ED4D6DFCA /* FirebaseInstallations.h in Headers */ = {isa = PBXBuildFile; fileRef = 183B8EEF2BA8C735371935889864D6B7 /* FirebaseInstallations.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF161112B04B9AC7D276D9F588BA6E313 /* SDDeviceHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FC23427538EE1DBB11F5EBBAAB6A513D /* SDDeviceHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tF17E3C439BBF49E6486B54C84DD0C190 /* FIRCoreDiagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = A2CD1B738ABAB7BA344D7969860B494C /* FIRCoreDiagnostics.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF1CFF76FC50BF026284051C6CAB9B389 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8CDC01574AEDC72431059BB3FDE16F59 /* de.lproj */; };\n\t\tF1F24427266F56690C90DBC258A8E712 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */; };\n\t\tF269152E11B82F412D3BD37F3E13E6C1 /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = D8BE8FDFF77007F5278B6A0E5BC01E6A /* pb_decode.c */; settings = {COMPILER_FLAGS = \"-fno-objc-arc -fno-objc-arc\"; }; };\n\t\tF270EDD68B781B1BE74FE134DADC2FE1 /* FBLPromise+Await.m in Sources */ = {isa = PBXBuildFile; fileRef = EC847DD51A92AE89F533B4312E344982 /* FBLPromise+Await.m */; };\n\t\tF2B107BBDDF18E390CE5F31FEAC37B5B /* FIRInstallationsErrorUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 6237C8DA5406A972EAFEEC2CB46AA910 /* FIRInstallationsErrorUtil.m */; };\n\t\tF2EC479E66AABB97FBFB289846C339EF /* GULURLSessionDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CE0245F2D926AF50D3BFBA488887C1 /* GULURLSessionDataResponse.m */; };\n\t\tF3824BB13CE13E5071200A50EA544D21 /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FF8CD99087C3A386C87B8B64F6814912 /* nanopb-dummy.m */; };\n\t\tF3B6F6BEAD0AFF34EAE82B95A7C56037 /* GDTCORLifecycle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E80D119146AEB6CE705A642B0A4012D /* GDTCORLifecycle.m */; };\n\t\tF3BF79D7923FCC0DBCCE33CC97D7134B /* cct.nanopb.c in Sources */ = {isa = PBXBuildFile; fileRef = 47C2768639337908388E00A97B570D97 /* cct.nanopb.c */; };\n\t\tF417C8E4B3D73E496E4764CF2FE9EDDD /* FirebaseCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BB2E5C745E6BEBDF556017B5389A3F8 /* FirebaseCore.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF421606C12494E53B7F6B5EAE13352F1 /* vi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = C6911F1DC733532D91E29D6B0433A787 /* vi.lproj */; };\n\t\tF4232EBD3CD57E497ECED11C9BECC958 /* GDTCORUploadCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AB43C522E93B03C169E99C63451C091 /* GDTCORUploadCoordinator.m */; };\n\t\tF4310C2EF76937100D2C74EBB593BFC4 /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 75E9E1284F8AE50551FF56600DDDCEBF /* GULSwizzler.m */; };\n\t\tF463DEB020D5C466D4613947AE4BE16F /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3808D78CAA3EAA14B869A1667210193C /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF4811CFAC05932CE436CC2C32BAD91E6 /* UIColor+SDHexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D628BFBCC6276E5E277ED26143A0529 /* UIColor+SDHexString.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tF497CD01EF6568475FD363A248D78A4B /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = A62E17FF50F14A446211D0E0BA00FD24 /* UIImage+ForceDecode.m */; };\n\t\tF4BE3CF05C223248D90AC0F46BAAB9FF /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4953F3D24A404D00A99D8A29BE61104C /* FIRLogger.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tF56971E69EB803E06C38E2751620E1E8 /* ms.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 867CE4FF42F759E76A71FEF4453E8079 /* ms.lproj */; };\n\t\tF5734286C309C6E2FF84E06DA25F51EF /* FBLPromise+Race.h in Headers */ = {isa = PBXBuildFile; fileRef = 447B191325C26D8C11C3D317EC3FBAA8 /* FBLPromise+Race.h */; };\n\t\tF595C8E6D01D6FFEC46D540A198AD062 /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA476F642687D5FC7AA27BDDA27DEBC /* FIROptions.m */; };\n\t\tF646BABB56E9E66692865720E3FB71DA /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = A8689F656BCD2DE359141CDE820E425F /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF7289F163C285103D6CCAB39447153CA /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = F53274C0B6BDFB6F2402643CF71B2F77 /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF8FE94E2FE6E57F616878424F22528CA /* GDTCORTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = B06B80A4EE003DEDFC1F89E8907C6C16 /* GDTCORTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tFA10A9A289B0F3E86CCCE9E2A7E94EF2 /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = EC9689AF5C4E7C5E057221C42B74F092 /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\tFA1435956493F6C517F5A097360C11D2 /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 06D5568DC434FEF3EF84595EE271B95A /* pb_common.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tFA24FF48B63577BA0DC691E35C9F7FA9 /* FIRFirebaseUserAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 893980C67675F297617FB935213E4671 /* FIRFirebaseUserAgent.m */; };\n\t\tFA9814200D820A4CB4EE5032B8E5973A /* FBLPromise+Validate.m in Sources */ = {isa = PBXBuildFile; fileRef = 281F885809D3382CEFAC6F78D5E16CA0 /* FBLPromise+Validate.m */; };\n\t\tFB0E00B080CD4EE84EF1BF65C47F3185 /* GULKeychainUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F80FBEC0B534E33030C9ECCABDD9BE62 /* GULKeychainUtils.m */; };\n\t\tFB359FC2B8375E01A8A8F84D3C50EE82 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 25BB086F66AE0B62674631094FA38DB9 /* SDWebImageDownloaderResponseModifier.m */; };\n\t\tFE0189D2FE038AD82C4CCF5A801A50A3 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E74C0A2D416186897FBBC33BC5608B /* SDDiskCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tFE05A1BF611E69C94BC7A9EADBE10B2F /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = ACAACBFBB72CC5DBA48E5939C7C05CBB /* SDWebImageDownloaderConfig.m */; };\n\t\tFE3E0BB2B4E000770F2FC5CB9FDB9097 /* FBLPromise+Catch.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 1BC2750E276CE3D6725F398532CEB28B /* FBLPromise+Catch.h */; };\n\t\tFE42751E23F9C15EB7A8D8D0569D95F1 /* GDTCOREvent+GDTCCTSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 135A77B30A220981214A503DF9FB9D3A /* GDTCOREvent+GDTCCTSupport.m */; };\n\t\tFE4845B6FDD260059CDF9E26965CA31B /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA24773B096CF90111EA4F2AA2C464D /* SDWebImageManager.m */; };\n\t\tFE4C5664159A808BD7984CB35D69CFAB /* GDTCORFlatFileStorage+Promises.m in Sources */ = {isa = PBXBuildFile; fileRef = 79AB37844F04B4F0CF83A66B9FBD9175 /* GDTCORFlatFileStorage+Promises.m */; };\n\t\tFE7AB9DA939B0E528ED9F339C6DCC201 /* GDTCORFlatFileStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B1EB303FD52ADD9ABA791AD8C33496F /* GDTCORFlatFileStorage.h */; settings = {ATTRIBUTES = (Project, ); }; };\n\t\tFED292AF8AD5924263FC0A8D0B8AF26D /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 83495546D2D6077CD99D793135E8A7EC /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tFF66F3E7374A9398D5B08AA23273BC0E /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D682D19C50EF105FF8EF05D677CA964 /* NSData+ImageContentType.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t017C8F825B2F93FFCB2F173D75B0623D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2;\n\t\t\tremoteInfo = FirebaseCore;\n\t\t};\n\t\t019A23FE239BD69A9982DFBA9D477A03 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t0CCABEB11C23BF29F6C694531602F292 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 620E05868772C10B4920DC7E324F2C87;\n\t\t\tremoteInfo = FirebaseCoreDiagnostics;\n\t\t};\n\t\t107F5D2853F4AAFB42A81181FDB1E1DD /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = B53D977A951AFC38B21751B706C1DF83;\n\t\t\tremoteInfo = GoogleAppMeasurement;\n\t\t};\n\t\t13D9CFCD8B7BD73E7C9DE7108252C17E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t179483F0AEF1C518BA00B35B81A30639 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429;\n\t\t\tremoteInfo = SDWebImage;\n\t\t};\n\t\t1CA617FF6BC13C778A37FCD64EB5171C /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3;\n\t\t\tremoteInfo = nanopb;\n\t\t};\n\t\t1EA446CB14655B63DDF173D56348CF0C /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t299349E1BCD52B21826853337CF6A1C4 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = C49E7A4D59E5C8BE8DE9FB1EFB150185;\n\t\t\tremoteInfo = FirebaseAnalytics;\n\t\t};\n\t\t2F4219A4D7ABBC820468F9119F658E52 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t3068F1E435C57EA32BE211ECBD073BC6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3;\n\t\t\tremoteInfo = nanopb;\n\t\t};\n\t\t3EABBDC05624720577DC38CFFE35516E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = C49E7A4D59E5C8BE8DE9FB1EFB150185;\n\t\t\tremoteInfo = FirebaseAnalytics;\n\t\t};\n\t\t41A499968FD5AC9EAE0375E50C6432F6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = E56E80821D169C98E99A62EBCBC60B2C;\n\t\t\tremoteInfo = \"Appirater-Appirater\";\n\t\t};\n\t\t42781FFD2FA1F2EDE97339A0136EDCD2 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3;\n\t\t\tremoteInfo = nanopb;\n\t\t};\n\t\t4605540DE00C391F1995371BAF739423 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8;\n\t\t\tremoteInfo = PromisesObjC;\n\t\t};\n\t\t4AE8370CEECA1D1E24DE01B095051767 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = CE9FA8ACD6205C77B753798CD736FAEF;\n\t\t\tremoteInfo = Appirater;\n\t\t};\n\t\t4AF8ADE52426F73572B9DCF5DAF9E166 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 620E05868772C10B4920DC7E324F2C87;\n\t\t\tremoteInfo = FirebaseCoreDiagnostics;\n\t\t};\n\t\t5A2B9082AADF585B09978FD211A672E2 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2;\n\t\t\tremoteInfo = FirebaseCore;\n\t\t};\n\t\t5ED9D700A988839F2AED6A8424F05591 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t64BB0EA73EC74FA5D442D982996CEE10 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t6536CA055DA2CE1A6BC4ECCA78BE9E3D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D;\n\t\t\tremoteInfo = GoogleUtilities;\n\t\t};\n\t\t66522F2C26FB2DA91D7F26867BBFD45D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3;\n\t\t\tremoteInfo = nanopb;\n\t\t};\n\t\t75A52B3F3AF7540549FE42CCD7D77E21 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8;\n\t\t\tremoteInfo = PromisesObjC;\n\t\t};\n\t\t8C5626444E1A84EEEC6B1F447CDC3835 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 87803597EB3F20FC46472B85392EC4FD;\n\t\t\tremoteInfo = FirebaseInstallations;\n\t\t};\n\t\tA977FEFABC64BF1427A465B2BB858E38 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3;\n\t\t\tremoteInfo = nanopb;\n\t\t};\n\t\tB16C5D96A221C36E30318D4000EF80F2 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2;\n\t\t\tremoteInfo = FirebaseCore;\n\t\t};\n\t\tBC0ECFA70CF24D5AD9BA339E3D2F9476 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 87803597EB3F20FC46472B85392EC4FD;\n\t\t\tremoteInfo = FirebaseInstallations;\n\t\t};\n\t\tD09E65E94D05A8E445515725C350BE0D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 5C0371EE948D0357B8EE0E34ABB44BF0;\n\t\t\tremoteInfo = GoogleDataTransport;\n\t\t};\n\t\tD34555543663478CC798C373DD6F3097 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 072CEA044D2EF26F03496D5996BBF59F;\n\t\t\tremoteInfo = Firebase;\n\t\t};\n\t\tE01CEC52D49138FF303416CCAC27428F /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 5C0371EE948D0357B8EE0E34ABB44BF0;\n\t\t\tremoteInfo = GoogleDataTransport;\n\t\t};\n\t\tE36D5F0B788F0DF60B17237B05CF025C /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8;\n\t\t\tremoteInfo = PromisesObjC;\n\t\t};\n\t\tECA56526923E8FA4E91B31255FA8A6C0 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2;\n\t\t\tremoteInfo = FirebaseCore;\n\t\t};\n\t\tFDD63A1FAEDABC2F1E1949DCC5AF3165 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = B53D977A951AFC38B21751B706C1DF83;\n\t\t\tremoteInfo = GoogleAppMeasurement;\n\t\t};\n\t\tFF55F8919770C873139545DDB9B82E39 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8;\n\t\t\tremoteInfo = PromisesObjC;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t88441CA33AAB2BA346D73F3E23B24BC1 /* Copy . Public Headers */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"$(PUBLIC_HEADERS_FOLDER_PATH)/.\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t\tEDDBA077EC19453A85E90DBC87AB8C2B /* FBLPromise.h in Copy . Public Headers */,\n\t\t\t\tC6B19B09709899C1D9F1062017C9E497 /* FBLPromise+All.h in Copy . Public Headers */,\n\t\t\t\t4634DFDEF1A08A4C90EF8CCDBEF04003 /* FBLPromise+Always.h in Copy . Public Headers */,\n\t\t\t\tC2FF212194FBD30D199C4958030720D1 /* FBLPromise+Any.h in Copy . Public Headers */,\n\t\t\t\tBAF01AD02AE3A4066A56C40095FE11F6 /* FBLPromise+Async.h in Copy . Public Headers */,\n\t\t\t\t18191A26B494BB7777A6420722A46B29 /* FBLPromise+Await.h in Copy . Public Headers */,\n\t\t\t\tFE3E0BB2B4E000770F2FC5CB9FDB9097 /* FBLPromise+Catch.h in Copy . Public Headers */,\n\t\t\t\tB502D35637FD94ED622BFEE8D65D2E14 /* FBLPromise+Delay.h in Copy . Public Headers */,\n\t\t\t\t1AF4F328009E37FD64DA9CA51CC90932 /* FBLPromise+Do.h in Copy . Public Headers */,\n\t\t\t\t842007158292E13DF5B3878A89BD4727 /* FBLPromise+Race.h in Copy . Public Headers */,\n\t\t\t\tE41BE1E98D3A9AADCA187D34E0A0F1F0 /* FBLPromise+Recover.h in Copy . Public Headers */,\n\t\t\t\t3A899B9C5A8C258ED40829D2BBB6CF78 /* FBLPromise+Reduce.h in Copy . Public Headers */,\n\t\t\t\tB99344EDD10321BF98BD222F9CA56993 /* FBLPromise+Retry.h in Copy . Public Headers */,\n\t\t\t\t3E5A84FD8D62B473AF24D16F36112D81 /* FBLPromise+Testing.h in Copy . Public Headers */,\n\t\t\t\t047DCD22E37D894B69D095C8E537819F /* FBLPromise+Then.h in Copy . Public Headers */,\n\t\t\t\tAB471FF0764CF95AAC04F43A451C54D5 /* FBLPromise+Timeout.h in Copy . Public Headers */,\n\t\t\t\t7A0703CD6D58504249D27BB436F68B39 /* FBLPromise+Validate.h in Copy . Public Headers */,\n\t\t\t\t04AA4C56A3620BE2A70364D47CE08AF3 /* FBLPromise+Wrap.h in Copy . Public Headers */,\n\t\t\t\tC22DB2BCE626C82201E5409BD16B0C97 /* FBLPromiseError.h in Copy . Public Headers */,\n\t\t\t\t620EBEBCDCF8233A6CED99BD83B4C8D1 /* FBLPromises.h in Copy . Public Headers */,\n\t\t\t);\n\t\t\tname = \"Copy . Public Headers\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC1CF4B15D01CD8E372C0028680453569 /* Copy . Private Headers */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"$(PRIVATE_HEADERS_FOLDER_PATH)/.\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t\t276A3E64698148850F514C10F440DDD0 /* FBLPromisePrivate.h in Copy . Private Headers */,\n\t\t\t);\n\t\t\tname = \"Copy . Private Headers\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t00287C1BECC76217689476B210B41A36 /* FIRComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponent.m; path = FirebaseCore/Sources/FIRComponent.m; sourceTree = \"<group>\"; };\n\t\t00F035755BD3D0F891EF8F32718F2E74 /* FBLPromise+Testing.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Testing.m\"; path = \"Sources/FBLPromises/FBLPromise+Testing.m\"; sourceTree = \"<group>\"; };\n\t\t018833202B971E61CF36DA9775AED769 /* GDTCCTUploader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCCTUploader.h; path = GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploader.h; sourceTree = \"<group>\"; };\n\t\t02EBCB4694F493398B30D145521759BB /* Pods-Spotify.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = \"Pods-Spotify.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t030D92BA7629B33D7DEDDD755B2FB34B /* sv.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = sv.lproj; sourceTree = \"<group>\"; };\n\t\t0323C2AB5A72DF893829A51D8F181F49 /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Sources/Private/FIROptionsInternal.h; sourceTree = \"<group>\"; };\n\t\t0338A87088B87F5A5D1BB03CA2AB274B /* GDTCORRegistrar_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORRegistrar_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h; sourceTree = \"<group>\"; };\n\t\t036C70BC91046AD6992330F90128AC83 /* FirebaseInstallations.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseInstallations.modulemap; sourceTree = \"<group>\"; };\n\t\t04119D68F2961D5912F24F5066E00D0D /* FirebaseAnalytics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t0440093C278700F6A5362B45AD5DBC91 /* SDAsyncBlockOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAsyncBlockOperation.h; path = SDWebImage/Private/SDAsyncBlockOperation.h; sourceTree = \"<group>\"; };\n\t\t0466C52ED49E6E1C863BAFB6E1AE5B92 /* Appirater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = Appirater.m; sourceTree = \"<group>\"; };\n\t\t0502AAFCB22CA8A06A21C20517BE89B4 /* GULNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetwork.m; path = GoogleUtilities/Network/GULNetwork.m; sourceTree = \"<group>\"; };\n\t\t05850FDD1539ACB6AB1C9DB0142B8403 /* GULHeartbeatDateStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorage.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h; sourceTree = \"<group>\"; };\n\t\t061F4EB74D749A7F360F62B20F46294A /* nanopb-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"nanopb-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t068EFE7F14EBD412EB944B5B38CE3CB3 /* FBLPromise+Async.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Async.m\"; path = \"Sources/FBLPromises/FBLPromise+Async.m\"; sourceTree = \"<group>\"; };\n\t\t06D5568DC434FEF3EF84595EE271B95A /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = \"<group>\"; };\n\t\t06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = nanopb; path = nanopb.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t0720E29DA86F4D52C08D6942FFEF190A /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = FirebaseCore/Sources/FIRLogger.m; sourceTree = \"<group>\"; };\n\t\t073BC434BDEB48DDF3B92DF041D277CE /* FirebaseCoreDiagnostics-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"FirebaseCoreDiagnostics-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t079B6435FC4625DBC4A439EDF7FD5844 /* SDWebImageError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageError.m; path = SDWebImage/Core/SDWebImageError.m; sourceTree = \"<group>\"; };\n\t\t07E9568C4EE8BF77740269310C486888 /* FIRInstallations.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallations.m; path = FirebaseInstallations/Source/Library/FIRInstallations.m; sourceTree = \"<group>\"; };\n\t\t08586FD84613D5B8D0037AF3714A8D9F /* GULLoggerCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerCodes.h; path = GoogleUtilities/Common/GULLoggerCodes.h; sourceTree = \"<group>\"; };\n\t\t08F469B9832F15DBDE81EB155A43226B /* GDTCCTUploadOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCCTUploadOperation.h; path = GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTUploadOperation.h; sourceTree = \"<group>\"; };\n\t\t09F19A6EF0F8A7D0CDEEA09F1E90D4A1 /* SDWebImageTransition.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageTransition.m; path = SDWebImage/Core/SDWebImageTransition.m; sourceTree = \"<group>\"; };\n\t\t0A31AE9C96B6817F39D60A3B4CB0E787 /* pl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = pl.lproj; sourceTree = \"<group>\"; };\n\t\t0ADF13875C4D61EE62B5265D074DB171 /* GDTCORTransformer_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORTransformer_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer_Private.h; sourceTree = \"<group>\"; };\n\t\t0B538C0DED9A96F51790585E9AF03D97 /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h; sourceTree = \"<group>\"; };\n\t\t0B722DB0B3C51C3645037E3399784B69 /* SDMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDMemoryCache.h; path = SDWebImage/Core/SDMemoryCache.h; sourceTree = \"<group>\"; };\n\t\t0BBCA689ED4AD568D1203A32DDCB2654 /* SDWebImageOptionsProcessor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageOptionsProcessor.m; path = SDWebImage/Core/SDWebImageOptionsProcessor.m; sourceTree = \"<group>\"; };\n\t\t0DFCC2FB818BA3289E85B84DD2F068A3 /* FBLPromise+Always.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Always.m\"; path = \"Sources/FBLPromises/FBLPromise+Always.m\"; sourceTree = \"<group>\"; };\n\t\t0E3D719558B6C623CB196272CE80D92B /* FIRInstallationsHTTPError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsHTTPError.h; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h; sourceTree = \"<group>\"; };\n\t\t0E80D119146AEB6CE705A642B0A4012D /* GDTCORLifecycle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORLifecycle.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORLifecycle.m; sourceTree = \"<group>\"; };\n\t\t0F824E440C097E5A5FE69CFBC7293F15 /* SDImageTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageTransformer.h; path = SDWebImage/Core/SDImageTransformer.h; sourceTree = \"<group>\"; };\n\t\t0FC4393F5EB9D10CAC25D438B9ECB2A3 /* SDGraphicsImageRenderer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDGraphicsImageRenderer.m; path = SDWebImage/Core/SDGraphicsImageRenderer.m; sourceTree = \"<group>\"; };\n\t\t0FCDB01EEB669605F883EA4E79E56AD2 /* UIImage+ForceDecode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+ForceDecode.h\"; path = \"SDWebImage/Core/UIImage+ForceDecode.h\"; sourceTree = \"<group>\"; };\n\t\t11DC645818CEA0B49FB41D10974587E3 /* GDTCCTUploadOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCCTUploadOperation.m; path = GoogleDataTransport/GDTCCTLibrary/GDTCCTUploadOperation.m; sourceTree = \"<group>\"; };\n\t\t135A77B30A220981214A503DF9FB9D3A /* GDTCOREvent+GDTCCTSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"GDTCOREvent+GDTCCTSupport.m\"; path = \"GoogleDataTransport/GDTCCTLibrary/GDTCOREvent+GDTCCTSupport.m\"; sourceTree = \"<group>\"; };\n\t\t13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseInstallations; path = FirebaseInstallations.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t1416C43E8091C630E21516532F691796 /* SDImageIOCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOCoder.h; path = SDWebImage/Core/SDImageIOCoder.h; sourceTree = \"<group>\"; };\n\t\t142559AF1A21A92BBB53100F317735FE /* GULNetworkURLSession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkURLSession.m; path = GoogleUtilities/Network/GULNetworkURLSession.m; sourceTree = \"<group>\"; };\n\t\t14DB6413E93A38460FE253FC259C28D5 /* UIColor+SDHexString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIColor+SDHexString.m\"; path = \"SDWebImage/Private/UIColor+SDHexString.m\"; sourceTree = \"<group>\"; };\n\t\t15C9B0DD52D5C611E1AB4BB7A9A92DF5 /* pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb.h; sourceTree = \"<group>\"; };\n\t\t15F02952828900F1CC5E66B83274F6E0 /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Sources/Private/FIROptionsInternal.h; sourceTree = \"<group>\"; };\n\t\t161553D9C89B2C716D3056754C86B4A5 /* GoogleAppMeasurement-xcframeworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = \"GoogleAppMeasurement-xcframeworks.sh\"; sourceTree = \"<group>\"; };\n\t\t16A5A619D3393C3652027A63F8D6406E /* GULAppDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m; sourceTree = \"<group>\"; };\n\t\t17A959EECDBC8B53DAF62371054DAAE9 /* SDAnimatedImagePlayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImagePlayer.m; path = SDWebImage/Core/SDAnimatedImagePlayer.m; sourceTree = \"<group>\"; };\n\t\t18281399F797A6B19033D53D2B0992E3 /* SDWebImageDownloader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloader.m; path = SDWebImage/Core/SDWebImageDownloader.m; sourceTree = \"<group>\"; };\n\t\t183B8EEF2BA8C735371935889864D6B7 /* FirebaseInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h; sourceTree = \"<group>\"; };\n\t\t18637DFB49F868B5320F06FCD27ABD99 /* FBLPromise+Then.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Then.m\"; path = \"Sources/FBLPromises/FBLPromise+Then.m\"; sourceTree = \"<group>\"; };\n\t\t18D28D4E30FB28D835221C737B53B7E0 /* GULNetworkInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkInternal.h; path = GoogleUtilities/Network/GULNetworkInternal.h; sourceTree = \"<group>\"; };\n\t\t1925BCD73D2687C697D5448145F92862 /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderOperation.m; path = SDWebImage/Core/SDWebImageDownloaderOperation.m; sourceTree = \"<group>\"; };\n\t\t193B43A46E5628F605735E9C2EB9C5B1 /* GDTCORTransport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORTransport.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORTransport.m; sourceTree = \"<group>\"; };\n\t\t1A58961C9BBD35E7B60ECDB62E56F7DC /* firebasecore.nanopb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = firebasecore.nanopb.h; path = Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h; sourceTree = \"<group>\"; };\n\t\t1A6FE3762E8CAD647386716CD1698F48 /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"GULReachabilityChecker+Internal.h\"; path = \"GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h\"; sourceTree = \"<group>\"; };\n\t\t1AA24773B096CF90111EA4F2AA2C464D /* SDWebImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageManager.m; path = SDWebImage/Core/SDWebImageManager.m; sourceTree = \"<group>\"; };\n\t\t1AA30DDE545C3AB8E5A8BCD08CA5B923 /* FIRInstallationsAuthTokenResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAuthTokenResultInternal.h; path = FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h; sourceTree = \"<group>\"; };\n\t\t1AA6F310E602B6F29B722C01961258A4 /* SDImageCachesManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManager.h; path = SDWebImage/Core/SDImageCachesManager.h; sourceTree = \"<group>\"; };\n\t\t1B185568A19C67E5278D6DB507473C2B /* FIRComponentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentType.m; path = FirebaseCore/Sources/FIRComponentType.m; sourceTree = \"<group>\"; };\n\t\t1BC2750E276CE3D6725F398532CEB28B /* FBLPromise+Catch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Catch.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Catch.h\"; sourceTree = \"<group>\"; };\n\t\t1BF0F7EE147A98C2F11F7C4C32C5B6E3 /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h; sourceTree = \"<group>\"; };\n\t\t1CBEB10B215FDB65E86331667E87AE84 /* GDTCCTNanopbHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCCTNanopbHelpers.m; path = GoogleDataTransport/GDTCCTLibrary/GDTCCTNanopbHelpers.m; sourceTree = \"<group>\"; };\n\t\t1DFB6F1D058B390F2A1340D6D90391C0 /* FIRCoreDiagnosticsConnector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsConnector.h; path = FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h; sourceTree = \"<group>\"; };\n\t\t1E9CD753F6BD26760EFAA1DF57482D50 /* Appirater-Appirater */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = \"Appirater-Appirater\"; path = Appirater.bundle; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t1F54F5C198006F0294B0657489850E48 /* GoogleUtilities-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"GoogleUtilities-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t1F96A93009C7CAECE802F2AF89962662 /* FBLPromise+Await.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Await.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Await.h\"; sourceTree = \"<group>\"; };\n\t\t20481C9B0D8652965A8D3CA6CF4FB6DF /* Appirater.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Appirater.modulemap; sourceTree = \"<group>\"; };\n\t\t20DAC9944D4D96AD4E142D77D43D9F68 /* Pods-Spotify.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = \"Pods-Spotify.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t2186649006C5A621B8BA7DDCC5C27AB4 /* UIImage+GIF.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+GIF.m\"; path = \"SDWebImage/Core/UIImage+GIF.m\"; sourceTree = \"<group>\"; };\n\t\t219546DB6A6974432E1E0283F24A3329 /* GDTCCTCompressionHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCCTCompressionHelper.m; path = GoogleDataTransport/GDTCCTLibrary/GDTCCTCompressionHelper.m; sourceTree = \"<group>\"; };\n\t\t2264D3828F48F1D2D87C73BE181475A2 /* NSImage+Compatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"NSImage+Compatibility.h\"; path = \"SDWebImage/Core/NSImage+Compatibility.h\"; sourceTree = \"<group>\"; };\n\t\t22B6E2A2A128A5A1F1B6F8D6C0EF4BBE /* GDTCORConsoleLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORConsoleLogger.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h; sourceTree = \"<group>\"; };\n\t\t22B79826946DBE0D731ED6479069F8C1 /* PromisesObjC-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"PromisesObjC-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t22CACEEBCAA12953A3BA4DB2820EB06A /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderOperation.h; path = SDWebImage/Core/SDWebImageDownloaderOperation.h; sourceTree = \"<group>\"; };\n\t\t233FC59CE7BD0ABCB6EFD98AF26F4228 /* SDWebImageDownloaderResponseModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderResponseModifier.h; path = SDWebImage/Core/SDWebImageDownloaderResponseModifier.h; sourceTree = \"<group>\"; };\n\t\t2368DD7767138A73CD7D9EADED904481 /* FirebaseCore.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.release.xcconfig; sourceTree = \"<group>\"; };\n\t\t239EF7C666D42E75FB20E65D3491B74A /* FBLPromise+Delay.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Delay.m\"; path = \"Sources/FBLPromises/FBLPromise+Delay.m\"; sourceTree = \"<group>\"; };\n\t\t23D4D9F87518207E73E88D8FBC7C8DE3 /* Appirater */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Appirater; path = Appirater.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2494BB0409778ADBC0785D40DE703573 /* NSURLSession+GULPromises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"NSURLSession+GULPromises.h\"; path = \"GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h\"; sourceTree = \"<group>\"; };\n\t\t255E93987C91799073F418C741D2F912 /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = \"zh-Hans.lproj\"; sourceTree = \"<group>\"; };\n\t\t2565C009A42B8D093CEB285EE59D4EE0 /* Pods-Spotify.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = \"Pods-Spotify.modulemap\"; sourceTree = \"<group>\"; };\n\t\t25BB086F66AE0B62674631094FA38DB9 /* SDWebImageDownloaderResponseModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderResponseModifier.m; path = SDWebImage/Core/SDWebImageDownloaderResponseModifier.m; sourceTree = \"<group>\"; };\n\t\t25D0D7E32DDD7AE56C23799445C13A57 /* FIRInstallationsStoredItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStoredItem.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h; sourceTree = \"<group>\"; };\n\t\t25E74C0A2D416186897FBBC33BC5608B /* SDDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDiskCache.h; path = SDWebImage/Core/SDDiskCache.h; sourceTree = \"<group>\"; };\n\t\t26C98C55DA7C8E2B36CE7527095DED78 /* UIImage+ExtendedCacheData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+ExtendedCacheData.m\"; path = \"SDWebImage/Core/UIImage+ExtendedCacheData.m\"; sourceTree = \"<group>\"; };\n\t\t278F2C97E692BBEB7227CFD22EE4333A /* FBLPromisePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromisePrivate.h; path = Sources/FBLPromises/include/FBLPromisePrivate.h; sourceTree = \"<group>\"; };\n\t\t27B6AEBABD0DD760910C2037F73CBBA7 /* UIImage+Transform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+Transform.m\"; path = \"SDWebImage/Core/UIImage+Transform.m\"; sourceTree = \"<group>\"; };\n\t\t27EFCAB3E6A3DE572444045971D498C5 /* GoogleAppMeasurement.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.release.xcconfig; sourceTree = \"<group>\"; };\n\t\t281F885809D3382CEFAC6F78D5E16CA0 /* FBLPromise+Validate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Validate.m\"; path = \"Sources/FBLPromises/FBLPromise+Validate.m\"; sourceTree = \"<group>\"; };\n\t\t28859EE1F335E36BD76813D7AC4608D9 /* GoogleDataTransport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GoogleDataTransport.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GoogleDataTransport.h; sourceTree = \"<group>\"; };\n\t\t28A55FC857FA4F7D9FE98F3B5AA514E8 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CoreTelephony.framework; sourceTree = DEVELOPER_DIR; };\n\t\t296AEDDAB76C6DA79B00DFB17FE94B13 /* SDWebImageCacheKeyFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheKeyFilter.h; path = SDWebImage/Core/SDWebImageCacheKeyFilter.h; sourceTree = \"<group>\"; };\n\t\t29AE365492E6E96E5708A9AD6E31746F /* nanopb-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"nanopb-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t2A1C27AE73C820EC4ACBF12FAEEA1D93 /* SDImageCodersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCodersManager.h; path = SDWebImage/Core/SDImageCodersManager.h; sourceTree = \"<group>\"; };\n\t\t2A93FB313CA659376FAA369092F2D036 /* FBLPromise+Timeout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Timeout.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Timeout.h\"; sourceTree = \"<group>\"; };\n\t\t2B055BE0C98324B8E1EE0B588C14B23C /* FIRAnalyticsConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAnalyticsConfiguration.m; path = FirebaseCore/Sources/FIRAnalyticsConfiguration.m; sourceTree = \"<group>\"; };\n\t\t2B207171596C8E59567CB49A2BC0B7C9 /* SDGraphicsImageRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDGraphicsImageRenderer.h; path = SDWebImage/Core/SDGraphicsImageRenderer.h; sourceTree = \"<group>\"; };\n\t\t2CD99347EC1D85D2C2FDDB3D1F9DF393 /* FBLPromise+Validate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Validate.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Validate.h\"; sourceTree = \"<group>\"; };\n\t\t2D682D19C50EF105FF8EF05D677CA964 /* NSData+ImageContentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"NSData+ImageContentType.m\"; path = \"SDWebImage/Core/NSData+ImageContentType.m\"; sourceTree = \"<group>\"; };\n\t\t2DDBED0511F929D50127372614C07E38 /* FIRInstallationsIDController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIDController.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m; sourceTree = \"<group>\"; };\n\t\t2E7185858699874B61C27769747820E1 /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImagePrefetcher.m; path = SDWebImage/Core/SDWebImagePrefetcher.m; sourceTree = \"<group>\"; };\n\t\t2F4695D22C004206B1EF601650EB58F1 /* SDWebImageDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDefine.m; path = SDWebImage/Core/SDWebImageDefine.m; sourceTree = \"<group>\"; };\n\t\t2FC875B27ACA63CA271CA0D921CF94C3 /* GDTCORUploader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORUploader.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORUploader.h; sourceTree = \"<group>\"; };\n\t\t303FE2537CE3769B58923B71632FED1C /* FIRBundleUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRBundleUtil.h; path = FirebaseCore/Sources/FIRBundleUtil.h; sourceTree = \"<group>\"; };\n\t\t31527FC5A967FDE9F076D544F4923295 /* NSData+ImageContentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"NSData+ImageContentType.h\"; path = \"SDWebImage/Core/NSData+ImageContentType.h\"; sourceTree = \"<group>\"; };\n\t\t32073165CB0BA8A73E608799A7994586 /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t32B0EB1571B6CA660B7AD773851B90C5 /* FirebaseAnalytics.xcframework */ = {isa = PBXFileReference; includeInIndex = 1; name = FirebaseAnalytics.xcframework; path = Frameworks/FirebaseAnalytics.xcframework; sourceTree = \"<group>\"; };\n\t\t32B1014C844F5619D536DFD1800B11D5 /* GULLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLogger.h; path = GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h; sourceTree = \"<group>\"; };\n\t\t32DB218DD71AD0570B0E339E5319F93B /* SDDeviceHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDeviceHelper.m; path = SDWebImage/Private/SDDeviceHelper.m; sourceTree = \"<group>\"; };\n\t\t33282DA51418F8E945CDA2BC7DDA734E /* FIRInstallationsStatus.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStatus.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h; sourceTree = \"<group>\"; };\n\t\t3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PromisesObjC; path = FBLPromises.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t33802E944806D1B99AD085FE7F697A74 /* SDDisplayLink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDisplayLink.m; path = SDWebImage/Private/SDDisplayLink.m; sourceTree = \"<group>\"; };\n\t\t3446029F86E0312850EAC5C98A32C65C /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ru.lproj; sourceTree = \"<group>\"; };\n\t\t34A40FBEB8C0F4629E017EA065211E5C /* FirebaseCoreDiagnostics-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"FirebaseCoreDiagnostics-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t350451991B16222891CB7702FAA4C26A /* Appirater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = Appirater.h; sourceTree = \"<group>\"; };\n\t\t35329B868A55A887B96B3891C90CE411 /* UIImage+MemoryCacheCost.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+MemoryCacheCost.m\"; path = \"SDWebImage/Core/UIImage+MemoryCacheCost.m\"; sourceTree = \"<group>\"; };\n\t\t363CE7A6599529EED98580D11773BD01 /* GDTCORAssert.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORAssert.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORAssert.m; sourceTree = \"<group>\"; };\n\t\t36C228F973FB461AAC3DE1B3CAC5533C /* PromisesObjC-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"PromisesObjC-dummy.m\"; sourceTree = \"<group>\"; };\n\t\t370CEA1E37CB5E0D01FDBFF39E1020BE /* SDWebImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloader.h; path = SDWebImage/Core/SDWebImageDownloader.h; sourceTree = \"<group>\"; };\n\t\t37B1C403940FAFD0BDA8092C0726458A /* SDImageAPNGCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAPNGCoder.m; path = SDWebImage/Core/SDImageAPNGCoder.m; sourceTree = \"<group>\"; };\n\t\t3808D78CAA3EAA14B869A1667210193C /* SDAnimatedImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageView.h; path = SDWebImage/Core/SDAnimatedImageView.h; sourceTree = \"<group>\"; };\n\t\t382D07A53D722649DCAD5C5BC3BDCAC1 /* FIRInstallationsBackoffController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsBackoffController.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h; sourceTree = \"<group>\"; };\n\t\t38A7BC4B65A58A155D087DA3EFFC1D79 /* FIRVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRVersion.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h; sourceTree = \"<group>\"; };\n\t\t3A023925AC3740397148C89A37EA72B8 /* UIImage+GIF.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+GIF.h\"; path = \"SDWebImage/Core/UIImage+GIF.h\"; sourceTree = \"<group>\"; };\n\t\t3AE71CC3E7412E1F33D2D46AB258531C /* GDTCOREndpoints.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREndpoints.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREndpoints.h; sourceTree = \"<group>\"; };\n\t\t3B56D652DA90C728A3D4AA16170D7FA2 /* GDTCCTCompressionHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCCTCompressionHelper.h; path = GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTCompressionHelper.h; sourceTree = \"<group>\"; };\n\t\t3BB2E5C745E6BEBDF556017B5389A3F8 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h; sourceTree = \"<group>\"; };\n\t\t3C2FEB053783A6171CE3DECCFF936A28 /* FIRApp.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRApp.m; path = FirebaseCore/Sources/FIRApp.m; sourceTree = \"<group>\"; };\n\t\t3C31DC7C6755337262C1BDDB6677C635 /* GDTCOREventDataObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREventDataObject.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventDataObject.h; sourceTree = \"<group>\"; };\n\t\t3C388E0E2142C8BAB1FBE711F1A33688 /* UIImage+ExtendedCacheData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+ExtendedCacheData.h\"; path = \"SDWebImage/Core/UIImage+ExtendedCacheData.h\"; sourceTree = \"<group>\"; };\n\t\t3EAF64B24EEF15C83158B0A1B832978D /* FirebaseInstallationsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallationsInternal.h; path = FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h; sourceTree = \"<group>\"; };\n\t\t3F2853ABAFCEFBF960A5040D649074EC /* GULURLSessionDataResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULURLSessionDataResponse.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h; sourceTree = \"<group>\"; };\n\t\t3FA3607B121AEFB0595C76441513C64D /* SDAnimatedImagePlayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImagePlayer.h; path = SDWebImage/Core/SDAnimatedImagePlayer.h; sourceTree = \"<group>\"; };\n\t\t40CE0245F2D926AF50D3BFBA488887C1 /* GULURLSessionDataResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULURLSessionDataResponse.m; path = GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m; sourceTree = \"<group>\"; };\n\t\t415A874BEFEAB372A795B3F77C86139D /* SDWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWeakProxy.h; path = SDWebImage/Private/SDWeakProxy.h; sourceTree = \"<group>\"; };\n\t\t4187F6DA61736F8AD4201616D23D8061 /* FIRInstallationsStoredAuthToken.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStoredAuthToken.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h; sourceTree = \"<group>\"; };\n\t\t43363A5F804039F569FD9ABD9433F07B /* SDWebImageIndicator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageIndicator.h; path = SDWebImage/Core/SDWebImageIndicator.h; sourceTree = \"<group>\"; };\n\t\t43864D2A6701CB0D5A279382ABEF4FD9 /* Pods-Spotify-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"Pods-Spotify-acknowledgements.plist\"; sourceTree = \"<group>\"; };\n\t\t4468F16CABC244B58ACDC50E87F8B3C4 /* GULLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULLogger.m; path = GoogleUtilities/Logger/GULLogger.m; sourceTree = \"<group>\"; };\n\t\t447875125DF9F0D89F9C6EF9340E1570 /* GULHeartbeatDateStorable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorable.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h; sourceTree = \"<group>\"; };\n\t\t447B191325C26D8C11C3D317EC3FBAA8 /* FBLPromise+Race.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Race.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Race.h\"; sourceTree = \"<group>\"; };\n\t\t44E9E3AB162F34A2457874535E2D437A /* UIImage+MemoryCacheCost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+MemoryCacheCost.h\"; path = \"SDWebImage/Core/UIImage+MemoryCacheCost.h\"; sourceTree = \"<group>\"; };\n\t\t45405CBF1024B18B4589ED32B6B9D343 /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Sources/Private/FirebaseCoreInternal.h; sourceTree = \"<group>\"; };\n\t\t45A1925DBA110CDCB56C30C2AEC79D96 /* tr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = tr.lproj; sourceTree = \"<group>\"; };\n\t\t45D88DFE4BAAB878102C9DB69C90E1EE /* FIRCoreDiagnostics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRCoreDiagnostics.m; path = Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m; sourceTree = \"<group>\"; };\n\t\t4600B5D11E621BE294D5D7A8106BF312 /* SDImageHEICCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageHEICCoder.h; path = SDWebImage/Core/SDImageHEICCoder.h; sourceTree = \"<group>\"; };\n\t\t46849267116D15C2F916F95AF7ED6264 /* FIRInstallationsErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsErrors.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h; sourceTree = \"<group>\"; };\n\t\t4687296E13EF95A9B5206235744E21EC /* AppiraterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = AppiraterDelegate.h; sourceTree = \"<group>\"; };\n\t\t476A318EB831BFCD3B77190E73149735 /* GULSecureCoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSecureCoding.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h; sourceTree = \"<group>\"; };\n\t\t47C2768639337908388E00A97B570D97 /* cct.nanopb.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cct.nanopb.c; path = GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.c; sourceTree = \"<group>\"; };\n\t\t47F2FC011CE490B793305158ACB2048E /* FBLPromise+Wrap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Wrap.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Wrap.h\"; sourceTree = \"<group>\"; };\n\t\t483340B3D5102879F6C45F55BD02FF1E /* SDImageHEICCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageHEICCoder.m; path = SDWebImage/Core/SDImageHEICCoder.m; sourceTree = \"<group>\"; };\n\t\t48972591E3AF0F13726EC5D4C6BEDFDC /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Sources/Private/FIRAppInternal.h; sourceTree = \"<group>\"; };\n\t\t490C3A82D71E20AB4B5BC07D75101D21 /* FBLPromise+Catch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Catch.m\"; path = \"Sources/FBLPromises/FBLPromise+Catch.m\"; sourceTree = \"<group>\"; };\n\t\t4953F3D24A404D00A99D8A29BE61104C /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Sources/Private/FIRLogger.h; sourceTree = \"<group>\"; };\n\t\t4958CF39D5BE0CE693F9BABAB470D5A1 /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = it.lproj; sourceTree = \"<group>\"; };\n\t\t495F9A8ED0CBC83C181879060E49F21E /* firebasecore.nanopb.c */ = {isa = PBXFileReference; includeInIndex = 1; name = firebasecore.nanopb.c; path = Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c; sourceTree = \"<group>\"; };\n\t\t4AABAA72A7A163BFFFA781CE2598D89B /* Pods-Spotify-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = \"Pods-Spotify-frameworks.sh\"; sourceTree = \"<group>\"; };\n\t\t4AC80933AD4E17DC2DDD4A5156E1FADB /* id.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = id.lproj; sourceTree = \"<group>\"; };\n\t\t4CD317B6F97D4204C18D7618DBB86C03 /* GDTCORLifecycle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORLifecycle.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h; sourceTree = \"<group>\"; };\n\t\t4D06A1E8D589DEE651EA569B253B9DA6 /* GoogleUtilities.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.release.xcconfig; sourceTree = \"<group>\"; };\n\t\t4D7D4D1C90894E8A533206E5679B1871 /* SDImageAssetManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAssetManager.m; path = SDWebImage/Private/SDImageAssetManager.m; sourceTree = \"<group>\"; };\n\t\t4D82EC7D361BCA9009FD349978107D1C /* FBLPromise+All.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+All.h\"; path = \"Sources/FBLPromises/include/FBLPromise+All.h\"; sourceTree = \"<group>\"; };\n\t\t4D8AA9949B871C5C08476B12041D2D99 /* SDImageCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoder.m; path = SDWebImage/Core/SDImageCoder.m; sourceTree = \"<group>\"; };\n\t\t4DEBF0EE7331EEAD283D9D6370A2B3FF /* SDImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCache.m; path = SDWebImage/Core/SDImageCache.m; sourceTree = \"<group>\"; };\n\t\t4E43BB424620088D2FC848F87869992C /* FirebaseInstallations.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstallations.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t4E579AE58A2F6343FA943DA78FDA6A24 /* ca.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ca.lproj; sourceTree = \"<group>\"; };\n\t\t4F72FBD1344FC32D12AA727F983904D6 /* nb.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = nb.lproj; sourceTree = \"<group>\"; };\n\t\t4F86D0619F7550A5DBDF634B8413E25F /* GULHeartbeatDateStorageUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULHeartbeatDateStorageUserDefaults.m; path = GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m; sourceTree = \"<group>\"; };\n\t\t50A0F26807A7475A7CAB02BAC26EA368 /* Appirater-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"Appirater-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t50AF89B1AE50DF562243E31C949BD5B3 /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+MultiFormat.m\"; path = \"SDWebImage/Core/UIImage+MultiFormat.m\"; sourceTree = \"<group>\"; };\n\t\t5304860EBF8FA61DE4A892566862746D /* SDImageLoadersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoadersManager.m; path = SDWebImage/Core/SDImageLoadersManager.m; sourceTree = \"<group>\"; };\n\t\t5352D3BC21FF5229DD4FC39829C48E7C /* GDTCORReachability.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORReachability.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORReachability.m; sourceTree = \"<group>\"; };\n\t\t5415E857C6437079EA6CE8D49BC4D00F /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = CoreOnly/Sources/Firebase.h; sourceTree = \"<group>\"; };\n\t\t54836C20C54693641AA8386E05C05C5C /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h; sourceTree = \"<group>\"; };\n\t\t54D381D3559D8677EA0632FDB5EEA05A /* FirebaseInstallations-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"FirebaseInstallations-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t5514ED015845BE4DF10DF85BF4983A59 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Sources/Private/FIRComponentType.h; sourceTree = \"<group>\"; };\n\t\t561783788BEFAECA7A813F1442497E1D /* Pods-Spotify-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = \"Pods-Spotify-acknowledgements.markdown\"; sourceTree = \"<group>\"; };\n\t\t56EBF81C7BB707870CF8F18F19C219BC /* GULSceneDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSceneDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h; sourceTree = \"<group>\"; };\n\t\t573447DBCFF573125A97AC8FE08CF8FB /* sk.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = sk.lproj; sourceTree = \"<group>\"; };\n\t\t579C123C87D8545B91CD64649918A148 /* SDmetamacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDmetamacros.h; path = SDWebImage/Private/SDmetamacros.h; sourceTree = \"<group>\"; };\n\t\t57A489F83B821E73C9F898D59FD839D5 /* SDWebImageCacheSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheSerializer.h; path = SDWebImage/Core/SDWebImageCacheSerializer.h; sourceTree = \"<group>\"; };\n\t\t5805E31EC45A505EEE3457FA2B9FA351 /* FIRCoreDiagnosticsInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsInterop.h; path = Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h; sourceTree = \"<group>\"; };\n\t\t5852FC7ED30AAEEA07547AF6D71F3D85 /* SDImageCacheDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheDefine.h; path = SDWebImage/Core/SDImageCacheDefine.h; sourceTree = \"<group>\"; };\n\t\t5A8A40185ABE648F7A15E613D0C0559F /* FBLPromise+Timeout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Timeout.m\"; path = \"Sources/FBLPromises/FBLPromise+Timeout.m\"; sourceTree = \"<group>\"; };\n\t\t5BE80A247D8376A910A19BFB10B99430 /* GDTCORStorageEventSelector.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORStorageEventSelector.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORStorageEventSelector.m; sourceTree = \"<group>\"; };\n\t\t5BEA3009F10DE79DB402A683F6839FC8 /* FBLPromise+Wrap.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Wrap.m\"; path = \"Sources/FBLPromises/FBLPromise+Wrap.m\"; sourceTree = \"<group>\"; };\n\t\t5C5DD83B8521D66EB85A5A45A92F810F /* GULAppDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h; sourceTree = \"<group>\"; };\n\t\t5CBCB878C4026B383CA6687B4DC52D58 /* FIRAppAssociationRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppAssociationRegistration.h; path = FirebaseCore/Sources/FIRAppAssociationRegistration.h; sourceTree = \"<group>\"; };\n\t\t5DD11686FB044C460680737D6E66EC0C /* SDImageIOCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOCoder.m; path = SDWebImage/Core/SDImageIOCoder.m; sourceTree = \"<group>\"; };\n\t\t5E16667A1668B640A863FF171D2CB5FB /* FIRHeartbeatInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatInfo.h; path = FirebaseCore/Sources/Private/FIRHeartbeatInfo.h; sourceTree = \"<group>\"; };\n\t\t5F030A051DB2F7C17CB74A9C0FBD7B56 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };\n\t\t5FD16FE46197F77B6D4E28CDE644CC73 /* GDTCORRegistrar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORRegistrar.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORRegistrar.h; sourceTree = \"<group>\"; };\n\t\t606B14BF9E8B55AA634896F3FE6C2102 /* GDTCORDirectorySizeTracker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORDirectorySizeTracker.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORDirectorySizeTracker.m; sourceTree = \"<group>\"; };\n\t\t615A6102144F4931AF689AB96C01D719 /* SDAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImage.h; path = SDWebImage/Core/SDAnimatedImage.h; sourceTree = \"<group>\"; };\n\t\t61C15E699851C928BE91C72A5169AEB2 /* NSURLSession+GULPromises.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"NSURLSession+GULPromises.m\"; path = \"GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m\"; sourceTree = \"<group>\"; };\n\t\t6237C8DA5406A972EAFEEC2CB46AA910 /* FIRInstallationsErrorUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsErrorUtil.m; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m; sourceTree = \"<group>\"; };\n\t\t62E087DDBCC7CE3CA61BACD11EE3931E /* SDWebImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImage.h; path = WebImage/SDWebImage.h; sourceTree = \"<group>\"; };\n\t\t63FB1BA9182BB6D6E47E4DD049005A29 /* FirebaseCore-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"FirebaseCore-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t65F9EFAA484830CADC6FE4DE20867D8D /* SDWebImageDownloaderDecryptor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderDecryptor.h; path = SDWebImage/Core/SDWebImageDownloaderDecryptor.h; sourceTree = \"<group>\"; };\n\t\t668CE7FB58FBCA03E7BF9FFA7D4AEA8C /* FIRAnalyticsConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsConfiguration.h; path = FirebaseCore/Sources/FIRAnalyticsConfiguration.h; sourceTree = \"<group>\"; };\n\t\t66B0B7773B93F50516AFA7A4AD80001F /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Sources/Private/FIRAppInternal.h; sourceTree = \"<group>\"; };\n\t\t66E791BF8C770CDCE827420B1959B849 /* GDTCORDirectorySizeTracker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORDirectorySizeTracker.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORDirectorySizeTracker.h; sourceTree = \"<group>\"; };\n\t\t67A976AAF1EAC9BADF423E17C96B88FE /* GDTCORTransport_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORTransport_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h; sourceTree = \"<group>\"; };\n\t\t6806286AE468436D210DE24F56FFD7A2 /* FBLPromise+Recover.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Recover.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Recover.h\"; sourceTree = \"<group>\"; };\n\t\t68332238690458AE7A254B6097B8BD22 /* SDWebImageDownloaderDecryptor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderDecryptor.m; path = SDWebImage/Core/SDWebImageDownloaderDecryptor.m; sourceTree = \"<group>\"; };\n\t\t695ADBFC9C4D04D17897085D1ABBBAA7 /* GoogleAppMeasurement.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t6A35F8BE947883A35C48CDFFF5BACB72 /* FIRInstallationsAPIService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsAPIService.m; path = FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m; sourceTree = \"<group>\"; };\n\t\t6AB43C522E93B03C169E99C63451C091 /* GDTCORUploadCoordinator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORUploadCoordinator.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORUploadCoordinator.m; sourceTree = \"<group>\"; };\n\t\t6AFBDA1EBD167AFD2083DC8D9D565001 /* GDTCORUploadBatch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORUploadBatch.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORUploadBatch.m; sourceTree = \"<group>\"; };\n\t\t6BA2A90BF46E4D5796820E1A900E2C0B /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Sources/Private/FIRComponentContainer.h; sourceTree = \"<group>\"; };\n\t\t6C61DBDC1219C0AC0AD0FF84A0133692 /* GULSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzler.h; path = GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h; sourceTree = \"<group>\"; };\n\t\t6C8ECB26C6DABE3DBF37DBC44D5A8C5C /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h; sourceTree = \"<group>\"; };\n\t\t6E03F27C2DCF8DB117CBC29C875DCD95 /* FIRInstallationsBackoffController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsBackoffController.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m; sourceTree = \"<group>\"; };\n\t\t6E7EB7DF29D03415C41C56734E0C9017 /* FIRInstallationsErrorUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsErrorUtil.h; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h; sourceTree = \"<group>\"; };\n\t\t6F25465DB16E55EFF41F24C620E24E05 /* FIRInstallationsStoredAuthToken.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStoredAuthToken.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m; sourceTree = \"<group>\"; };\n\t\t700956653190B059B98E6D0401813D2F /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = nl.lproj; sourceTree = \"<group>\"; };\n\t\t703B93588CDC01E3116988AAD425A74D /* FIRInstallationsIIDStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIIDStore.h; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h; sourceTree = \"<group>\"; };\n\t\t7055DAE8B926D478FFCB05DC46E7F844 /* FIRConfigurationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfigurationInternal.h; path = FirebaseCore/Sources/FIRConfigurationInternal.h; sourceTree = \"<group>\"; };\n\t\t70FBB40CF13B29C7EC31294E2767F546 /* FBLPromise+Any.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Any.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Any.h\"; sourceTree = \"<group>\"; };\n\t\t71783D9D8F34A0AB09F92BAF64FC155E /* GoogleUtilities-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"GoogleUtilities-dummy.m\"; sourceTree = \"<group>\"; };\n\t\t724419369F9B475400E63E05193D0394 /* FIRVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRVersion.m; path = FirebaseCore/Sources/FIRVersion.m; sourceTree = \"<group>\"; };\n\t\t7283DD0E961B31F830AEB840A7B59650 /* FBLPromises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromises.h; path = Sources/FBLPromises/include/FBLPromises.h; sourceTree = \"<group>\"; };\n\t\t73009AD0D7FBF3D5781BD8B87D5E1D98 /* GULMutableDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULMutableDictionary.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h; sourceTree = \"<group>\"; };\n\t\t736D3261A8A25DCBBECD54A6C5C48166 /* GDTCORFlatFileStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORFlatFileStorage.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORFlatFileStorage.m; sourceTree = \"<group>\"; };\n\t\t7387A62B07188200FF8487FD3A2CF2A5 /* FIRInstallationsSingleOperationPromiseCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsSingleOperationPromiseCache.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m; sourceTree = \"<group>\"; };\n\t\t73F76A840EAA1BA85CD5CE2578134A93 /* SDWebImageOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOperation.h; path = SDWebImage/Core/SDWebImageOperation.h; sourceTree = \"<group>\"; };\n\t\t747BA4839026A5B48F78F7F2F59B01D8 /* FIRCoreDiagnosticsConnector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsConnector.h; path = FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h; sourceTree = \"<group>\"; };\n\t\t74B387BF4963DADE929360BC4D95BF9F /* GDTCOREvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCOREvent.m; path = GoogleDataTransport/GDTCORLibrary/GDTCOREvent.m; sourceTree = \"<group>\"; };\n\t\t75E9E1284F8AE50551FF56600DDDCEBF /* GULSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzler.m; path = GoogleUtilities/MethodSwizzler/GULSwizzler.m; sourceTree = \"<group>\"; };\n\t\t7887F0BAB621B4623BFE017BC5FA339D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };\n\t\t78E45C724EB1ABA21537759F2AA0CDBF /* UIView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIView+WebCache.m\"; path = \"SDWebImage/Core/UIView+WebCache.m\"; sourceTree = \"<group>\"; };\n\t\t79AB37844F04B4F0CF83A66B9FBD9175 /* GDTCORFlatFileStorage+Promises.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"GDTCORFlatFileStorage+Promises.m\"; path = \"GoogleDataTransport/GDTCORLibrary/GDTCORFlatFileStorage+Promises.m\"; sourceTree = \"<group>\"; };\n\t\t7A10001AFFFB54BB477050134573A9C4 /* SDImageCoderHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoderHelper.h; path = SDWebImage/Core/SDImageCoderHelper.h; sourceTree = \"<group>\"; };\n\t\t7B1EB303FD52ADD9ABA791AD8C33496F /* GDTCORFlatFileStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORFlatFileStorage.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage.h; sourceTree = \"<group>\"; };\n\t\t7B4DFE57A7C5FC68155C295484A72007 /* SDWebImageTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransition.h; path = SDWebImage/Core/SDWebImageTransition.h; sourceTree = \"<group>\"; };\n\t\t7BBDEBAD931B605980FE3DCE9FA337AE /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; };\n\t\t7BF54C90D1DF4DD3950B8DCD5C09D18C /* PromisesObjC-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"PromisesObjC-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t7CE88DC6249A53E194E886FD268B4F22 /* SDDisplayLink.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDisplayLink.h; path = SDWebImage/Private/SDDisplayLink.h; sourceTree = \"<group>\"; };\n\t\t7D8A688C63FDD5533A68B0CD80B0501E /* SDImageCacheConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheConfig.m; path = SDWebImage/Core/SDImageCacheConfig.m; sourceTree = \"<group>\"; };\n\t\t7EF33965A3795DEE7A531EC8C56300B4 /* GDTCOREvent+GDTCCTSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"GDTCOREvent+GDTCCTSupport.h\"; path = \"GoogleDataTransport/GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h\"; sourceTree = \"<group>\"; };\n\t\t7F0F742A22FC71CED5A18A108E514A8B /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = \"<group>\"; };\n\t\t7F3BFEC70D8BA82BE6E262B3750543AC /* GDTCORStorageProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORStorageProtocol.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h; sourceTree = \"<group>\"; };\n\t\t7FDFC5FEAC4A550A50CD516405F6DFF2 /* FBLPromise+Async.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Async.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Async.h\"; sourceTree = \"<group>\"; };\n\t\t804DFCC909792374DF921D69BE1F1C18 /* SDInternalMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDInternalMacros.h; path = SDWebImage/Private/SDInternalMacros.h; sourceTree = \"<group>\"; };\n\t\t809CE53E4184869CD1D4910C0A359884 /* GDTCORPlatform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORPlatform.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORPlatform.m; sourceTree = \"<group>\"; };\n\t\t80FE85865E814FFFE9FC4BD1E92FF02B /* SDAssociatedObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAssociatedObject.m; path = SDWebImage/Private/SDAssociatedObject.m; sourceTree = \"<group>\"; };\n\t\t813CEE72D58D250DD2A09A4157C51303 /* GDTCORAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORAssert.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h; sourceTree = \"<group>\"; };\n\t\t82AAE98FB8E850A8ECBA43F727AD3F4B /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Sources/Private/FIRComponentContainer.h; sourceTree = \"<group>\"; };\n\t\t82EAA36E76AE8F4E664A68EC8EB36298 /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h; sourceTree = \"<group>\"; };\n\t\t83495546D2D6077CD99D793135E8A7EC /* SDWebImageCompat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCompat.h; path = SDWebImage/Core/SDWebImageCompat.h; sourceTree = \"<group>\"; };\n\t\t83D038C4E24C71BFAE211A6E0CDA58BA /* nanopb.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t841780DAC592F44AB2E8D35D36E32285 /* SDImageTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageTransformer.m; path = SDWebImage/Core/SDImageTransformer.m; sourceTree = \"<group>\"; };\n\t\t8454F0C4E786C6A2499ED8DA5879A808 /* FIRHeartbeatInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRHeartbeatInfo.m; path = FirebaseCore/Sources/FIRHeartbeatInfo.m; sourceTree = \"<group>\"; };\n\t\t856B5CD56F194FAD26EA91620B66D614 /* GoogleDataTransport */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleDataTransport; path = GoogleDataTransport.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t859E0D4CB486D5A4710D605554199885 /* FirebaseCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"FirebaseCore-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t859F0A43E3649885E17F4D515A86A159 /* UIImage+Metadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+Metadata.h\"; path = \"SDWebImage/Core/UIImage+Metadata.h\"; sourceTree = \"<group>\"; };\n\t\t867CE4FF42F759E76A71FEF4453E8079 /* ms.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ms.lproj; sourceTree = \"<group>\"; };\n\t\t87BD1262A5EDC0CE9D84214096454004 /* GDTCORReachability.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORReachability.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORReachability.h; sourceTree = \"<group>\"; };\n\t\t881ACDC9E0325D12479F43AD079D1CBB /* GoogleDataTransport-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"GoogleDataTransport-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t893980C67675F297617FB935213E4671 /* FIRFirebaseUserAgent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRFirebaseUserAgent.m; path = FirebaseCore/Sources/FIRFirebaseUserAgent.m; sourceTree = \"<group>\"; };\n\t\t8A0DEDA4144F466B62361967B86ACC25 /* th.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = th.lproj; sourceTree = \"<group>\"; };\n\t\t8A7AE3C5E6E2073C8FAC46FF8333849F /* ResourceBundle-Appirater-Appirater-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"ResourceBundle-Appirater-Appirater-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t8B4E22AE507DF453D28673AD92339EB1 /* FirebaseInstallations.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstallations.release.xcconfig; sourceTree = \"<group>\"; };\n\t\t8BD491CEBE34A4FF9B067D4431A9525D /* SDWebImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageManager.h; path = SDWebImage/Core/SDWebImageManager.h; sourceTree = \"<group>\"; };\n\t\t8C1F9B1C56AC542B7695BF945F7E8A5A /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+MultiFormat.h\"; path = \"SDWebImage/Core/UIImage+MultiFormat.h\"; sourceTree = \"<group>\"; };\n\t\t8C5EE75C53160A323F9D43000C9258C2 /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = \"zh-Hant.lproj\"; sourceTree = \"<group>\"; };\n\t\t8C7297F9F351E0DFB107547CC454F81B /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = en.lproj; sourceTree = \"<group>\"; };\n\t\t8CC9178C366942FD6FF6A115604EAD58 /* FirebaseCoreDiagnostics */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCoreDiagnostics; path = FirebaseCoreDiagnostics.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t8CDC01574AEDC72431059BB3FDE16F59 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = de.lproj; sourceTree = \"<group>\"; };\n\t\t8CDC11191CD5FAC6E9AA96E2BC7DAD05 /* FIRHeartbeatInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatInfo.h; path = FirebaseCore/Sources/Private/FIRHeartbeatInfo.h; sourceTree = \"<group>\"; };\n\t\t8D2E7ABE07934F659148C41C852087FD /* NSImage+Compatibility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"NSImage+Compatibility.m\"; path = \"SDWebImage/Core/NSImage+Compatibility.m\"; sourceTree = \"<group>\"; };\n\t\t8D628BFBCC6276E5E277ED26143A0529 /* UIColor+SDHexString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIColor+SDHexString.h\"; path = \"SDWebImage/Private/UIColor+SDHexString.h\"; sourceTree = \"<group>\"; };\n\t\t8D85590DB78FA3CE98F5876D319CDC9F /* FBLPromise+Then.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Then.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Then.h\"; sourceTree = \"<group>\"; };\n\t\t8DFCA2753EDD74C8B7D46CD39BC4F756 /* NSBezierPath+SDRoundedCorners.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"NSBezierPath+SDRoundedCorners.m\"; path = \"SDWebImage/Private/NSBezierPath+SDRoundedCorners.m\"; sourceTree = \"<group>\"; };\n\t\t8E3D624D33EC772ADA4910D9A6A067AD /* SDImageCoderHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoderHelper.m; path = SDWebImage/Core/SDImageCoderHelper.m; sourceTree = \"<group>\"; };\n\t\t8E7ED49344AE0AC6AD92262E047201BD /* FIRCoreDiagnosticsConnector.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRCoreDiagnosticsConnector.m; path = FirebaseCore/Sources/FIRCoreDiagnosticsConnector.m; sourceTree = \"<group>\"; };\n\t\t8F2CD38DB179EE57D03D1E4AE0BBA047 /* SDImageGraphics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGraphics.m; path = SDWebImage/Core/SDImageGraphics.m; sourceTree = \"<group>\"; };\n\t\t8F6FA7F2B642E68ECD25BCCB0DDAAA75 /* GDTCORClock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORClock.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORClock.m; sourceTree = \"<group>\"; };\n\t\t90548723A968948DA9E270815D5DFEA2 /* hu.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = hu.lproj; sourceTree = \"<group>\"; };\n\t\t90D9BC28AA40B8F7AAC5DBAFFFA2503A /* pb_encode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_encode.c; sourceTree = \"<group>\"; };\n\t\t90E823CCF25045F00FF4E98E871586A6 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; };\n\t\t91D7D93CD15EE8BBB672073A9EE9172E /* SDWebImageDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDefine.h; path = SDWebImage/Core/SDWebImageDefine.h; sourceTree = \"<group>\"; };\n\t\t91EF3E33FDEAEF5BB90A91327C8718B6 /* SDWebImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"SDWebImage-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t92EA46401122BB560F222964810DAE14 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Sources/Private/FIRComponent.h; sourceTree = \"<group>\"; };\n\t\t932BDDF177FD04B28E9285096E7D291C /* GoogleDataTransport-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"GoogleDataTransport-dummy.m\"; sourceTree = \"<group>\"; };\n\t\t93498C80BEE42599CD4B49D1DCDE8DAA /* GDTCORConsoleLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORConsoleLogger.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORConsoleLogger.m; sourceTree = \"<group>\"; };\n\t\t94342AAF24F20C2012C9E17B8D8076FA /* GoogleUtilities.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleUtilities.modulemap; sourceTree = \"<group>\"; };\n\t\t9484BA52176E0E66CBDC23122D2948A2 /* FIRInstallationsStoredItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStoredItem.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m; sourceTree = \"<group>\"; };\n\t\t9487AD43770C35ED6D6CF71B197AE775 /* SDWebImageTransitionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransitionInternal.h; path = SDWebImage/Private/SDWebImageTransitionInternal.h; sourceTree = \"<group>\"; };\n\t\t94FAEBC41B0BE3E27929CC570CB58423 /* FirebaseInstallations-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"FirebaseInstallations-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t97DFD7435A40FB6C7611C58681006DC8 /* Pods-Spotify */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = \"Pods-Spotify\"; path = Pods_Spotify.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t98368FFE6F3A2C1CB4B79C360D245377 /* SDImageCachesManagerOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManagerOperation.h; path = SDWebImage/Private/SDImageCachesManagerOperation.h; sourceTree = \"<group>\"; };\n\t\t983C23FA76E7A245275E7A252B67A2A0 /* pb_common.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_common.c; sourceTree = \"<group>\"; };\n\t\t98A2C33C3CFB15DFB0AD91D948975967 /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ko.lproj; sourceTree = \"<group>\"; };\n\t\t99108619FD685C7E04AA2798D8184E88 /* FIRInstallationsLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsLogger.h; path = FirebaseInstallations/Source/Library/FIRInstallationsLogger.h; sourceTree = \"<group>\"; };\n\t\t99AC313325A72709F61AD9B82245FC4F /* SDImageCachesManagerOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManagerOperation.m; path = SDWebImage/Private/SDImageCachesManagerOperation.m; sourceTree = \"<group>\"; };\n\t\t99C91ADC1F402BD8ABEE63EAB8134747 /* el.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = el.lproj; sourceTree = \"<group>\"; };\n\t\t9A75B93924C163BDD4BFE27BE82320E0 /* GULKeychainUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULKeychainUtils.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h; sourceTree = \"<group>\"; };\n\t\t9B960865AD112FB963F482E45E567B56 /* SDDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDiskCache.m; path = SDWebImage/Core/SDDiskCache.m; sourceTree = \"<group>\"; };\n\t\t9BA476F642687D5FC7AA27BDDA27DEBC /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = FirebaseCore/Sources/FIROptions.m; sourceTree = \"<group>\"; };\n\t\t9BC48CD5B43C672FF7213F9BE34110DB /* UIImage+Metadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+Metadata.m\"; path = \"SDWebImage/Core/UIImage+Metadata.m\"; sourceTree = \"<group>\"; };\n\t\t9C35CA5CB6C0053B485FCFDFD30A1662 /* GULAppDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h; sourceTree = \"<group>\"; };\n\t\t9D110B53C055335FB5D62021AD131E9F /* FBLPromise+All.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+All.m\"; path = \"Sources/FBLPromises/FBLPromise+All.m\"; sourceTree = \"<group>\"; };\n\t\t9D1FFD95B9DC7DB4011FC5445F7059CE /* GDTCOREndpoints.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCOREndpoints.m; path = GoogleDataTransport/GDTCORLibrary/GDTCOREndpoints.m; sourceTree = \"<group>\"; };\n\t\t9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };\n\t\t9DB1409CD0C3B140ECAB6006D2DAD8BC /* GDTCORRegistrar.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORRegistrar.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORRegistrar.m; sourceTree = \"<group>\"; };\n\t\t9E08253131AF6EBD5597DF21EBF9B98D /* FIRInstallationsItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsItem.m; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.m; sourceTree = \"<group>\"; };\n\t\t9FB349B1B1D5B036FA774AC001CEBCB4 /* hy.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = hy.lproj; sourceTree = \"<group>\"; };\n\t\tA0F0A5A8418FA40166272625AFB5330A /* FIRAppAssociationRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAppAssociationRegistration.m; path = FirebaseCore/Sources/FIRAppAssociationRegistration.m; sourceTree = \"<group>\"; };\n\t\tA1B2BE9FCAE442C062B1070B5F83D9D9 /* FBLPromise+Any.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Any.m\"; path = \"Sources/FBLPromises/FBLPromise+Any.m\"; sourceTree = \"<group>\"; };\n\t\tA243783F2DB10CD105EA1B585E02DF32 /* SDImageIOAnimatedCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOAnimatedCoderInternal.h; path = SDWebImage/Private/SDImageIOAnimatedCoderInternal.h; sourceTree = \"<group>\"; };\n\t\tA259FD968B2F3F103051FCCB13D1EF8F /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImageView+HighlightedWebCache.m\"; path = \"SDWebImage/Core/UIImageView+HighlightedWebCache.m\"; sourceTree = \"<group>\"; };\n\t\tA27A53F9FCBFE297E53C77376ACB64D1 /* Pods-Spotify-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"Pods-Spotify-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tA2CD1B738ABAB7BA344D7969860B494C /* FIRCoreDiagnostics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnostics.h; path = Firebase/CoreDiagnostics/FIRCDLibrary/Public/FIRCoreDiagnostics.h; sourceTree = \"<group>\"; };\n\t\tA3142D0BC0A7099D82BA56A3FD637656 /* FIRConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfiguration.m; path = FirebaseCore/Sources/FIRConfiguration.m; sourceTree = \"<group>\"; };\n\t\tA328CD57DBA12543441049EBF409F205 /* FIRInstallationsStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStore.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m; sourceTree = \"<group>\"; };\n\t\tA40C76162676EC9A3E0C33C1F29CB93F /* GULKeychainStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULKeychainStorage.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h; sourceTree = \"<group>\"; };\n\t\tA4A6DED8C7023B5E793A748ED43129EE /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h; sourceTree = \"<group>\"; };\n\t\tA4FB500E6FBEE5F4910B4E4F3894E917 /* SDWebImageIndicator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageIndicator.m; path = SDWebImage/Core/SDWebImageIndicator.m; sourceTree = \"<group>\"; };\n\t\tA55020CA6EDE9396075075D402E84AEC /* FIRInstallationsSingleOperationPromiseCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsSingleOperationPromiseCache.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h; sourceTree = \"<group>\"; };\n\t\tA6178B53BBB7ED0452CEE088B25AA064 /* GoogleUtilities-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"GoogleUtilities-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tA62E17FF50F14A446211D0E0BA00FD24 /* UIImage+ForceDecode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImage+ForceDecode.m\"; path = \"SDWebImage/Core/UIImage+ForceDecode.m\"; sourceTree = \"<group>\"; };\n\t\tA6344AC78A87A0720BE33CE02655D669 /* SDWebImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"SDWebImage-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\tA6888DFA1022D0AF9FB4109175558CEC /* FBLPromise+Do.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Do.m\"; path = \"Sources/FBLPromises/FBLPromise+Do.m\"; sourceTree = \"<group>\"; };\n\t\tA7D509EE7C37DC62C5F5119B2692E792 /* FIRCoreDiagnosticsData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsData.h; path = Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h; sourceTree = \"<group>\"; };\n\t\tA8689F656BCD2DE359141CDE820E425F /* FIRConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfiguration.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h; sourceTree = \"<group>\"; };\n\t\tA86DA94DC9AB6D6E95B73BF4F59C3EF1 /* fa.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = fa.lproj; sourceTree = \"<group>\"; };\n\t\tA8B52265053B7A072C3CFD52774A4E64 /* GULNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetwork.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h; sourceTree = \"<group>\"; };\n\t\tA9A5B5BEF1CFAFF4AEB69AFD4C20968A /* SDImageIOAnimatedCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOAnimatedCoder.m; path = SDWebImage/Core/SDImageIOAnimatedCoder.m; sourceTree = \"<group>\"; };\n\t\tAA8BA4718A81C87F777362D613444D44 /* Firebase.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tAAC1202619BDEC6CB408DEFB276233E1 /* FIRCoreDiagnosticsData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsData.h; path = Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h; sourceTree = \"<group>\"; };\n\t\tAB007F418E0ED0E20061B9ED7D831C76 /* GULSecureCoding.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSecureCoding.m; path = GoogleUtilities/Environment/GULSecureCoding.m; sourceTree = \"<group>\"; };\n\t\tAB33B7FB74C324A4584D1D93AF8B1DB5 /* cct.nanopb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = cct.nanopb.h; path = GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h; sourceTree = \"<group>\"; };\n\t\tACAACBFBB72CC5DBA48E5939C7C05CBB /* SDWebImageDownloaderConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderConfig.m; path = SDWebImage/Core/SDWebImageDownloaderConfig.m; sourceTree = \"<group>\"; };\n\t\tACE81B64A65F8AF15E7C822CDF6A73E6 /* FirebaseCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tAE780E851F5F67AAA9C4AE38402A4086 /* GoogleDataTransport.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleDataTransport.modulemap; sourceTree = \"<group>\"; };\n\t\tAE8073B498E3701A492F026966747912 /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = FirebaseCore/Sources/FIRComponentContainer.m; sourceTree = \"<group>\"; };\n\t\tAF5AFDC2F2B6C3E31AFC75FE3430CA49 /* fi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = fi.lproj; sourceTree = \"<group>\"; };\n\t\tB06B80A4EE003DEDFC1F89E8907C6C16 /* GDTCORTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORTransformer.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h; sourceTree = \"<group>\"; };\n\t\tB0893F86784B88FBEBDDAD469BA72394 /* FBLPromise+Retry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Retry.m\"; path = \"Sources/FBLPromises/FBLPromise+Retry.m\"; sourceTree = \"<group>\"; };\n\t\tB0B214D775196BA7CA8E17E53048A493 /* SDWebImage */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SDWebImage; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB12CEE2C03EFBD7EBAF1717349B42067 /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImagePrefetcher.h; path = SDWebImage/Core/SDWebImagePrefetcher.h; sourceTree = \"<group>\"; };\n\t\tB134BD979A35DB81CA4CBD64BE86AAC5 /* GULApplication.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULApplication.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h; sourceTree = \"<group>\"; };\n\t\tB17DB1B80794FEE3D7DC12CB3641AB30 /* FIRCurrentDateProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRCurrentDateProvider.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m; sourceTree = \"<group>\"; };\n\t\tB195FEEB2B6FD768A1270ABE2938AA39 /* SDImageGraphics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGraphics.h; path = SDWebImage/Core/SDImageGraphics.h; sourceTree = \"<group>\"; };\n\t\tB1C3F5E1F2DA4D224862FC3F811D0917 /* SDImageAPNGCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoder.h; path = SDWebImage/Core/SDImageAPNGCoder.h; sourceTree = \"<group>\"; };\n\t\tB21C4B6B899118FE97F08797C6CC6D78 /* FBLPromise.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBLPromise.m; path = Sources/FBLPromises/FBLPromise.m; sourceTree = \"<group>\"; };\n\t\tB3310E7F0BD29950EA79269F8864E7B0 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Sources/Private/FIRComponentType.h; sourceTree = \"<group>\"; };\n\t\tB349AD374EBA10C2D49FC4BA8A53F0CF /* FIRCurrentDateProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCurrentDateProvider.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h; sourceTree = \"<group>\"; };\n\t\tB3522FD698E8EFD6BDE90D04D1ABC13D /* SDImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoader.m; path = SDWebImage/Core/SDImageLoader.m; sourceTree = \"<group>\"; };\n\t\tB3DC2C81260A550A30B6C664556BAD8A /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Sources/Private/FIRDependency.h; sourceTree = \"<group>\"; };\n\t\tB43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleUtilities; path = GoogleUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB46C4D5C2FF1FB2417D06ADB91D1CEBA /* FIRInstallationsStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStore.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h; sourceTree = \"<group>\"; };\n\t\tB4A0C1F3F59FF0ECC737E3A22B64F7F0 /* SDAnimatedImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageView.m; path = SDWebImage/Core/SDAnimatedImageView.m; sourceTree = \"<group>\"; };\n\t\tB526E38BA63C966AF02EA09F26802535 /* PromisesObjC.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PromisesObjC.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tB5E3DBB2F100E0A299BCFC77EBC69A7E /* FIRInstallationsHTTPError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsHTTPError.m; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m; sourceTree = \"<group>\"; };\n\t\tB66ADF3FBC020B8BAE5E1C0C6EA3C650 /* SDImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCache.h; path = SDWebImage/Core/SDImageCache.h; sourceTree = \"<group>\"; };\n\t\tB6A08E238C0EA041AF882D5F75E6C3C9 /* SDImageGIFCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGIFCoder.m; path = SDWebImage/Core/SDImageGIFCoder.m; sourceTree = \"<group>\"; };\n\t\tB74D76E7DA492E2DD4E2C7CE3A5874F9 /* Appirater.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Appirater.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tB83BA9762F2888371B5ADE95B066DCB4 /* SDImageCacheConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheConfig.h; path = SDWebImage/Core/SDImageCacheConfig.h; sourceTree = \"<group>\"; };\n\t\tB8633B4212F9E21E512835226D2BEC2E /* FBLPromise+Delay.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Delay.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Delay.h\"; sourceTree = \"<group>\"; };\n\t\tB8AE32764C24267738A026CE787CE667 /* GULKeychainStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULKeychainStorage.m; path = GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m; sourceTree = \"<group>\"; };\n\t\tB95FF8BC5E40163C886E3DB1B394DD75 /* SDAnimatedImageRep.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageRep.h; path = SDWebImage/Core/SDAnimatedImageRep.h; sourceTree = \"<group>\"; };\n\t\tBA37D2C1168173A7796B05F93479A231 /* NSButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"NSButton+WebCache.h\"; path = \"SDWebImage/Core/NSButton+WebCache.h\"; sourceTree = \"<group>\"; };\n\t\tBA393B4B24C719DDDC878C0A08B2D1BB /* GoogleDataTransport.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleDataTransport.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tBA44BA3AD4121BF4B3BA03128355DA0A /* GULNetworkConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkConstants.m; path = GoogleUtilities/Network/GULNetworkConstants.m; sourceTree = \"<group>\"; };\n\t\tBAB945382DE7BCE1238478DF4341D1C3 /* FIRInstallationsItem+RegisterInstallationAPI.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FIRInstallationsItem+RegisterInstallationAPI.h\"; path = \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h\"; sourceTree = \"<group>\"; };\n\t\tBB06018D1785388A5C83E9EF4D57ED16 /* GULHeartbeatDateStorageUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorageUserDefaults.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h; sourceTree = \"<group>\"; };\n\t\tBB1D1192CEC6C26D481BAB47C75BCA56 /* SDImageAssetManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAssetManager.h; path = SDWebImage/Private/SDImageAssetManager.h; sourceTree = \"<group>\"; };\n\t\tBB81C8F74DB13FEF4D842A7A4127FEBF /* SDImageIOAnimatedCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOAnimatedCoder.h; path = SDWebImage/Core/SDImageIOAnimatedCoder.h; sourceTree = \"<group>\"; };\n\t\tBBB794E91F141A51A62086A95A79B3B0 /* GDTCOREvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREvent.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h; sourceTree = \"<group>\"; };\n\t\tBCBC03DFAC32230F28CDE2D8E913A269 /* GDTCORTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCORTransformer.m; path = GoogleDataTransport/GDTCORLibrary/GDTCORTransformer.m; sourceTree = \"<group>\"; };\n\t\tBCEE4E5F9E2A1F4352E21C55CC500B15 /* GDTCORClock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORClock.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h; sourceTree = \"<group>\"; };\n\t\tBD01D4D2C9BD8D230AC07E17D1BC2580 /* GULNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"GULNSData+zlib.h\"; path = \"GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h\"; sourceTree = \"<group>\"; };\n\t\tBD3097914838C55DE30D9D377048A664 /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = \"<group>\"; };\n\t\tBE1CFCA4C81C90732F8DB42EA1F017A3 /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Sources/Private/FIRLibrary.h; sourceTree = \"<group>\"; };\n\t\tBE37397A0A9B84C77A7B34A9406A3952 /* GoogleDataTransport.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleDataTransport.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tBE65A7532D1E92D1171FAB3E3DBF0EC2 /* FBLPromise+Recover.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Recover.m\"; path = \"Sources/FBLPromises/FBLPromise+Recover.m\"; sourceTree = \"<group>\"; };\n\t\tBFEAB29224248CA276353656139D1668 /* SDImageCachesManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManager.m; path = SDWebImage/Core/SDImageCachesManager.m; sourceTree = \"<group>\"; };\n\t\tC0FF8273009BBF51F9894931F3B54A5E /* Appirater-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"Appirater-prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tC1150A7649D44398A5F001918CBE0C16 /* GDTCORReachability_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORReachability_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORReachability_Private.h; sourceTree = \"<group>\"; };\n\t\tC18C4496C07F34201871F99AD27069A0 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Sources/Private/FIRLogger.h; sourceTree = \"<group>\"; };\n\t\tC2439987FF247C8C084181EBCF11641F /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h; sourceTree = \"<group>\"; };\n\t\tC2B6C797B8E1770AE7FB92B865BB499B /* FIRApp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRApp.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h; sourceTree = \"<group>\"; };\n\t\tC2EDD3FE368044C57FFE267748AD31CE /* FIRComponentContainerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainerInternal.h; path = FirebaseCore/Sources/FIRComponentContainerInternal.h; sourceTree = \"<group>\"; };\n\t\tC3AECB4945D348C50164B9454BA98CB3 /* pt-BR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = \"pt-BR.lproj\"; sourceTree = \"<group>\"; };\n\t\tC41FA4729FC85108299943DF13BE21D7 /* SDWebImageError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageError.h; path = SDWebImage/Core/SDWebImageError.h; sourceTree = \"<group>\"; };\n\t\tC48BA4C3D0C62019243E819DD277C007 /* SDInternalMacros.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDInternalMacros.m; path = SDWebImage/Private/SDInternalMacros.m; sourceTree = \"<group>\"; };\n\t\tC52C466DF84E99205E54E0AEC7DF14B2 /* FirebaseCoreDiagnostics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCoreDiagnostics.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tC5674D03956C9BD31033CABEEFE4F2E1 /* PromisesObjC.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PromisesObjC.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tC5E56AF681704D05296BF6544BFD6DBC /* nanopb.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tC6911F1DC733532D91E29D6B0433A787 /* vi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = vi.lproj; sourceTree = \"<group>\"; };\n\t\tC6A1BDEE41C3F181B6BAC16ADB84601E /* SDAssociatedObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAssociatedObject.h; path = SDWebImage/Private/SDAssociatedObject.h; sourceTree = \"<group>\"; };\n\t\tC76E61D46C6D64C4743B6A7256A286EF /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Sources/Private/FIRLibrary.h; sourceTree = \"<group>\"; };\n\t\tC78361E6DA67CDEC2A04C25F1B40D31F /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; };\n\t\tC869A091C5104F60176DCBAC53E9FCD6 /* FBLPromise+Retry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Retry.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Retry.h\"; sourceTree = \"<group>\"; };\n\t\tC87340AB40E7872EBB32D3E37F151B98 /* SDImageCodersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCodersManager.m; path = SDWebImage/Core/SDImageCodersManager.m; sourceTree = \"<group>\"; };\n\t\tC887379F2FAEEA195D743E2A7E8695B2 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Sources/Private/FIRDependency.h; sourceTree = \"<group>\"; };\n\t\tC8CC6A0CB955A36A57FB8DC86DC7122B /* UIView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIView+WebCache.h\"; path = \"SDWebImage/Core/UIView+WebCache.h\"; sourceTree = \"<group>\"; };\n\t\tCA1E5C47B1D161A6D7326A63F73039E1 /* UIImage+Transform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImage+Transform.h\"; path = \"SDWebImage/Core/UIImage+Transform.h\"; sourceTree = \"<group>\"; };\n\t\tCAFA66ED08EE2214A12519DB72F11801 /* FIRInstallationsLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsLogger.m; path = FirebaseInstallations/Source/Library/FIRInstallationsLogger.m; sourceTree = \"<group>\"; };\n\t\tCC9B5348D8E36B88FD0E3329BCF4479D /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = FirebaseCore/Sources/FIRDependency.m; sourceTree = \"<group>\"; };\n\t\tCD9056754A12ED3E38D68945FE70B586 /* Appirater-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"Appirater-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tCE0BC2BA98097A46FED66139FADDB5C2 /* NSButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"NSButton+WebCache.m\"; path = \"SDWebImage/Core/NSButton+WebCache.m\"; sourceTree = \"<group>\"; };\n\t\tCE6BFCD79351B8CDEDCAB2DE6EDB89AE /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"SDWebImage-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tCE9EF082FAA32B5B2D0B0C7CC14C11E6 /* Appirater.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Appirater.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tCEB2E6515F73C730A4DE300BCA32CE76 /* GDTCOREvent_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREvent_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h; sourceTree = \"<group>\"; };\n\t\tCEB675D419ACF104AD5C8F2619C4FCF5 /* SDWeakProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWeakProxy.m; path = SDWebImage/Private/SDWeakProxy.m; sourceTree = \"<group>\"; };\n\t\tCF04F211D2AE46EEBF166D2CC374B517 /* SDAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"SDAnimatedImageView+WebCache.h\"; path = \"SDWebImage/Core/SDAnimatedImageView+WebCache.h\"; sourceTree = \"<group>\"; };\n\t\tCF805F43FFDD645D95C1ACEABC114049 /* GULUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULUserDefaults.m; path = GoogleUtilities/UserDefaults/GULUserDefaults.m; sourceTree = \"<group>\"; };\n\t\tD005D4ECC0D56EB73527C065B49D192C /* he.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = he.lproj; sourceTree = \"<group>\"; };\n\t\tD053D0A9CE99EC16E5ED88D7BA8C3A65 /* ro.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ro.lproj; sourceTree = \"<group>\"; };\n\t\tD2771347E37390095BF7D36EB989050F /* Appirater-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"Appirater-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\tD29D1ACD3388DF30F5213782D0089AAE /* FIRInstallationsItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsItem.h; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.h; sourceTree = \"<group>\"; };\n\t\tD2D3BD16668BB31898CA2909AB1211CB /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ja.lproj; sourceTree = \"<group>\"; };\n\t\tD2DC9C0FCEB534D5193B9600BF0552FC /* GULAppEnvironmentUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppEnvironmentUtil.m; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m; sourceTree = \"<group>\"; };\n\t\tD327D14764B30DDEEB17666FA535871D /* GULSceneDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSceneDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h; sourceTree = \"<group>\"; };\n\t\tD368B1A08214DF1EF6A0A9F4860161C0 /* FirebaseCoreDiagnostics.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseCoreDiagnostics.modulemap; sourceTree = \"<group>\"; };\n\t\tD43779F7D174B41F97107A9631DFA91A /* GoogleAppMeasurement.xcframework */ = {isa = PBXFileReference; includeInIndex = 1; name = GoogleAppMeasurement.xcframework; path = Frameworks/GoogleAppMeasurement.xcframework; sourceTree = \"<group>\"; };\n\t\tD519F9451A80C810AEF071E0A50F225E /* UIImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImageView+WebCache.h\"; path = \"SDWebImage/Core/UIImageView+WebCache.h\"; sourceTree = \"<group>\"; };\n\t\tD52688E7BC72717ABC1A8FD85DD32AE4 /* cs.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = cs.lproj; sourceTree = \"<group>\"; };\n\t\tD53EBA2326B86A037D7D89C9C9849AB1 /* UIButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIButton+WebCache.h\"; path = \"SDWebImage/Core/UIButton+WebCache.h\"; sourceTree = \"<group>\"; };\n\t\tD54DA10983EF09ABC480187282A87A58 /* FIRInstallationsAuthTokenResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsAuthTokenResult.m; path = FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m; sourceTree = \"<group>\"; };\n\t\tD5FB0717B52FE2A1C59CA75D8CE483EA /* FIRInstallationsIIDStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIIDStore.m; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m; sourceTree = \"<group>\"; };\n\t\tD605D91349EBFFC6D84A254293FFF56F /* FIRCoreDiagnosticsInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreDiagnosticsInterop.h; path = Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsInterop.h; sourceTree = \"<group>\"; };\n\t\tD6368995E44A12ED775E22745EE36796 /* SDWebImageCompat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCompat.m; path = SDWebImage/Core/SDWebImageCompat.m; sourceTree = \"<group>\"; };\n\t\tD69D4E5A3DF64985BBF9D3080CCD6144 /* GULUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULUserDefaults.h; path = GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h; sourceTree = \"<group>\"; };\n\t\tD71B48D7039219AEB311FB0DA2E1E389 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Sources/Private/FIRComponent.h; sourceTree = \"<group>\"; };\n\t\tD75DB99AD94B959D922B1BF144AEFE15 /* SDAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImage.m; path = SDWebImage/Core/SDAnimatedImage.m; sourceTree = \"<group>\"; };\n\t\tD8ADAB8E982AFC5F2BD545EB091C78BD /* FIRInstallationsAuthTokenResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAuthTokenResult.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h; sourceTree = \"<group>\"; };\n\t\tD8BE8FDFF77007F5278B6A0E5BC01E6A /* pb_decode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_decode.c; sourceTree = \"<group>\"; };\n\t\tD92B4CC4E2762BD017DDAA71533D1487 /* SDWebImageDownloaderRequestModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderRequestModifier.m; path = SDWebImage/Core/SDWebImageDownloaderRequestModifier.m; sourceTree = \"<group>\"; };\n\t\tD9304F4CFD273BA0BC3D8FD8EA8CE973 /* SDWebImageDownloaderRequestModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderRequestModifier.h; path = SDWebImage/Core/SDWebImageDownloaderRequestModifier.h; sourceTree = \"<group>\"; };\n\t\tD934FF1B0DBCF555CAF470E0CF5AA900 /* GoogleUtilities.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.debug.xcconfig; sourceTree = \"<group>\"; };\n\t\tD955AAA9A402178AFCBD9F07B289BECB /* FirebaseCoreDiagnostics-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"FirebaseCoreDiagnostics-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tDA01E7E21E39AD745F362344A6F1CA3D /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIImageView+HighlightedWebCache.h\"; path = \"SDWebImage/Core/UIImageView+HighlightedWebCache.h\"; sourceTree = \"<group>\"; };\n\t\tDC55F3B02A125C1D8CBC59176095F043 /* GDTCORPlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORPlatform.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h; sourceTree = \"<group>\"; };\n\t\tDC743DAAB18B30FCDB192836851ADE13 /* PromisesObjC.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PromisesObjC.modulemap; sourceTree = \"<group>\"; };\n\t\tDC79300A6D291A17A3804A3511C41D9B /* GULNetworkLoggerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkLoggerProtocol.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h; sourceTree = \"<group>\"; };\n\t\tDD050D11898BDC1AE3F6FC357A319586 /* FirebaseCoreDiagnostics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCoreDiagnostics.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tDD42FC19A2CC2BEA3D2DBD52D86D8F36 /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = FirebaseCore/Sources/FIRBundleUtil.m; sourceTree = \"<group>\"; };\n\t\tDD910C5803E3E0E5E17C5ED00AFEEEC0 /* SDImageFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageFrame.h; path = SDWebImage/Core/SDImageFrame.h; sourceTree = \"<group>\"; };\n\t\tDDDFE2B6438138D00D92226D62FA76AD /* FIRInstallationsIIDTokenStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIIDTokenStore.m; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m; sourceTree = \"<group>\"; };\n\t\tDED0CE98C3CC1D5B1BEBB3F2409DF55E /* SDAsyncBlockOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAsyncBlockOperation.m; path = SDWebImage/Private/SDAsyncBlockOperation.m; sourceTree = \"<group>\"; };\n\t\tDEEA9E90B955F3FF75BD5CC9F8F49886 /* GDTCCTUploader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GDTCCTUploader.m; path = GoogleDataTransport/GDTCCTLibrary/GDTCCTUploader.m; sourceTree = \"<group>\"; };\n\t\tDFF930E1A1EF9818E6781AA056A03AD3 /* SDImageAWebPCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAWebPCoder.h; path = SDWebImage/Core/SDImageAWebPCoder.h; sourceTree = \"<group>\"; };\n\t\tE06211AF2F4E3047043DD4BCDC40403C /* NSBezierPath+SDRoundedCorners.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"NSBezierPath+SDRoundedCorners.h\"; path = \"SDWebImage/Private/NSBezierPath+SDRoundedCorners.h\"; sourceTree = \"<group>\"; };\n\t\tE19DD2593A51A0FEDEA7A4688C0D8645 /* GULSceneDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSceneDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m; sourceTree = \"<group>\"; };\n\t\tE21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };\n\t\tE2A2FCE7B47213F9F0585EA70EA2024A /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"UIView+WebCacheOperation.h\"; path = \"SDWebImage/Core/UIView+WebCacheOperation.h\"; sourceTree = \"<group>\"; };\n\t\tE2A88BFB19C447C4ED3DE4168952FE80 /* SDImageCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoder.h; path = SDWebImage/Core/SDImageCoder.h; sourceTree = \"<group>\"; };\n\t\tE2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCore; path = FirebaseCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tE30EDBDA563FB09CF5AE6965F2558FE9 /* Pods-Spotify-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"Pods-Spotify-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tE43C759DC1C3554D8988244726FFB280 /* FIRInstallationsIIDTokenStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIIDTokenStore.h; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h; sourceTree = \"<group>\"; };\n\t\tE666E3C34AF4E53A131BD4AF0F6ABA47 /* FirebaseCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"FirebaseCore-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tE6921E05E12367D79F30526D90D84BE6 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"SDWebImage-prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tE76B8095179CC1855E5CFA2FF2597A24 /* FBLPromiseError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromiseError.h; path = Sources/FBLPromises/include/FBLPromiseError.h; sourceTree = \"<group>\"; };\n\t\tE80E4257A841B7AA5C92B2CB19B16F0B /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = fr.lproj; sourceTree = \"<group>\"; };\n\t\tE9D885B6C37485841C093413F8E4B5CE /* FIRInstallationsItem+RegisterInstallationAPI.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FIRInstallationsItem+RegisterInstallationAPI.m\"; path = \"FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m\"; sourceTree = \"<group>\"; };\n\t\tE9E0C507183FA6B14B3FED0BB9BFE8E5 /* GDTCORFlatFileStorage+Promises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"GDTCORFlatFileStorage+Promises.h\"; path = \"GoogleDataTransport/GDTCORLibrary/Private/GDTCORFlatFileStorage+Promises.h\"; sourceTree = \"<group>\"; };\n\t\tEA1C659029357A11E03301278FD8D706 /* SDWebImageCacheSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheSerializer.m; path = SDWebImage/Core/SDWebImageCacheSerializer.m; sourceTree = \"<group>\"; };\n\t\tEACF04048B0827BDA828E835A7EA14C6 /* SDFileAttributeHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDFileAttributeHelper.m; path = SDWebImage/Private/SDFileAttributeHelper.m; sourceTree = \"<group>\"; };\n\t\tEB886795A3DF2E63330CE092DB9B5F46 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageRep.m; path = SDWebImage/Core/SDAnimatedImageRep.m; sourceTree = \"<group>\"; };\n\t\tEC28ED48C1E6F76572193AD374027BB7 /* SDMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDMemoryCache.m; path = SDWebImage/Core/SDMemoryCache.m; sourceTree = \"<group>\"; };\n\t\tEC2AA38D1492EE015AE393D7FCDBCDF1 /* GDTCOREventTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREventTransformer.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventTransformer.h; sourceTree = \"<group>\"; };\n\t\tEC47234C0173B2827334091E5C04C152 /* GDTCORUploadBatch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORUploadBatch.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadBatch.h; sourceTree = \"<group>\"; };\n\t\tEC847DD51A92AE89F533B4312E344982 /* FBLPromise+Await.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Await.m\"; path = \"Sources/FBLPromises/FBLPromise+Await.m\"; sourceTree = \"<group>\"; };\n\t\tEC9689AF5C4E7C5E057221C42B74F092 /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Sources/Private/FirebaseCoreInternal.h; sourceTree = \"<group>\"; };\n\t\tECF677E408094637A67960F364C6FA0D /* FBLPromise+Do.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Do.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Do.h\"; sourceTree = \"<group>\"; };\n\t\tEDF07392617868FE264D5E58788D279F /* FirebaseInstallations-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"FirebaseInstallations-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tEDF0E36BC33BC1C752AA5C64455974C1 /* GULNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"GULNSData+zlib.m\"; path = \"GoogleUtilities/NSData+zlib/GULNSData+zlib.m\"; sourceTree = \"<group>\"; };\n\t\tEE06EB2E171945BC2050FB3D4A038D02 /* FIRInstallationsIDController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIDController.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h; sourceTree = \"<group>\"; };\n\t\tEE0CECAF5DA5AAE13E1615E7B14147CB /* ar.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ar.lproj; sourceTree = \"<group>\"; };\n\t\tEE1ABBBCF34996AB6FAD3A7099D80CF5 /* FIRDiagnosticsData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDiagnosticsData.h; path = FirebaseCore/Sources/FIRDiagnosticsData.h; sourceTree = \"<group>\"; };\n\t\tEE2390C8AD53927134B524CBC997D50E /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIView+WebCacheOperation.m\"; path = \"SDWebImage/Core/UIView+WebCacheOperation.m\"; sourceTree = \"<group>\"; };\n\t\tEF3303042C21F9396439AB3DE71C7BB2 /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h; sourceTree = \"<group>\"; };\n\t\tEF7A55F92FBA10C1CA52F98BF5B091C9 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = es.lproj; sourceTree = \"<group>\"; };\n\t\tEF82E76BE97070A77C122D8CD5A2A852 /* GULReachabilityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULReachabilityChecker.m; path = GoogleUtilities/Reachability/GULReachabilityChecker.m; sourceTree = \"<group>\"; };\n\t\tEF8FCF0158C3FC321B0CCC8F87E286F6 /* GDTCOREndpoints_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCOREndpoints_Private.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCOREndpoints_Private.h; sourceTree = \"<group>\"; };\n\t\tEFD6BF26B215DD780EA6145DFEEC525A /* FBLPromise+Race.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Race.m\"; path = \"Sources/FBLPromises/FBLPromise+Race.m\"; sourceTree = \"<group>\"; };\n\t\tF03A138FFFD47F81003F3160EC8E9953 /* SDAnimatedImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"SDAnimatedImageView+WebCache.m\"; path = \"SDWebImage/Core/SDAnimatedImageView+WebCache.m\"; sourceTree = \"<group>\"; };\n\t\tF0647D92B0FBA5FC4BF6371012FEE181 /* FBLPromise+Testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Testing.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Testing.h\"; sourceTree = \"<group>\"; };\n\t\tF0A654F37AEA764934660E26E3BD2475 /* SDImageLoadersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoadersManager.h; path = SDWebImage/Core/SDImageLoadersManager.h; sourceTree = \"<group>\"; };\n\t\tF124022073EADCF94FCBED857E5EABBB /* Pods-Spotify-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"Pods-Spotify-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\tF1A5B63B766812910C3FC66A4D5BD359 /* FBLPromise+Reduce.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Reduce.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Reduce.h\"; sourceTree = \"<group>\"; };\n\t\tF1DFF11C55F9B1D83DF7C7397FDACBA2 /* FIRInstallationsAPIService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAPIService.h; path = FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h; sourceTree = \"<group>\"; };\n\t\tF2EC88E51FC34B63E85F84778E9C618A /* SDImageFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageFrame.m; path = SDWebImage/Core/SDImageFrame.m; sourceTree = \"<group>\"; };\n\t\tF34C30C677383D5895A28720200014A4 /* FIRFirebaseUserAgent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRFirebaseUserAgent.h; path = FirebaseCore/Sources/FIRFirebaseUserAgent.h; sourceTree = \"<group>\"; };\n\t\tF35AA80907A78AC92F34C61F368248E7 /* FBLPromise.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromise.h; path = Sources/FBLPromises/include/FBLPromise.h; sourceTree = \"<group>\"; };\n\t\tF36DCFF7B72CE2940864E1364072151A /* GULHeartbeatDateStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULHeartbeatDateStorage.m; path = GoogleUtilities/Environment/GULHeartbeatDateStorage.m; sourceTree = \"<group>\"; };\n\t\tF3A8A80738539221543E61697604F331 /* GoogleDataTransport-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"GoogleDataTransport-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tF3DF4F3E573CB800D27E86168DD5EECB /* UIButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIButton+WebCache.m\"; path = \"SDWebImage/Core/UIButton+WebCache.m\"; sourceTree = \"<group>\"; };\n\t\tF457C5FADED7F6B16F8F8C265309AEA7 /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"nanopb-prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tF463B32358D0340C851CB2FCB8E3B0A5 /* FIRInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h; sourceTree = \"<group>\"; };\n\t\tF4A7F01DAC8F3E158C6CB70DD5E60C24 /* da.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = da.lproj; sourceTree = \"<group>\"; };\n\t\tF53274C0B6BDFB6F2402643CF71B2F77 /* SDWebImageDownloaderConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderConfig.h; path = SDWebImage/Core/SDWebImageDownloaderConfig.h; sourceTree = \"<group>\"; };\n\t\tF538296E4FA1BF861A19524F47E7A6D5 /* SDImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoader.h; path = SDWebImage/Core/SDImageLoader.h; sourceTree = \"<group>\"; };\n\t\tF582A3CDAC1DDA3FCEA8CB2C13293A4D /* Firebase.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tF589BA173CD44451894C642200BAD5A9 /* GDTCORTargets.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORTargets.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTargets.h; sourceTree = \"<group>\"; };\n\t\tF59DA2817374C9606A05E0D57A6993AB /* SDImageAWebPCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAWebPCoder.m; path = SDWebImage/Core/SDImageAWebPCoder.m; sourceTree = \"<group>\"; };\n\t\tF6FF94050EDDF80FD2501F4E30F18E4D /* GDTCORUploadCoordinator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORUploadCoordinator.h; path = GoogleDataTransport/GDTCORLibrary/Private/GDTCORUploadCoordinator.h; sourceTree = \"<group>\"; };\n\t\tF80FBEC0B534E33030C9ECCABDD9BE62 /* GULKeychainUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULKeychainUtils.m; path = GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m; sourceTree = \"<group>\"; };\n\t\tF848EBF5A77518F1437E59128B898ACE /* SDWebImageOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageOperation.m; path = SDWebImage/Core/SDWebImageOperation.m; sourceTree = \"<group>\"; };\n\t\tF917DFD015523A1E48D920C0FAC03683 /* nanopb.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = nanopb.modulemap; sourceTree = \"<group>\"; };\n\t\tF9DD6F50E5F16B3EE2AFBBBA48053FA5 /* SDWebImageCacheKeyFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheKeyFilter.m; path = SDWebImage/Core/SDWebImageCacheKeyFilter.m; sourceTree = \"<group>\"; };\n\t\tFA50FFBEC226EAB798930460C18C4350 /* SDWebImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImage.modulemap; sourceTree = \"<group>\"; };\n\t\tFAE1DA94ED4CE423E2B4A57176826E98 /* FirebaseAnalytics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tFB7600C02A26CBAC1E67CFF0278A198D /* SDImageGIFCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoder.h; path = SDWebImage/Core/SDImageGIFCoder.h; sourceTree = \"<group>\"; };\n\t\tFB9896C32514099F18D7AA422602FB04 /* FBLPromise+Always.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = \"FBLPromise+Always.h\"; path = \"Sources/FBLPromises/include/FBLPromise+Always.h\"; sourceTree = \"<group>\"; };\n\t\tFC10065E60D607F83A9C96DF9332A2FD /* FirebaseAnalytics-xcframeworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = \"FirebaseAnalytics-xcframeworks.sh\"; sourceTree = \"<group>\"; };\n\t\tFC22CB2FD3FE9BC3D607B5CA39155B83 /* GULReachabilityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityChecker.h; path = GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h; sourceTree = \"<group>\"; };\n\t\tFC23427538EE1DBB11F5EBBAAB6A513D /* SDDeviceHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDeviceHelper.h; path = SDWebImage/Private/SDDeviceHelper.h; sourceTree = \"<group>\"; };\n\t\tFC3C259DB11E51E08F2D5630A5145839 /* pt.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = pt.lproj; sourceTree = \"<group>\"; };\n\t\tFC6A0016A0D695FE4F0D2BCB7B58E53B /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = \"<group>\"; };\n\t\tFCA00A91EC23FFE0892B9D0F0B84F617 /* FBLPromiseError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBLPromiseError.m; path = Sources/FBLPromises/FBLPromiseError.m; sourceTree = \"<group>\"; };\n\t\tFDCDC0DC5EBD4242B3B44E167355E955 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"UIImageView+WebCache.m\"; path = \"SDWebImage/Core/UIImageView+WebCache.m\"; sourceTree = \"<group>\"; };\n\t\tFDF404E683FC3DE61DCE91FF8B1E0842 /* pb_encode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_encode.h; sourceTree = \"<group>\"; };\n\t\tFDF958DE0F2E4C471517C45865738FDF /* FirebaseCore.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseCore.modulemap; sourceTree = \"<group>\"; };\n\t\tFE8190044D8F103421DED7166A530383 /* GDTCCTNanopbHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCCTNanopbHelpers.h; path = GoogleDataTransport/GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h; sourceTree = \"<group>\"; };\n\t\tFEA2BFC7C6DBDD183F3EC0220976D86F /* FIRDiagnosticsData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDiagnosticsData.m; path = FirebaseCore/Sources/FIRDiagnosticsData.m; sourceTree = \"<group>\"; };\n\t\tFEE086E4BCB7B965DFED58170011ADD2 /* uk.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = uk.lproj; sourceTree = \"<group>\"; };\n\t\tFEE20DA431EFAB6E9DE3F14B005CCF75 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/GULReachabilityMessageCode.h; sourceTree = \"<group>\"; };\n\t\tFEE29B50BED2D3B4F195FBAF219817D9 /* SDFileAttributeHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDFileAttributeHelper.h; path = SDWebImage/Private/SDFileAttributeHelper.h; sourceTree = \"<group>\"; };\n\t\tFF32D6A22D56F5787F289A4BEA15E6A1 /* SDWebImageOptionsProcessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOptionsProcessor.h; path = SDWebImage/Core/SDWebImageOptionsProcessor.h; sourceTree = \"<group>\"; };\n\t\tFF3EF4B23861192F1BF203B7E288A145 /* SDImageCacheDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheDefine.m; path = SDWebImage/Core/SDImageCacheDefine.m; sourceTree = \"<group>\"; };\n\t\tFF60EBD5E154FA9A791F0C421B4D9AEE /* FBLPromise+Reduce.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = \"FBLPromise+Reduce.m\"; path = \"Sources/FBLPromises/FBLPromise+Reduce.m\"; sourceTree = \"<group>\"; };\n\t\tFF8CD99087C3A386C87B8B64F6814912 /* nanopb-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"nanopb-dummy.m\"; sourceTree = \"<group>\"; };\n\t\tFFBEACDBC00E47FDCE130333C01BDD52 /* GDTCORStorageEventSelector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORStorageEventSelector.h; path = GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageEventSelector.h; sourceTree = \"<group>\"; };\n\t\tFFC85887576AED4EB7D6127CC1FDC955 /* GDTCORTransport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GDTCORTransport.h; path = GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORTransport.h; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t2F90AC4B1394693187B33E9454925C26 /* 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\t\t557258F7F82A8926BA01926A0CB40E15 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF1F24427266F56690C90DBC258A8E712 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t751E8AA0AFD15DFD93F5C1D10458E77C /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2DD7B33B4FB4F06F6BDB9FDE23463CCC /* CFNetwork.framework in Frameworks */,\n\t\t\t\tB5C56C4D45E7E7A9630F9417A6E39C1D /* Foundation.framework in Frameworks */,\n\t\t\t\t7061D35639F93885B8A80B3B7FE090F7 /* SystemConfiguration.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tA9D2F93060742D670740AA52D4F1A7BE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t84B818EEE3E3EE948F29B61A752BFC0B /* Foundation.framework in Frameworks */,\n\t\t\t\t0D4FBF072F6431A5D5324C83FC2E5DE7 /* Security.framework in Frameworks */,\n\t\t\t\t6503E1414B68019CD76455273240A263 /* SystemConfiguration.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tADD00E3E8A0426067D803A942C3BA84C /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t14B49802A4BD5C9EB648342B539ACC0E /* Foundation.framework in Frameworks */,\n\t\t\t\t2E30ED9EE4AA861FAB2BD7E875BFFCC2 /* UIKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tD7D014542D95DD38C8C2502010D4CD43 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCEBCB78AD6ADE2D0F18F7D9E07D5C4DB /* Foundation.framework in Frameworks */,\n\t\t\t\tAC551E9186602377EC1751E316CDCEC2 /* Security.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tD8CEF8654739A822265F965518353CC2 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tAC76D5E67DCEFB22BE84148317D7B5A5 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDA11FA7A020AFDCA73B93EDF3D3F1073 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCF4DAD38BC9565548EC08D14D2B6541C /* CoreTelephony.framework in Frameworks */,\n\t\t\t\t940AEABD2B727E9478DD58CB3EF383F6 /* Foundation.framework in Frameworks */,\n\t\t\t\t7100C2CFC22D1689ADA78A36E65B697B /* SystemConfiguration.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF0861647ADFD6A6E877396A52F43B90A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t714EB6036BF393E60ADE1F6F2C7E8A1F /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF9DE14B7D99DBDE04A0AC39B6C4F83E3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB519045D5C102170273EDD0B9D141F94 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tFB6A1E8A43CF1D3ADFB49BA355F0DEA1 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t5A3E5B854E8188DDF4E958BBC9198600 /* Foundation.framework in Frameworks */,\n\t\t\t\t51F891EA712D8F14CF1DD77BF20B62A9 /* ImageIO.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t02D4B1661A567187466821708E44DE0A /* CoreOnly */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5415E857C6437079EA6CE8D49BC4D00F /* Firebase.h */,\n\t\t\t);\n\t\t\tname = CoreOnly;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t058C19C88B10171A17924987A122D927 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t32B0EB1571B6CA660B7AD773851B90C5 /* FirebaseAnalytics.xcframework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t0C6CEC6D687B3736917288BC43D2B350 /* AppDelegateSwizzler */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9C35CA5CB6C0053B485FCFDFD30A1662 /* GULAppDelegateSwizzler.h */,\n\t\t\t\t16A5A619D3393C3652027A63F8D6406E /* GULAppDelegateSwizzler.m */,\n\t\t\t\t5C5DD83B8521D66EB85A5A45A92F810F /* GULAppDelegateSwizzler_Private.h */,\n\t\t\t\tB134BD979A35DB81CA4CBD64BE86AAC5 /* GULApplication.h */,\n\t\t\t\t08586FD84613D5B8D0037AF3714A8D9F /* GULLoggerCodes.h */,\n\t\t\t\tD327D14764B30DDEEB17666FA535871D /* GULSceneDelegateSwizzler.h */,\n\t\t\t\tE19DD2593A51A0FEDEA7A4688C0D8645 /* GULSceneDelegateSwizzler.m */,\n\t\t\t\t56EBF81C7BB707870CF8F18F19C219BC /* GULSceneDelegateSwizzler_Private.h */,\n\t\t\t);\n\t\t\tname = AppDelegateSwizzler;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t16EF75AC256F0C94C6273A51CFE74355 /* Targets Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB7C5491CCF4E11B34D2C388422157234 /* Pods-Spotify */,\n\t\t\t);\n\t\t\tname = \"Targets Support Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t1AE034B84201B1046BCCE51577E15354 /* FirebaseCore */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668CE7FB58FBCA03E7BF9FFA7D4AEA8C /* FIRAnalyticsConfiguration.h */,\n\t\t\t\t2B055BE0C98324B8E1EE0B588C14B23C /* FIRAnalyticsConfiguration.m */,\n\t\t\t\tC2B6C797B8E1770AE7FB92B865BB499B /* FIRApp.h */,\n\t\t\t\t3C2FEB053783A6171CE3DECCFF936A28 /* FIRApp.m */,\n\t\t\t\t5CBCB878C4026B383CA6687B4DC52D58 /* FIRAppAssociationRegistration.h */,\n\t\t\t\tA0F0A5A8418FA40166272625AFB5330A /* FIRAppAssociationRegistration.m */,\n\t\t\t\t48972591E3AF0F13726EC5D4C6BEDFDC /* FIRAppInternal.h */,\n\t\t\t\t303FE2537CE3769B58923B71632FED1C /* FIRBundleUtil.h */,\n\t\t\t\tDD42FC19A2CC2BEA3D2DBD52D86D8F36 /* FIRBundleUtil.m */,\n\t\t\t\t92EA46401122BB560F222964810DAE14 /* FIRComponent.h */,\n\t\t\t\t00287C1BECC76217689476B210B41A36 /* FIRComponent.m */,\n\t\t\t\t82AAE98FB8E850A8ECBA43F727AD3F4B /* FIRComponentContainer.h */,\n\t\t\t\tAE8073B498E3701A492F026966747912 /* FIRComponentContainer.m */,\n\t\t\t\tC2EDD3FE368044C57FFE267748AD31CE /* FIRComponentContainerInternal.h */,\n\t\t\t\tB3310E7F0BD29950EA79269F8864E7B0 /* FIRComponentType.h */,\n\t\t\t\t1B185568A19C67E5278D6DB507473C2B /* FIRComponentType.m */,\n\t\t\t\tA8689F656BCD2DE359141CDE820E425F /* FIRConfiguration.h */,\n\t\t\t\tA3142D0BC0A7099D82BA56A3FD637656 /* FIRConfiguration.m */,\n\t\t\t\t7055DAE8B926D478FFCB05DC46E7F844 /* FIRConfigurationInternal.h */,\n\t\t\t\t1DFB6F1D058B390F2A1340D6D90391C0 /* FIRCoreDiagnosticsConnector.h */,\n\t\t\t\t8E7ED49344AE0AC6AD92262E047201BD /* FIRCoreDiagnosticsConnector.m */,\n\t\t\t\tA7D509EE7C37DC62C5F5119B2692E792 /* FIRCoreDiagnosticsData.h */,\n\t\t\t\tD605D91349EBFFC6D84A254293FFF56F /* FIRCoreDiagnosticsInterop.h */,\n\t\t\t\tB3DC2C81260A550A30B6C664556BAD8A /* FIRDependency.h */,\n\t\t\t\tCC9B5348D8E36B88FD0E3329BCF4479D /* FIRDependency.m */,\n\t\t\t\tEE1ABBBCF34996AB6FAD3A7099D80CF5 /* FIRDiagnosticsData.h */,\n\t\t\t\tFEA2BFC7C6DBDD183F3EC0220976D86F /* FIRDiagnosticsData.m */,\n\t\t\t\t3BB2E5C745E6BEBDF556017B5389A3F8 /* FirebaseCore.h */,\n\t\t\t\tEC9689AF5C4E7C5E057221C42B74F092 /* FirebaseCoreInternal.h */,\n\t\t\t\tF34C30C677383D5895A28720200014A4 /* FIRFirebaseUserAgent.h */,\n\t\t\t\t893980C67675F297617FB935213E4671 /* FIRFirebaseUserAgent.m */,\n\t\t\t\t5E16667A1668B640A863FF171D2CB5FB /* FIRHeartbeatInfo.h */,\n\t\t\t\t8454F0C4E786C6A2499ED8DA5879A808 /* FIRHeartbeatInfo.m */,\n\t\t\t\tC76E61D46C6D64C4743B6A7256A286EF /* FIRLibrary.h */,\n\t\t\t\t4953F3D24A404D00A99D8A29BE61104C /* FIRLogger.h */,\n\t\t\t\t0720E29DA86F4D52C08D6942FFEF190A /* FIRLogger.m */,\n\t\t\t\tA4A6DED8C7023B5E793A748ED43129EE /* FIRLoggerLevel.h */,\n\t\t\t\t1BF0F7EE147A98C2F11F7C4C32C5B6E3 /* FIROptions.h */,\n\t\t\t\t9BA476F642687D5FC7AA27BDDA27DEBC /* FIROptions.m */,\n\t\t\t\t0323C2AB5A72DF893829A51D8F181F49 /* FIROptionsInternal.h */,\n\t\t\t\t38A7BC4B65A58A155D087DA3EFFC1D79 /* FIRVersion.h */,\n\t\t\t\t724419369F9B475400E63E05193D0394 /* FIRVersion.m */,\n\t\t\t\t54C7F450DCD0A9B6831BDE3285A54B1F /* Support Files */,\n\t\t\t);\n\t\t\tname = FirebaseCore;\n\t\t\tpath = FirebaseCore;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t1AFCC02FC929E5DD450B688E200653B7 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDC743DAAB18B30FCDB192836851ADE13 /* PromisesObjC.modulemap */,\n\t\t\t\t36C228F973FB461AAC3DE1B3CAC5533C /* PromisesObjC-dummy.m */,\n\t\t\t\t22B79826946DBE0D731ED6479069F8C1 /* PromisesObjC-Info.plist */,\n\t\t\t\t7BF54C90D1DF4DD3950B8DCD5C09D18C /* PromisesObjC-umbrella.h */,\n\t\t\t\tC5674D03956C9BD31033CABEEFE4F2E1 /* PromisesObjC.debug.xcconfig */,\n\t\t\t\tB526E38BA63C966AF02EA09F26802535 /* PromisesObjC.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/PromisesObjC\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t1FC49855849F77DD042774C08FB9A2BD /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t23D4D9F87518207E73E88D8FBC7C8DE3 /* Appirater */,\n\t\t\t\t1E9CD753F6BD26760EFAA1DF57482D50 /* Appirater-Appirater */,\n\t\t\t\tE2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */,\n\t\t\t\t8CC9178C366942FD6FF6A115604EAD58 /* FirebaseCoreDiagnostics */,\n\t\t\t\t13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */,\n\t\t\t\t856B5CD56F194FAD26EA91620B66D614 /* GoogleDataTransport */,\n\t\t\t\tB43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */,\n\t\t\t\t06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */,\n\t\t\t\t97DFD7435A40FB6C7611C58681006DC8 /* Pods-Spotify */,\n\t\t\t\t3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */,\n\t\t\t\tB0B214D775196BA7CA8E17E53048A493 /* SDWebImage */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2152BB9B7EF0C69F7B86DE1EF926D67F /* Firebase */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t02D4B1661A567187466821708E44DE0A /* CoreOnly */,\n\t\t\t\tEF5B961421EC2787E78401B772CC91D5 /* Support Files */,\n\t\t\t);\n\t\t\tname = Firebase;\n\t\t\tpath = Firebase;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t278C4253D3F115DE5037DF8D472B252D /* AdIdSupport */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAC1136BE3B047EDE3C63B82F0FADFAAC /* Frameworks */,\n\t\t\t);\n\t\t\tname = AdIdSupport;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3082F193C8D1BA24D51A7BC01CEBD841 /* SDWebImage */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6FEF14F9A1B0B218432F7694289CDFF5 /* Core */,\n\t\t\t\t82ABAFE15F86B5F2F88A2DAA6D6FF5C9 /* Support Files */,\n\t\t\t);\n\t\t\tname = SDWebImage;\n\t\t\tpath = SDWebImage;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3DA5ECD28DB682EEB7CE60E41A95AC39 /* MethodSwizzler */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC2439987FF247C8C084181EBCF11641F /* GULOriginalIMPConvenienceMacros.h */,\n\t\t\t\t6C61DBDC1219C0AC0AD0FF84A0133692 /* GULSwizzler.h */,\n\t\t\t\t75E9E1284F8AE50551FF56600DDDCEBF /* GULSwizzler.m */,\n\t\t\t);\n\t\t\tname = MethodSwizzler;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t48EA86F33969C2420662B0A62E5A9FCE /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF917DFD015523A1E48D920C0FAC03683 /* nanopb.modulemap */,\n\t\t\t\tFF8CD99087C3A386C87B8B64F6814912 /* nanopb-dummy.m */,\n\t\t\t\t061F4EB74D749A7F360F62B20F46294A /* nanopb-Info.plist */,\n\t\t\t\tF457C5FADED7F6B16F8F8C265309AEA7 /* nanopb-prefix.pch */,\n\t\t\t\t29AE365492E6E96E5708A9AD6E31746F /* nanopb-umbrella.h */,\n\t\t\t\t83D038C4E24C71BFAE211A6E0CDA58BA /* nanopb.debug.xcconfig */,\n\t\t\t\tC5E56AF681704D05296BF6544BFD6DBC /* nanopb.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/nanopb\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4DEE105FF0FD390E62D91CCF24486B2A /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tFC10065E60D607F83A9C96DF9332A2FD /* FirebaseAnalytics-xcframeworks.sh */,\n\t\t\t\t04119D68F2961D5912F24F5066E00D0D /* FirebaseAnalytics.debug.xcconfig */,\n\t\t\t\tFAE1DA94ED4CE423E2B4A57176826E98 /* FirebaseAnalytics.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/FirebaseAnalytics\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t54C7F450DCD0A9B6831BDE3285A54B1F /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tFDF958DE0F2E4C471517C45865738FDF /* FirebaseCore.modulemap */,\n\t\t\t\tE666E3C34AF4E53A131BD4AF0F6ABA47 /* FirebaseCore-dummy.m */,\n\t\t\t\t859E0D4CB486D5A4710D605554199885 /* FirebaseCore-Info.plist */,\n\t\t\t\t63FB1BA9182BB6D6E47E4DD049005A29 /* FirebaseCore-umbrella.h */,\n\t\t\t\tACE81B64A65F8AF15E7C822CDF6A73E6 /* FirebaseCore.debug.xcconfig */,\n\t\t\t\t2368DD7767138A73CD7D9EADED904481 /* FirebaseCore.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/FirebaseCore\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5544FD9AFB77FFE3A00CB2505C4726A3 /* UserDefaults */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD69D4E5A3DF64985BBF9D3080CCD6144 /* GULUserDefaults.h */,\n\t\t\t\tCF805F43FFDD645D95C1ACEABC114049 /* GULUserDefaults.m */,\n\t\t\t);\n\t\t\tname = UserDefaults;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5633E1A74655186D803F0C91BD6B16C0 /* NSData+zlib */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tBD01D4D2C9BD8D230AC07E17D1BC2580 /* GULNSData+zlib.h */,\n\t\t\t\tEDF0E36BC33BC1C752AA5C64455974C1 /* GULNSData+zlib.m */,\n\t\t\t);\n\t\t\tname = \"NSData+zlib\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5D0B7910C5928FF0F06049E99FAACD41 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAE780E851F5F67AAA9C4AE38402A4086 /* GoogleDataTransport.modulemap */,\n\t\t\t\t932BDDF177FD04B28E9285096E7D291C /* GoogleDataTransport-dummy.m */,\n\t\t\t\tF3A8A80738539221543E61697604F331 /* GoogleDataTransport-Info.plist */,\n\t\t\t\t881ACDC9E0325D12479F43AD079D1CBB /* GoogleDataTransport-umbrella.h */,\n\t\t\t\tBA393B4B24C719DDDC878C0A08B2D1BB /* GoogleDataTransport.debug.xcconfig */,\n\t\t\t\tBE37397A0A9B84C77A7B34A9406A3952 /* GoogleDataTransport.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/GoogleDataTransport\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t62A2F567C67C028B3713BC180E3A5B8C /* FirebaseInstallations */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B0B7773B93F50516AFA7A4AD80001F /* FIRAppInternal.h */,\n\t\t\t\tD71B48D7039219AEB311FB0DA2E1E389 /* FIRComponent.h */,\n\t\t\t\t6BA2A90BF46E4D5796820E1A900E2C0B /* FIRComponentContainer.h */,\n\t\t\t\t5514ED015845BE4DF10DF85BF4983A59 /* FIRComponentType.h */,\n\t\t\t\t747BA4839026A5B48F78F7F2F59B01D8 /* FIRCoreDiagnosticsConnector.h */,\n\t\t\t\tB349AD374EBA10C2D49FC4BA8A53F0CF /* FIRCurrentDateProvider.h */,\n\t\t\t\tB17DB1B80794FEE3D7DC12CB3641AB30 /* FIRCurrentDateProvider.m */,\n\t\t\t\tC887379F2FAEEA195D743E2A7E8695B2 /* FIRDependency.h */,\n\t\t\t\t45405CBF1024B18B4589ED32B6B9D343 /* FirebaseCoreInternal.h */,\n\t\t\t\t183B8EEF2BA8C735371935889864D6B7 /* FirebaseInstallations.h */,\n\t\t\t\t3EAF64B24EEF15C83158B0A1B832978D /* FirebaseInstallationsInternal.h */,\n\t\t\t\t8CDC11191CD5FAC6E9AA96E2BC7DAD05 /* FIRHeartbeatInfo.h */,\n\t\t\t\tF463B32358D0340C851CB2FCB8E3B0A5 /* FIRInstallations.h */,\n\t\t\t\t07E9568C4EE8BF77740269310C486888 /* FIRInstallations.m */,\n\t\t\t\tF1DFF11C55F9B1D83DF7C7397FDACBA2 /* FIRInstallationsAPIService.h */,\n\t\t\t\t6A35F8BE947883A35C48CDFFF5BACB72 /* FIRInstallationsAPIService.m */,\n\t\t\t\tD8ADAB8E982AFC5F2BD545EB091C78BD /* FIRInstallationsAuthTokenResult.h */,\n\t\t\t\tD54DA10983EF09ABC480187282A87A58 /* FIRInstallationsAuthTokenResult.m */,\n\t\t\t\t1AA30DDE545C3AB8E5A8BCD08CA5B923 /* FIRInstallationsAuthTokenResultInternal.h */,\n\t\t\t\t382D07A53D722649DCAD5C5BC3BDCAC1 /* FIRInstallationsBackoffController.h */,\n\t\t\t\t6E03F27C2DCF8DB117CBC29C875DCD95 /* FIRInstallationsBackoffController.m */,\n\t\t\t\t46849267116D15C2F916F95AF7ED6264 /* FIRInstallationsErrors.h */,\n\t\t\t\t6E7EB7DF29D03415C41C56734E0C9017 /* FIRInstallationsErrorUtil.h */,\n\t\t\t\t6237C8DA5406A972EAFEEC2CB46AA910 /* FIRInstallationsErrorUtil.m */,\n\t\t\t\t0E3D719558B6C623CB196272CE80D92B /* FIRInstallationsHTTPError.h */,\n\t\t\t\tB5E3DBB2F100E0A299BCFC77EBC69A7E /* FIRInstallationsHTTPError.m */,\n\t\t\t\tEE06EB2E171945BC2050FB3D4A038D02 /* FIRInstallationsIDController.h */,\n\t\t\t\t2DDBED0511F929D50127372614C07E38 /* FIRInstallationsIDController.m */,\n\t\t\t\t703B93588CDC01E3116988AAD425A74D /* FIRInstallationsIIDStore.h */,\n\t\t\t\tD5FB0717B52FE2A1C59CA75D8CE483EA /* FIRInstallationsIIDStore.m */,\n\t\t\t\tE43C759DC1C3554D8988244726FFB280 /* FIRInstallationsIIDTokenStore.h */,\n\t\t\t\tDDDFE2B6438138D00D92226D62FA76AD /* FIRInstallationsIIDTokenStore.m */,\n\t\t\t\tD29D1ACD3388DF30F5213782D0089AAE /* FIRInstallationsItem.h */,\n\t\t\t\t9E08253131AF6EBD5597DF21EBF9B98D /* FIRInstallationsItem.m */,\n\t\t\t\tBAB945382DE7BCE1238478DF4341D1C3 /* FIRInstallationsItem+RegisterInstallationAPI.h */,\n\t\t\t\tE9D885B6C37485841C093413F8E4B5CE /* FIRInstallationsItem+RegisterInstallationAPI.m */,\n\t\t\t\t99108619FD685C7E04AA2798D8184E88 /* FIRInstallationsLogger.h */,\n\t\t\t\tCAFA66ED08EE2214A12519DB72F11801 /* FIRInstallationsLogger.m */,\n\t\t\t\tA55020CA6EDE9396075075D402E84AEC /* FIRInstallationsSingleOperationPromiseCache.h */,\n\t\t\t\t7387A62B07188200FF8487FD3A2CF2A5 /* FIRInstallationsSingleOperationPromiseCache.m */,\n\t\t\t\t33282DA51418F8E945CDA2BC7DDA734E /* FIRInstallationsStatus.h */,\n\t\t\t\tB46C4D5C2FF1FB2417D06ADB91D1CEBA /* FIRInstallationsStore.h */,\n\t\t\t\tA328CD57DBA12543441049EBF409F205 /* FIRInstallationsStore.m */,\n\t\t\t\t4187F6DA61736F8AD4201616D23D8061 /* FIRInstallationsStoredAuthToken.h */,\n\t\t\t\t6F25465DB16E55EFF41F24C620E24E05 /* FIRInstallationsStoredAuthToken.m */,\n\t\t\t\t25D0D7E32DDD7AE56C23799445C13A57 /* FIRInstallationsStoredItem.h */,\n\t\t\t\t9484BA52176E0E66CBDC23122D2948A2 /* FIRInstallationsStoredItem.m */,\n\t\t\t\tBE1CFCA4C81C90732F8DB42EA1F017A3 /* FIRLibrary.h */,\n\t\t\t\tC18C4496C07F34201871F99AD27069A0 /* FIRLogger.h */,\n\t\t\t\t15F02952828900F1CC5E66B83274F6E0 /* FIROptionsInternal.h */,\n\t\t\t\tBA6859418815F5231E3CEAAA21D0F012 /* Support Files */,\n\t\t\t);\n\t\t\tname = FirebaseInstallations;\n\t\t\tpath = FirebaseInstallations;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6E122AC728989052F6E7D19E4F6218E6 /* Logger */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t32B1014C844F5619D536DFD1800B11D5 /* GULLogger.h */,\n\t\t\t\t4468F16CABC244B58ACDC50E87F8B3C4 /* GULLogger.m */,\n\t\t\t\t82EAA36E76AE8F4E664A68EC8EB36298 /* GULLoggerLevel.h */,\n\t\t\t);\n\t\t\tname = Logger;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6EF332B85D74AC3B2E0615B4F1FB4DC5 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD368B1A08214DF1EF6A0A9F4860161C0 /* FirebaseCoreDiagnostics.modulemap */,\n\t\t\t\tD955AAA9A402178AFCBD9F07B289BECB /* FirebaseCoreDiagnostics-dummy.m */,\n\t\t\t\t073BC434BDEB48DDF3B92DF041D277CE /* FirebaseCoreDiagnostics-Info.plist */,\n\t\t\t\t34A40FBEB8C0F4629E017EA065211E5C /* FirebaseCoreDiagnostics-umbrella.h */,\n\t\t\t\tC52C466DF84E99205E54E0AEC7DF14B2 /* FirebaseCoreDiagnostics.debug.xcconfig */,\n\t\t\t\tDD050D11898BDC1AE3F6FC357A319586 /* FirebaseCoreDiagnostics.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/FirebaseCoreDiagnostics\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6FEF14F9A1B0B218432F7694289CDFF5 /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE06211AF2F4E3047043DD4BCDC40403C /* NSBezierPath+SDRoundedCorners.h */,\n\t\t\t\t8DFCA2753EDD74C8B7D46CD39BC4F756 /* NSBezierPath+SDRoundedCorners.m */,\n\t\t\t\tBA37D2C1168173A7796B05F93479A231 /* NSButton+WebCache.h */,\n\t\t\t\tCE0BC2BA98097A46FED66139FADDB5C2 /* NSButton+WebCache.m */,\n\t\t\t\t31527FC5A967FDE9F076D544F4923295 /* NSData+ImageContentType.h */,\n\t\t\t\t2D682D19C50EF105FF8EF05D677CA964 /* NSData+ImageContentType.m */,\n\t\t\t\t2264D3828F48F1D2D87C73BE181475A2 /* NSImage+Compatibility.h */,\n\t\t\t\t8D2E7ABE07934F659148C41C852087FD /* NSImage+Compatibility.m */,\n\t\t\t\t615A6102144F4931AF689AB96C01D719 /* SDAnimatedImage.h */,\n\t\t\t\tD75DB99AD94B959D922B1BF144AEFE15 /* SDAnimatedImage.m */,\n\t\t\t\t3FA3607B121AEFB0595C76441513C64D /* SDAnimatedImagePlayer.h */,\n\t\t\t\t17A959EECDBC8B53DAF62371054DAAE9 /* SDAnimatedImagePlayer.m */,\n\t\t\t\tB95FF8BC5E40163C886E3DB1B394DD75 /* SDAnimatedImageRep.h */,\n\t\t\t\tEB886795A3DF2E63330CE092DB9B5F46 /* SDAnimatedImageRep.m */,\n\t\t\t\t3808D78CAA3EAA14B869A1667210193C /* SDAnimatedImageView.h */,\n\t\t\t\tB4A0C1F3F59FF0ECC737E3A22B64F7F0 /* SDAnimatedImageView.m */,\n\t\t\t\tCF04F211D2AE46EEBF166D2CC374B517 /* SDAnimatedImageView+WebCache.h */,\n\t\t\t\tF03A138FFFD47F81003F3160EC8E9953 /* SDAnimatedImageView+WebCache.m */,\n\t\t\t\tC6A1BDEE41C3F181B6BAC16ADB84601E /* SDAssociatedObject.h */,\n\t\t\t\t80FE85865E814FFFE9FC4BD1E92FF02B /* SDAssociatedObject.m */,\n\t\t\t\t0440093C278700F6A5362B45AD5DBC91 /* SDAsyncBlockOperation.h */,\n\t\t\t\tDED0CE98C3CC1D5B1BEBB3F2409DF55E /* SDAsyncBlockOperation.m */,\n\t\t\t\tFC23427538EE1DBB11F5EBBAAB6A513D /* SDDeviceHelper.h */,\n\t\t\t\t32DB218DD71AD0570B0E339E5319F93B /* SDDeviceHelper.m */,\n\t\t\t\t25E74C0A2D416186897FBBC33BC5608B /* SDDiskCache.h */,\n\t\t\t\t9B960865AD112FB963F482E45E567B56 /* SDDiskCache.m */,\n\t\t\t\t7CE88DC6249A53E194E886FD268B4F22 /* SDDisplayLink.h */,\n\t\t\t\t33802E944806D1B99AD085FE7F697A74 /* SDDisplayLink.m */,\n\t\t\t\tFEE29B50BED2D3B4F195FBAF219817D9 /* SDFileAttributeHelper.h */,\n\t\t\t\tEACF04048B0827BDA828E835A7EA14C6 /* SDFileAttributeHelper.m */,\n\t\t\t\t2B207171596C8E59567CB49A2BC0B7C9 /* SDGraphicsImageRenderer.h */,\n\t\t\t\t0FC4393F5EB9D10CAC25D438B9ECB2A3 /* SDGraphicsImageRenderer.m */,\n\t\t\t\tB1C3F5E1F2DA4D224862FC3F811D0917 /* SDImageAPNGCoder.h */,\n\t\t\t\t37B1C403940FAFD0BDA8092C0726458A /* SDImageAPNGCoder.m */,\n\t\t\t\tBB1D1192CEC6C26D481BAB47C75BCA56 /* SDImageAssetManager.h */,\n\t\t\t\t4D7D4D1C90894E8A533206E5679B1871 /* SDImageAssetManager.m */,\n\t\t\t\tDFF930E1A1EF9818E6781AA056A03AD3 /* SDImageAWebPCoder.h */,\n\t\t\t\tF59DA2817374C9606A05E0D57A6993AB /* SDImageAWebPCoder.m */,\n\t\t\t\tB66ADF3FBC020B8BAE5E1C0C6EA3C650 /* SDImageCache.h */,\n\t\t\t\t4DEBF0EE7331EEAD283D9D6370A2B3FF /* SDImageCache.m */,\n\t\t\t\tB83BA9762F2888371B5ADE95B066DCB4 /* SDImageCacheConfig.h */,\n\t\t\t\t7D8A688C63FDD5533A68B0CD80B0501E /* SDImageCacheConfig.m */,\n\t\t\t\t5852FC7ED30AAEEA07547AF6D71F3D85 /* SDImageCacheDefine.h */,\n\t\t\t\tFF3EF4B23861192F1BF203B7E288A145 /* SDImageCacheDefine.m */,\n\t\t\t\t1AA6F310E602B6F29B722C01961258A4 /* SDImageCachesManager.h */,\n\t\t\t\tBFEAB29224248CA276353656139D1668 /* SDImageCachesManager.m */,\n\t\t\t\t98368FFE6F3A2C1CB4B79C360D245377 /* SDImageCachesManagerOperation.h */,\n\t\t\t\t99AC313325A72709F61AD9B82245FC4F /* SDImageCachesManagerOperation.m */,\n\t\t\t\tE2A88BFB19C447C4ED3DE4168952FE80 /* SDImageCoder.h */,\n\t\t\t\t4D8AA9949B871C5C08476B12041D2D99 /* SDImageCoder.m */,\n\t\t\t\t7A10001AFFFB54BB477050134573A9C4 /* SDImageCoderHelper.h */,\n\t\t\t\t8E3D624D33EC772ADA4910D9A6A067AD /* SDImageCoderHelper.m */,\n\t\t\t\t2A1C27AE73C820EC4ACBF12FAEEA1D93 /* SDImageCodersManager.h */,\n\t\t\t\tC87340AB40E7872EBB32D3E37F151B98 /* SDImageCodersManager.m */,\n\t\t\t\tDD910C5803E3E0E5E17C5ED00AFEEEC0 /* SDImageFrame.h */,\n\t\t\t\tF2EC88E51FC34B63E85F84778E9C618A /* SDImageFrame.m */,\n\t\t\t\tFB7600C02A26CBAC1E67CFF0278A198D /* SDImageGIFCoder.h */,\n\t\t\t\tB6A08E238C0EA041AF882D5F75E6C3C9 /* SDImageGIFCoder.m */,\n\t\t\t\tB195FEEB2B6FD768A1270ABE2938AA39 /* SDImageGraphics.h */,\n\t\t\t\t8F2CD38DB179EE57D03D1E4AE0BBA047 /* SDImageGraphics.m */,\n\t\t\t\t4600B5D11E621BE294D5D7A8106BF312 /* SDImageHEICCoder.h */,\n\t\t\t\t483340B3D5102879F6C45F55BD02FF1E /* SDImageHEICCoder.m */,\n\t\t\t\tBB81C8F74DB13FEF4D842A7A4127FEBF /* SDImageIOAnimatedCoder.h */,\n\t\t\t\tA9A5B5BEF1CFAFF4AEB69AFD4C20968A /* SDImageIOAnimatedCoder.m */,\n\t\t\t\tA243783F2DB10CD105EA1B585E02DF32 /* SDImageIOAnimatedCoderInternal.h */,\n\t\t\t\t1416C43E8091C630E21516532F691796 /* SDImageIOCoder.h */,\n\t\t\t\t5DD11686FB044C460680737D6E66EC0C /* SDImageIOCoder.m */,\n\t\t\t\tF538296E4FA1BF861A19524F47E7A6D5 /* SDImageLoader.h */,\n\t\t\t\tB3522FD698E8EFD6BDE90D04D1ABC13D /* SDImageLoader.m */,\n\t\t\t\tF0A654F37AEA764934660E26E3BD2475 /* SDImageLoadersManager.h */,\n\t\t\t\t5304860EBF8FA61DE4A892566862746D /* SDImageLoadersManager.m */,\n\t\t\t\t0F824E440C097E5A5FE69CFBC7293F15 /* SDImageTransformer.h */,\n\t\t\t\t841780DAC592F44AB2E8D35D36E32285 /* SDImageTransformer.m */,\n\t\t\t\t804DFCC909792374DF921D69BE1F1C18 /* SDInternalMacros.h */,\n\t\t\t\tC48BA4C3D0C62019243E819DD277C007 /* SDInternalMacros.m */,\n\t\t\t\t0B722DB0B3C51C3645037E3399784B69 /* SDMemoryCache.h */,\n\t\t\t\tEC28ED48C1E6F76572193AD374027BB7 /* SDMemoryCache.m */,\n\t\t\t\t579C123C87D8545B91CD64649918A148 /* SDmetamacros.h */,\n\t\t\t\t415A874BEFEAB372A795B3F77C86139D /* SDWeakProxy.h */,\n\t\t\t\tCEB675D419ACF104AD5C8F2619C4FCF5 /* SDWeakProxy.m */,\n\t\t\t\t62E087DDBCC7CE3CA61BACD11EE3931E /* SDWebImage.h */,\n\t\t\t\t296AEDDAB76C6DA79B00DFB17FE94B13 /* SDWebImageCacheKeyFilter.h */,\n\t\t\t\tF9DD6F50E5F16B3EE2AFBBBA48053FA5 /* SDWebImageCacheKeyFilter.m */,\n\t\t\t\t57A489F83B821E73C9F898D59FD839D5 /* SDWebImageCacheSerializer.h */,\n\t\t\t\tEA1C659029357A11E03301278FD8D706 /* SDWebImageCacheSerializer.m */,\n\t\t\t\t83495546D2D6077CD99D793135E8A7EC /* SDWebImageCompat.h */,\n\t\t\t\tD6368995E44A12ED775E22745EE36796 /* SDWebImageCompat.m */,\n\t\t\t\t91D7D93CD15EE8BBB672073A9EE9172E /* SDWebImageDefine.h */,\n\t\t\t\t2F4695D22C004206B1EF601650EB58F1 /* SDWebImageDefine.m */,\n\t\t\t\t370CEA1E37CB5E0D01FDBFF39E1020BE /* SDWebImageDownloader.h */,\n\t\t\t\t18281399F797A6B19033D53D2B0992E3 /* SDWebImageDownloader.m */,\n\t\t\t\tF53274C0B6BDFB6F2402643CF71B2F77 /* SDWebImageDownloaderConfig.h */,\n\t\t\t\tACAACBFBB72CC5DBA48E5939C7C05CBB /* SDWebImageDownloaderConfig.m */,\n\t\t\t\t65F9EFAA484830CADC6FE4DE20867D8D /* SDWebImageDownloaderDecryptor.h */,\n\t\t\t\t68332238690458AE7A254B6097B8BD22 /* SDWebImageDownloaderDecryptor.m */,\n\t\t\t\t22CACEEBCAA12953A3BA4DB2820EB06A /* SDWebImageDownloaderOperation.h */,\n\t\t\t\t1925BCD73D2687C697D5448145F92862 /* SDWebImageDownloaderOperation.m */,\n\t\t\t\tD9304F4CFD273BA0BC3D8FD8EA8CE973 /* SDWebImageDownloaderRequestModifier.h */,\n\t\t\t\tD92B4CC4E2762BD017DDAA71533D1487 /* SDWebImageDownloaderRequestModifier.m */,\n\t\t\t\t233FC59CE7BD0ABCB6EFD98AF26F4228 /* SDWebImageDownloaderResponseModifier.h */,\n\t\t\t\t25BB086F66AE0B62674631094FA38DB9 /* SDWebImageDownloaderResponseModifier.m */,\n\t\t\t\tC41FA4729FC85108299943DF13BE21D7 /* SDWebImageError.h */,\n\t\t\t\t079B6435FC4625DBC4A439EDF7FD5844 /* SDWebImageError.m */,\n\t\t\t\t43363A5F804039F569FD9ABD9433F07B /* SDWebImageIndicator.h */,\n\t\t\t\tA4FB500E6FBEE5F4910B4E4F3894E917 /* SDWebImageIndicator.m */,\n\t\t\t\t8BD491CEBE34A4FF9B067D4431A9525D /* SDWebImageManager.h */,\n\t\t\t\t1AA24773B096CF90111EA4F2AA2C464D /* SDWebImageManager.m */,\n\t\t\t\t73F76A840EAA1BA85CD5CE2578134A93 /* SDWebImageOperation.h */,\n\t\t\t\tF848EBF5A77518F1437E59128B898ACE /* SDWebImageOperation.m */,\n\t\t\t\tFF32D6A22D56F5787F289A4BEA15E6A1 /* SDWebImageOptionsProcessor.h */,\n\t\t\t\t0BBCA689ED4AD568D1203A32DDCB2654 /* SDWebImageOptionsProcessor.m */,\n\t\t\t\tB12CEE2C03EFBD7EBAF1717349B42067 /* SDWebImagePrefetcher.h */,\n\t\t\t\t2E7185858699874B61C27769747820E1 /* SDWebImagePrefetcher.m */,\n\t\t\t\t7B4DFE57A7C5FC68155C295484A72007 /* SDWebImageTransition.h */,\n\t\t\t\t09F19A6EF0F8A7D0CDEEA09F1E90D4A1 /* SDWebImageTransition.m */,\n\t\t\t\t9487AD43770C35ED6D6CF71B197AE775 /* SDWebImageTransitionInternal.h */,\n\t\t\t\tD53EBA2326B86A037D7D89C9C9849AB1 /* UIButton+WebCache.h */,\n\t\t\t\tF3DF4F3E573CB800D27E86168DD5EECB /* UIButton+WebCache.m */,\n\t\t\t\t8D628BFBCC6276E5E277ED26143A0529 /* UIColor+SDHexString.h */,\n\t\t\t\t14DB6413E93A38460FE253FC259C28D5 /* UIColor+SDHexString.m */,\n\t\t\t\t3C388E0E2142C8BAB1FBE711F1A33688 /* UIImage+ExtendedCacheData.h */,\n\t\t\t\t26C98C55DA7C8E2B36CE7527095DED78 /* UIImage+ExtendedCacheData.m */,\n\t\t\t\t0FCDB01EEB669605F883EA4E79E56AD2 /* UIImage+ForceDecode.h */,\n\t\t\t\tA62E17FF50F14A446211D0E0BA00FD24 /* UIImage+ForceDecode.m */,\n\t\t\t\t3A023925AC3740397148C89A37EA72B8 /* UIImage+GIF.h */,\n\t\t\t\t2186649006C5A621B8BA7DDCC5C27AB4 /* UIImage+GIF.m */,\n\t\t\t\t44E9E3AB162F34A2457874535E2D437A /* UIImage+MemoryCacheCost.h */,\n\t\t\t\t35329B868A55A887B96B3891C90CE411 /* UIImage+MemoryCacheCost.m */,\n\t\t\t\t859F0A43E3649885E17F4D515A86A159 /* UIImage+Metadata.h */,\n\t\t\t\t9BC48CD5B43C672FF7213F9BE34110DB /* UIImage+Metadata.m */,\n\t\t\t\t8C1F9B1C56AC542B7695BF945F7E8A5A /* UIImage+MultiFormat.h */,\n\t\t\t\t50AF89B1AE50DF562243E31C949BD5B3 /* UIImage+MultiFormat.m */,\n\t\t\t\tCA1E5C47B1D161A6D7326A63F73039E1 /* UIImage+Transform.h */,\n\t\t\t\t27B6AEBABD0DD760910C2037F73CBBA7 /* UIImage+Transform.m */,\n\t\t\t\tDA01E7E21E39AD745F362344A6F1CA3D /* UIImageView+HighlightedWebCache.h */,\n\t\t\t\tA259FD968B2F3F103051FCCB13D1EF8F /* UIImageView+HighlightedWebCache.m */,\n\t\t\t\tD519F9451A80C810AEF071E0A50F225E /* UIImageView+WebCache.h */,\n\t\t\t\tFDCDC0DC5EBD4242B3B44E167355E955 /* UIImageView+WebCache.m */,\n\t\t\t\tC8CC6A0CB955A36A57FB8DC86DC7122B /* UIView+WebCache.h */,\n\t\t\t\t78E45C724EB1ABA21537759F2AA0CDBF /* UIView+WebCache.m */,\n\t\t\t\tE2A2FCE7B47213F9F0585EA70EA2024A /* UIView+WebCacheOperation.h */,\n\t\t\t\tEE2390C8AD53927134B524CBC997D50E /* UIView+WebCacheOperation.m */,\n\t\t\t);\n\t\t\tname = Core;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t71DD4FAB1BC8065512ABDD1F5001E5C8 /* GoogleDataTransport */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t47C2768639337908388E00A97B570D97 /* cct.nanopb.c */,\n\t\t\t\tAB33B7FB74C324A4584D1D93AF8B1DB5 /* cct.nanopb.h */,\n\t\t\t\t3B56D652DA90C728A3D4AA16170D7FA2 /* GDTCCTCompressionHelper.h */,\n\t\t\t\t219546DB6A6974432E1E0283F24A3329 /* GDTCCTCompressionHelper.m */,\n\t\t\t\tFE8190044D8F103421DED7166A530383 /* GDTCCTNanopbHelpers.h */,\n\t\t\t\t1CBEB10B215FDB65E86331667E87AE84 /* GDTCCTNanopbHelpers.m */,\n\t\t\t\t018833202B971E61CF36DA9775AED769 /* GDTCCTUploader.h */,\n\t\t\t\tDEEA9E90B955F3FF75BD5CC9F8F49886 /* GDTCCTUploader.m */,\n\t\t\t\t08F469B9832F15DBDE81EB155A43226B /* GDTCCTUploadOperation.h */,\n\t\t\t\t11DC645818CEA0B49FB41D10974587E3 /* GDTCCTUploadOperation.m */,\n\t\t\t\t813CEE72D58D250DD2A09A4157C51303 /* GDTCORAssert.h */,\n\t\t\t\t363CE7A6599529EED98580D11773BD01 /* GDTCORAssert.m */,\n\t\t\t\tBCEE4E5F9E2A1F4352E21C55CC500B15 /* GDTCORClock.h */,\n\t\t\t\t8F6FA7F2B642E68ECD25BCCB0DDAAA75 /* GDTCORClock.m */,\n\t\t\t\t22B6E2A2A128A5A1F1B6F8D6C0EF4BBE /* GDTCORConsoleLogger.h */,\n\t\t\t\t93498C80BEE42599CD4B49D1DCDE8DAA /* GDTCORConsoleLogger.m */,\n\t\t\t\t66E791BF8C770CDCE827420B1959B849 /* GDTCORDirectorySizeTracker.h */,\n\t\t\t\t606B14BF9E8B55AA634896F3FE6C2102 /* GDTCORDirectorySizeTracker.m */,\n\t\t\t\t3AE71CC3E7412E1F33D2D46AB258531C /* GDTCOREndpoints.h */,\n\t\t\t\t9D1FFD95B9DC7DB4011FC5445F7059CE /* GDTCOREndpoints.m */,\n\t\t\t\tEF8FCF0158C3FC321B0CCC8F87E286F6 /* GDTCOREndpoints_Private.h */,\n\t\t\t\tBBB794E91F141A51A62086A95A79B3B0 /* GDTCOREvent.h */,\n\t\t\t\t74B387BF4963DADE929360BC4D95BF9F /* GDTCOREvent.m */,\n\t\t\t\t7EF33965A3795DEE7A531EC8C56300B4 /* GDTCOREvent+GDTCCTSupport.h */,\n\t\t\t\t135A77B30A220981214A503DF9FB9D3A /* GDTCOREvent+GDTCCTSupport.m */,\n\t\t\t\tCEB2E6515F73C730A4DE300BCA32CE76 /* GDTCOREvent_Private.h */,\n\t\t\t\t3C31DC7C6755337262C1BDDB6677C635 /* GDTCOREventDataObject.h */,\n\t\t\t\tEC2AA38D1492EE015AE393D7FCDBCDF1 /* GDTCOREventTransformer.h */,\n\t\t\t\t7B1EB303FD52ADD9ABA791AD8C33496F /* GDTCORFlatFileStorage.h */,\n\t\t\t\t736D3261A8A25DCBBECD54A6C5C48166 /* GDTCORFlatFileStorage.m */,\n\t\t\t\tE9E0C507183FA6B14B3FED0BB9BFE8E5 /* GDTCORFlatFileStorage+Promises.h */,\n\t\t\t\t79AB37844F04B4F0CF83A66B9FBD9175 /* GDTCORFlatFileStorage+Promises.m */,\n\t\t\t\t4CD317B6F97D4204C18D7618DBB86C03 /* GDTCORLifecycle.h */,\n\t\t\t\t0E80D119146AEB6CE705A642B0A4012D /* GDTCORLifecycle.m */,\n\t\t\t\tDC55F3B02A125C1D8CBC59176095F043 /* GDTCORPlatform.h */,\n\t\t\t\t809CE53E4184869CD1D4910C0A359884 /* GDTCORPlatform.m */,\n\t\t\t\t87BD1262A5EDC0CE9D84214096454004 /* GDTCORReachability.h */,\n\t\t\t\t5352D3BC21FF5229DD4FC39829C48E7C /* GDTCORReachability.m */,\n\t\t\t\tC1150A7649D44398A5F001918CBE0C16 /* GDTCORReachability_Private.h */,\n\t\t\t\t5FD16FE46197F77B6D4E28CDE644CC73 /* GDTCORRegistrar.h */,\n\t\t\t\t9DB1409CD0C3B140ECAB6006D2DAD8BC /* GDTCORRegistrar.m */,\n\t\t\t\t0338A87088B87F5A5D1BB03CA2AB274B /* GDTCORRegistrar_Private.h */,\n\t\t\t\tFFBEACDBC00E47FDCE130333C01BDD52 /* GDTCORStorageEventSelector.h */,\n\t\t\t\t5BE80A247D8376A910A19BFB10B99430 /* GDTCORStorageEventSelector.m */,\n\t\t\t\t7F3BFEC70D8BA82BE6E262B3750543AC /* GDTCORStorageProtocol.h */,\n\t\t\t\tF589BA173CD44451894C642200BAD5A9 /* GDTCORTargets.h */,\n\t\t\t\tB06B80A4EE003DEDFC1F89E8907C6C16 /* GDTCORTransformer.h */,\n\t\t\t\tBCBC03DFAC32230F28CDE2D8E913A269 /* GDTCORTransformer.m */,\n\t\t\t\t0ADF13875C4D61EE62B5265D074DB171 /* GDTCORTransformer_Private.h */,\n\t\t\t\tFFC85887576AED4EB7D6127CC1FDC955 /* GDTCORTransport.h */,\n\t\t\t\t193B43A46E5628F605735E9C2EB9C5B1 /* GDTCORTransport.m */,\n\t\t\t\t67A976AAF1EAC9BADF423E17C96B88FE /* GDTCORTransport_Private.h */,\n\t\t\t\tEC47234C0173B2827334091E5C04C152 /* GDTCORUploadBatch.h */,\n\t\t\t\t6AFBDA1EBD167AFD2083DC8D9D565001 /* GDTCORUploadBatch.m */,\n\t\t\t\tF6FF94050EDDF80FD2501F4E30F18E4D /* GDTCORUploadCoordinator.h */,\n\t\t\t\t6AB43C522E93B03C169E99C63451C091 /* GDTCORUploadCoordinator.m */,\n\t\t\t\t2FC875B27ACA63CA271CA0D921CF94C3 /* GDTCORUploader.h */,\n\t\t\t\t28859EE1F335E36BD76813D7AC4608D9 /* GoogleDataTransport.h */,\n\t\t\t\t5D0B7910C5928FF0F06049E99FAACD41 /* Support Files */,\n\t\t\t);\n\t\t\tname = GoogleDataTransport;\n\t\t\tpath = GoogleDataTransport;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7486EB8C246AC69530D40BBBFC09B321 /* Reachability */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tFC22CB2FD3FE9BC3D607B5CA39155B83 /* GULReachabilityChecker.h */,\n\t\t\t\tEF82E76BE97070A77C122D8CD5A2A852 /* GULReachabilityChecker.m */,\n\t\t\t\t1A6FE3762E8CAD647386716CD1698F48 /* GULReachabilityChecker+Internal.h */,\n\t\t\t\tFEE20DA431EFAB6E9DE3F14B005CCF75 /* GULReachabilityMessageCode.h */,\n\t\t\t);\n\t\t\tname = Reachability;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8275CCB4E8732497B1021FCBC240F3C2 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8955292BD5F544B74B743CA93E987E41 /* iOS */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t82ABAFE15F86B5F2F88A2DAA6D6FF5C9 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tFA50FFBEC226EAB798930460C18C4350 /* SDWebImage.modulemap */,\n\t\t\t\tCE6BFCD79351B8CDEDCAB2DE6EDB89AE /* SDWebImage-dummy.m */,\n\t\t\t\t91EF3E33FDEAEF5BB90A91327C8718B6 /* SDWebImage-Info.plist */,\n\t\t\t\tE6921E05E12367D79F30526D90D84BE6 /* SDWebImage-prefix.pch */,\n\t\t\t\tA6344AC78A87A0720BE33CE02655D669 /* SDWebImage-umbrella.h */,\n\t\t\t\t32073165CB0BA8A73E608799A7994586 /* SDWebImage.debug.xcconfig */,\n\t\t\t\tFC6A0016A0D695FE4F0D2BCB7B58E53B /* SDWebImage.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/SDWebImage\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t85E90CB4A586E4CFFEF67024B592C673 /* GoogleUtilities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0C6CEC6D687B3736917288BC43D2B350 /* AppDelegateSwizzler */,\n\t\t\t\tBE0E4A57483DCC04AFA0CDB035E033DF /* Environment */,\n\t\t\t\t6E122AC728989052F6E7D19E4F6218E6 /* Logger */,\n\t\t\t\t3DA5ECD28DB682EEB7CE60E41A95AC39 /* MethodSwizzler */,\n\t\t\t\tA176A63F3EF04F64107A20A0172D49D1 /* Network */,\n\t\t\t\t5633E1A74655186D803F0C91BD6B16C0 /* NSData+zlib */,\n\t\t\t\t7486EB8C246AC69530D40BBBFC09B321 /* Reachability */,\n\t\t\t\t9C746AB702E7728A50B880BFE02EE1F0 /* Support Files */,\n\t\t\t\t5544FD9AFB77FFE3A00CB2505C4726A3 /* UserDefaults */,\n\t\t\t);\n\t\t\tname = GoogleUtilities;\n\t\t\tpath = GoogleUtilities;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t892DA6ED03D417C2A024B29B7963B0C8 /* PromisesObjC */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF35AA80907A78AC92F34C61F368248E7 /* FBLPromise.h */,\n\t\t\t\tB21C4B6B899118FE97F08797C6CC6D78 /* FBLPromise.m */,\n\t\t\t\t4D82EC7D361BCA9009FD349978107D1C /* FBLPromise+All.h */,\n\t\t\t\t9D110B53C055335FB5D62021AD131E9F /* FBLPromise+All.m */,\n\t\t\t\tFB9896C32514099F18D7AA422602FB04 /* FBLPromise+Always.h */,\n\t\t\t\t0DFCC2FB818BA3289E85B84DD2F068A3 /* FBLPromise+Always.m */,\n\t\t\t\t70FBB40CF13B29C7EC31294E2767F546 /* FBLPromise+Any.h */,\n\t\t\t\tA1B2BE9FCAE442C062B1070B5F83D9D9 /* FBLPromise+Any.m */,\n\t\t\t\t7FDFC5FEAC4A550A50CD516405F6DFF2 /* FBLPromise+Async.h */,\n\t\t\t\t068EFE7F14EBD412EB944B5B38CE3CB3 /* FBLPromise+Async.m */,\n\t\t\t\t1F96A93009C7CAECE802F2AF89962662 /* FBLPromise+Await.h */,\n\t\t\t\tEC847DD51A92AE89F533B4312E344982 /* FBLPromise+Await.m */,\n\t\t\t\t1BC2750E276CE3D6725F398532CEB28B /* FBLPromise+Catch.h */,\n\t\t\t\t490C3A82D71E20AB4B5BC07D75101D21 /* FBLPromise+Catch.m */,\n\t\t\t\tB8633B4212F9E21E512835226D2BEC2E /* FBLPromise+Delay.h */,\n\t\t\t\t239EF7C666D42E75FB20E65D3491B74A /* FBLPromise+Delay.m */,\n\t\t\t\tECF677E408094637A67960F364C6FA0D /* FBLPromise+Do.h */,\n\t\t\t\tA6888DFA1022D0AF9FB4109175558CEC /* FBLPromise+Do.m */,\n\t\t\t\t447B191325C26D8C11C3D317EC3FBAA8 /* FBLPromise+Race.h */,\n\t\t\t\tEFD6BF26B215DD780EA6145DFEEC525A /* FBLPromise+Race.m */,\n\t\t\t\t6806286AE468436D210DE24F56FFD7A2 /* FBLPromise+Recover.h */,\n\t\t\t\tBE65A7532D1E92D1171FAB3E3DBF0EC2 /* FBLPromise+Recover.m */,\n\t\t\t\tF1A5B63B766812910C3FC66A4D5BD359 /* FBLPromise+Reduce.h */,\n\t\t\t\tFF60EBD5E154FA9A791F0C421B4D9AEE /* FBLPromise+Reduce.m */,\n\t\t\t\tC869A091C5104F60176DCBAC53E9FCD6 /* FBLPromise+Retry.h */,\n\t\t\t\tB0893F86784B88FBEBDDAD469BA72394 /* FBLPromise+Retry.m */,\n\t\t\t\tF0647D92B0FBA5FC4BF6371012FEE181 /* FBLPromise+Testing.h */,\n\t\t\t\t00F035755BD3D0F891EF8F32718F2E74 /* FBLPromise+Testing.m */,\n\t\t\t\t8D85590DB78FA3CE98F5876D319CDC9F /* FBLPromise+Then.h */,\n\t\t\t\t18637DFB49F868B5320F06FCD27ABD99 /* FBLPromise+Then.m */,\n\t\t\t\t2A93FB313CA659376FAA369092F2D036 /* FBLPromise+Timeout.h */,\n\t\t\t\t5A8A40185ABE648F7A15E613D0C0559F /* FBLPromise+Timeout.m */,\n\t\t\t\t2CD99347EC1D85D2C2FDDB3D1F9DF393 /* FBLPromise+Validate.h */,\n\t\t\t\t281F885809D3382CEFAC6F78D5E16CA0 /* FBLPromise+Validate.m */,\n\t\t\t\t47F2FC011CE490B793305158ACB2048E /* FBLPromise+Wrap.h */,\n\t\t\t\t5BEA3009F10DE79DB402A683F6839FC8 /* FBLPromise+Wrap.m */,\n\t\t\t\tE76B8095179CC1855E5CFA2FF2597A24 /* FBLPromiseError.h */,\n\t\t\t\tFCA00A91EC23FFE0892B9D0F0B84F617 /* FBLPromiseError.m */,\n\t\t\t\t278F2C97E692BBEB7227CFD22EE4333A /* FBLPromisePrivate.h */,\n\t\t\t\t7283DD0E961B31F830AEB840A7B59650 /* FBLPromises.h */,\n\t\t\t\t1AFCC02FC929E5DD450B688E200653B7 /* Support Files */,\n\t\t\t);\n\t\t\tname = PromisesObjC;\n\t\t\tpath = PromisesObjC;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8955292BD5F544B74B743CA93E987E41 /* iOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t90E823CCF25045F00FF4E98E871586A6 /* CFNetwork.framework */,\n\t\t\t\t28A55FC857FA4F7D9FE98F3B5AA514E8 /* CoreTelephony.framework */,\n\t\t\t\tE21B3C078686406E2ECFD3BC65D566D7 /* Foundation.framework */,\n\t\t\t\tC78361E6DA67CDEC2A04C25F1B40D31F /* ImageIO.framework */,\n\t\t\t\t5F030A051DB2F7C17CB74A9C0FBD7B56 /* Security.framework */,\n\t\t\t\t7BBDEBAD931B605980FE3DCE9FA337AE /* SystemConfiguration.framework */,\n\t\t\t\t7887F0BAB621B4623BFE017BC5FA339D /* UIKit.framework */,\n\t\t\t);\n\t\t\tname = iOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8F79F2409CDA67E13113AA0DCFE8B8D7 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t20481C9B0D8652965A8D3CA6CF4FB6DF /* Appirater.modulemap */,\n\t\t\t\tCD9056754A12ED3E38D68945FE70B586 /* Appirater-dummy.m */,\n\t\t\t\t50A0F26807A7475A7CAB02BAC26EA368 /* Appirater-Info.plist */,\n\t\t\t\tC0FF8273009BBF51F9894931F3B54A5E /* Appirater-prefix.pch */,\n\t\t\t\tD2771347E37390095BF7D36EB989050F /* Appirater-umbrella.h */,\n\t\t\t\tB74D76E7DA492E2DD4E2C7CE3A5874F9 /* Appirater.debug.xcconfig */,\n\t\t\t\tCE9EF082FAA32B5B2D0B0C7CC14C11E6 /* Appirater.release.xcconfig */,\n\t\t\t\t8A7AE3C5E6E2073C8FAC46FF8333849F /* ResourceBundle-Appirater-Appirater-Info.plist */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/Appirater\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t98ABACC26B4DE659B90DF14F58AC6F5A /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEE0CECAF5DA5AAE13E1615E7B14147CB /* ar.lproj */,\n\t\t\t\t4E579AE58A2F6343FA943DA78FDA6A24 /* ca.lproj */,\n\t\t\t\tD52688E7BC72717ABC1A8FD85DD32AE4 /* cs.lproj */,\n\t\t\t\tF4A7F01DAC8F3E158C6CB70DD5E60C24 /* da.lproj */,\n\t\t\t\t8CDC01574AEDC72431059BB3FDE16F59 /* de.lproj */,\n\t\t\t\t99C91ADC1F402BD8ABEE63EAB8134747 /* el.lproj */,\n\t\t\t\t8C7297F9F351E0DFB107547CC454F81B /* en.lproj */,\n\t\t\t\tEF7A55F92FBA10C1CA52F98BF5B091C9 /* es.lproj */,\n\t\t\t\tA86DA94DC9AB6D6E95B73BF4F59C3EF1 /* fa.lproj */,\n\t\t\t\tAF5AFDC2F2B6C3E31AFC75FE3430CA49 /* fi.lproj */,\n\t\t\t\tE80E4257A841B7AA5C92B2CB19B16F0B /* fr.lproj */,\n\t\t\t\tD005D4ECC0D56EB73527C065B49D192C /* he.lproj */,\n\t\t\t\t90548723A968948DA9E270815D5DFEA2 /* hu.lproj */,\n\t\t\t\t9FB349B1B1D5B036FA774AC001CEBCB4 /* hy.lproj */,\n\t\t\t\t4AC80933AD4E17DC2DDD4A5156E1FADB /* id.lproj */,\n\t\t\t\t4958CF39D5BE0CE693F9BABAB470D5A1 /* it.lproj */,\n\t\t\t\tD2D3BD16668BB31898CA2909AB1211CB /* ja.lproj */,\n\t\t\t\t98A2C33C3CFB15DFB0AD91D948975967 /* ko.lproj */,\n\t\t\t\t867CE4FF42F759E76A71FEF4453E8079 /* ms.lproj */,\n\t\t\t\t4F72FBD1344FC32D12AA727F983904D6 /* nb.lproj */,\n\t\t\t\t700956653190B059B98E6D0401813D2F /* nl.lproj */,\n\t\t\t\t0A31AE9C96B6817F39D60A3B4CB0E787 /* pl.lproj */,\n\t\t\t\tFC3C259DB11E51E08F2D5630A5145839 /* pt.lproj */,\n\t\t\t\tC3AECB4945D348C50164B9454BA98CB3 /* pt-BR.lproj */,\n\t\t\t\tD053D0A9CE99EC16E5ED88D7BA8C3A65 /* ro.lproj */,\n\t\t\t\t3446029F86E0312850EAC5C98A32C65C /* ru.lproj */,\n\t\t\t\t573447DBCFF573125A97AC8FE08CF8FB /* sk.lproj */,\n\t\t\t\t030D92BA7629B33D7DEDDD755B2FB34B /* sv.lproj */,\n\t\t\t\t8A0DEDA4144F466B62361967B86ACC25 /* th.lproj */,\n\t\t\t\t45A1925DBA110CDCB56C30C2AEC79D96 /* tr.lproj */,\n\t\t\t\tFEE086E4BCB7B965DFED58170011ADD2 /* uk.lproj */,\n\t\t\t\tC6911F1DC733532D91E29D6B0433A787 /* vi.lproj */,\n\t\t\t\t255E93987C91799073F418C741D2F912 /* zh-Hans.lproj */,\n\t\t\t\t8C5EE75C53160A323F9D43000C9258C2 /* zh-Hant.lproj */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9C746AB702E7728A50B880BFE02EE1F0 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t94342AAF24F20C2012C9E17B8D8076FA /* GoogleUtilities.modulemap */,\n\t\t\t\t71783D9D8F34A0AB09F92BAF64FC155E /* GoogleUtilities-dummy.m */,\n\t\t\t\tA6178B53BBB7ED0452CEE088B25AA064 /* GoogleUtilities-Info.plist */,\n\t\t\t\t1F54F5C198006F0294B0657489850E48 /* GoogleUtilities-umbrella.h */,\n\t\t\t\tD934FF1B0DBCF555CAF470E0CF5AA900 /* GoogleUtilities.debug.xcconfig */,\n\t\t\t\t4D06A1E8D589DEE651EA569B253B9DA6 /* GoogleUtilities.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/GoogleUtilities\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9E278DC92C4390DDC86926F315CF7F51 /* FirebaseAnalytics */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF6AE86F671E4F982DD5BB48EAAB525A9 /* AdIdSupport */,\n\t\t\t\t4DEE105FF0FD390E62D91CCF24486B2A /* Support Files */,\n\t\t\t);\n\t\t\tname = FirebaseAnalytics;\n\t\t\tpath = FirebaseAnalytics;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA176A63F3EF04F64107A20A0172D49D1 /* Network */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t73009AD0D7FBF3D5781BD8B87D5E1D98 /* GULMutableDictionary.h */,\n\t\t\t\tBD3097914838C55DE30D9D377048A664 /* GULMutableDictionary.m */,\n\t\t\t\tA8B52265053B7A072C3CFD52774A4E64 /* GULNetwork.h */,\n\t\t\t\t0502AAFCB22CA8A06A21C20517BE89B4 /* GULNetwork.m */,\n\t\t\t\t6C8ECB26C6DABE3DBF37DBC44D5A8C5C /* GULNetworkConstants.h */,\n\t\t\t\tBA44BA3AD4121BF4B3BA03128355DA0A /* GULNetworkConstants.m */,\n\t\t\t\t18D28D4E30FB28D835221C737B53B7E0 /* GULNetworkInternal.h */,\n\t\t\t\tDC79300A6D291A17A3804A3511C41D9B /* GULNetworkLoggerProtocol.h */,\n\t\t\t\t54836C20C54693641AA8386E05C05C5C /* GULNetworkMessageCode.h */,\n\t\t\t\tEF3303042C21F9396439AB3DE71C7BB2 /* GULNetworkURLSession.h */,\n\t\t\t\t142559AF1A21A92BBB53100F317735FE /* GULNetworkURLSession.m */,\n\t\t\t);\n\t\t\tname = Network;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA21029CE5CC909068E9BC378006F9D29 /* decode */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = decode;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA756C5B446990E8A8C4B65394FCF4FEF /* GoogleAppMeasurement */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t278C4253D3F115DE5037DF8D472B252D /* AdIdSupport */,\n\t\t\t\tD522B9F055E8193E1EB8C99ACB45C3A0 /* Support Files */,\n\t\t\t);\n\t\t\tname = GoogleAppMeasurement;\n\t\t\tpath = GoogleAppMeasurement;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tAC1136BE3B047EDE3C63B82F0FADFAAC /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD43779F7D174B41F97107A9631DFA91A /* GoogleAppMeasurement.xcframework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB238E6220B3EC0E0373BE9408386D8A6 /* encode */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = encode;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB62CFD72F1B5C3EDED2D6436396B062F /* Appirater */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t350451991B16222891CB7702FAA4C26A /* Appirater.h */,\n\t\t\t\t0466C52ED49E6E1C863BAFB6E1AE5B92 /* Appirater.m */,\n\t\t\t\t4687296E13EF95A9B5206235744E21EC /* AppiraterDelegate.h */,\n\t\t\t\t98ABACC26B4DE659B90DF14F58AC6F5A /* Resources */,\n\t\t\t\t8F79F2409CDA67E13113AA0DCFE8B8D7 /* Support Files */,\n\t\t\t);\n\t\t\tname = Appirater;\n\t\t\tpath = Appirater;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB7C5491CCF4E11B34D2C388422157234 /* Pods-Spotify */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2565C009A42B8D093CEB285EE59D4EE0 /* Pods-Spotify.modulemap */,\n\t\t\t\t561783788BEFAECA7A813F1442497E1D /* Pods-Spotify-acknowledgements.markdown */,\n\t\t\t\t43864D2A6701CB0D5A279382ABEF4FD9 /* Pods-Spotify-acknowledgements.plist */,\n\t\t\t\tA27A53F9FCBFE297E53C77376ACB64D1 /* Pods-Spotify-dummy.m */,\n\t\t\t\t4AABAA72A7A163BFFFA781CE2598D89B /* Pods-Spotify-frameworks.sh */,\n\t\t\t\tE30EDBDA563FB09CF5AE6965F2558FE9 /* Pods-Spotify-Info.plist */,\n\t\t\t\tF124022073EADCF94FCBED857E5EABBB /* Pods-Spotify-umbrella.h */,\n\t\t\t\t02EBCB4694F493398B30D145521759BB /* Pods-Spotify.debug.xcconfig */,\n\t\t\t\t20DAC9944D4D96AD4E142D77D43D9F68 /* Pods-Spotify.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Pods-Spotify\";\n\t\t\tpath = \"Target Support Files/Pods-Spotify\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tBA6859418815F5231E3CEAAA21D0F012 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t036C70BC91046AD6992330F90128AC83 /* FirebaseInstallations.modulemap */,\n\t\t\t\tEDF07392617868FE264D5E58788D279F /* FirebaseInstallations-dummy.m */,\n\t\t\t\t94FAEBC41B0BE3E27929CC570CB58423 /* FirebaseInstallations-Info.plist */,\n\t\t\t\t54D381D3559D8677EA0632FDB5EEA05A /* FirebaseInstallations-umbrella.h */,\n\t\t\t\t4E43BB424620088D2FC848F87869992C /* FirebaseInstallations.debug.xcconfig */,\n\t\t\t\t8B4E22AE507DF453D28673AD92339EB1 /* FirebaseInstallations.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/FirebaseInstallations\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tBE0E4A57483DCC04AFA0CDB035E033DF /* Environment */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0B538C0DED9A96F51790585E9AF03D97 /* GULAppEnvironmentUtil.h */,\n\t\t\t\tD2DC9C0FCEB534D5193B9600BF0552FC /* GULAppEnvironmentUtil.m */,\n\t\t\t\t447875125DF9F0D89F9C6EF9340E1570 /* GULHeartbeatDateStorable.h */,\n\t\t\t\t05850FDD1539ACB6AB1C9DB0142B8403 /* GULHeartbeatDateStorage.h */,\n\t\t\t\tF36DCFF7B72CE2940864E1364072151A /* GULHeartbeatDateStorage.m */,\n\t\t\t\tBB06018D1785388A5C83E9EF4D57ED16 /* GULHeartbeatDateStorageUserDefaults.h */,\n\t\t\t\t4F86D0619F7550A5DBDF634B8413E25F /* GULHeartbeatDateStorageUserDefaults.m */,\n\t\t\t\tA40C76162676EC9A3E0C33C1F29CB93F /* GULKeychainStorage.h */,\n\t\t\t\tB8AE32764C24267738A026CE787CE667 /* GULKeychainStorage.m */,\n\t\t\t\t9A75B93924C163BDD4BFE27BE82320E0 /* GULKeychainUtils.h */,\n\t\t\t\tF80FBEC0B534E33030C9ECCABDD9BE62 /* GULKeychainUtils.m */,\n\t\t\t\t476A318EB831BFCD3B77190E73149735 /* GULSecureCoding.h */,\n\t\t\t\tAB007F418E0ED0E20061B9ED7D831C76 /* GULSecureCoding.m */,\n\t\t\t\t3F2853ABAFCEFBF960A5040D649074EC /* GULURLSessionDataResponse.h */,\n\t\t\t\t40CE0245F2D926AF50D3BFBA488887C1 /* GULURLSessionDataResponse.m */,\n\t\t\t\t2494BB0409778ADBC0785D40DE703573 /* NSURLSession+GULPromises.h */,\n\t\t\t\t61C15E699851C928BE91C72A5169AEB2 /* NSURLSession+GULPromises.m */,\n\t\t\t);\n\t\t\tname = Environment;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCF1408CF629C7361332E53B88F7BD30C = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,\n\t\t\t\t8275CCB4E8732497B1021FCBC240F3C2 /* Frameworks */,\n\t\t\t\tD97DF81019DCDCF585FD2F0B010BD2B2 /* Pods */,\n\t\t\t\t1FC49855849F77DD042774C08FB9A2BD /* Products */,\n\t\t\t\t16EF75AC256F0C94C6273A51CFE74355 /* Targets Support Files */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD522B9F055E8193E1EB8C99ACB45C3A0 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t161553D9C89B2C716D3056754C86B4A5 /* GoogleAppMeasurement-xcframeworks.sh */,\n\t\t\t\t695ADBFC9C4D04D17897085D1ABBBAA7 /* GoogleAppMeasurement.debug.xcconfig */,\n\t\t\t\t27EFCAB3E6A3DE572444045971D498C5 /* GoogleAppMeasurement.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/GoogleAppMeasurement\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD97DF81019DCDCF585FD2F0B010BD2B2 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB62CFD72F1B5C3EDED2D6436396B062F /* Appirater */,\n\t\t\t\t2152BB9B7EF0C69F7B86DE1EF926D67F /* Firebase */,\n\t\t\t\t9E278DC92C4390DDC86926F315CF7F51 /* FirebaseAnalytics */,\n\t\t\t\t1AE034B84201B1046BCCE51577E15354 /* FirebaseCore */,\n\t\t\t\tE46377C0E529F23020C710F7BB8AA1AA /* FirebaseCoreDiagnostics */,\n\t\t\t\t62A2F567C67C028B3713BC180E3A5B8C /* FirebaseInstallations */,\n\t\t\t\tA756C5B446990E8A8C4B65394FCF4FEF /* GoogleAppMeasurement */,\n\t\t\t\t71DD4FAB1BC8065512ABDD1F5001E5C8 /* GoogleDataTransport */,\n\t\t\t\t85E90CB4A586E4CFFEF67024B592C673 /* GoogleUtilities */,\n\t\t\t\tE2D425967250F754DBAE550A79EDDA23 /* nanopb */,\n\t\t\t\t892DA6ED03D417C2A024B29B7963B0C8 /* PromisesObjC */,\n\t\t\t\t3082F193C8D1BA24D51A7BC01CEBD841 /* SDWebImage */,\n\t\t\t);\n\t\t\tname = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE2D425967250F754DBAE550A79EDDA23 /* nanopb */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t15C9B0DD52D5C611E1AB4BB7A9A92DF5 /* pb.h */,\n\t\t\t\t983C23FA76E7A245275E7A252B67A2A0 /* pb_common.c */,\n\t\t\t\t06D5568DC434FEF3EF84595EE271B95A /* pb_common.h */,\n\t\t\t\tD8BE8FDFF77007F5278B6A0E5BC01E6A /* pb_decode.c */,\n\t\t\t\t7F0F742A22FC71CED5A18A108E514A8B /* pb_decode.h */,\n\t\t\t\t90D9BC28AA40B8F7AAC5DBAFFFA2503A /* pb_encode.c */,\n\t\t\t\tFDF404E683FC3DE61DCE91FF8B1E0842 /* pb_encode.h */,\n\t\t\t\tA21029CE5CC909068E9BC378006F9D29 /* decode */,\n\t\t\t\tB238E6220B3EC0E0373BE9408386D8A6 /* encode */,\n\t\t\t\t48EA86F33969C2420662B0A62E5A9FCE /* Support Files */,\n\t\t\t);\n\t\t\tname = nanopb;\n\t\t\tpath = nanopb;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE46377C0E529F23020C710F7BB8AA1AA /* FirebaseCoreDiagnostics */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA2CD1B738ABAB7BA344D7969860B494C /* FIRCoreDiagnostics.h */,\n\t\t\t\t45D88DFE4BAAB878102C9DB69C90E1EE /* FIRCoreDiagnostics.m */,\n\t\t\t\tAAC1202619BDEC6CB408DEFB276233E1 /* FIRCoreDiagnosticsData.h */,\n\t\t\t\t5805E31EC45A505EEE3457FA2B9FA351 /* FIRCoreDiagnosticsInterop.h */,\n\t\t\t\t495F9A8ED0CBC83C181879060E49F21E /* firebasecore.nanopb.c */,\n\t\t\t\t1A58961C9BBD35E7B60ECDB62E56F7DC /* firebasecore.nanopb.h */,\n\t\t\t\t6EF332B85D74AC3B2E0615B4F1FB4DC5 /* Support Files */,\n\t\t\t);\n\t\t\tname = FirebaseCoreDiagnostics;\n\t\t\tpath = FirebaseCoreDiagnostics;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF5B961421EC2787E78401B772CC91D5 /* Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAA8BA4718A81C87F777362D613444D44 /* Firebase.debug.xcconfig */,\n\t\t\t\tF582A3CDAC1DDA3FCEA8CB2C13293A4D /* Firebase.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Support Files\";\n\t\t\tpath = \"../Target Support Files/Firebase\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF6AE86F671E4F982DD5BB48EAAB525A9 /* AdIdSupport */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t058C19C88B10171A17924987A122D927 /* Frameworks */,\n\t\t\t);\n\t\t\tname = AdIdSupport;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t104737A7F2F8176AF07A40A019B4DC37 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6C93ABDF963DDA7C78AADD9F22CD5CB1 /* NSBezierPath+SDRoundedCorners.h in Headers */,\n\t\t\t\t7E6862A73246BB1A0E7BCEBAF50FFBE1 /* NSButton+WebCache.h in Headers */,\n\t\t\t\tBD074722CD72470954ADB5B1198E01C5 /* NSData+ImageContentType.h in Headers */,\n\t\t\t\tE8CE28499C17965A931605D4F47AAEBF /* NSImage+Compatibility.h in Headers */,\n\t\t\t\t38CF7D5EE6C28780FE3F9C1E63CFF3D4 /* SDAnimatedImage.h in Headers */,\n\t\t\t\t57E1C476BA5F8DD1ED740FE8DBC05D8A /* SDAnimatedImagePlayer.h in Headers */,\n\t\t\t\t4FB353F2B2E7D7AE0811D7C538DA2B36 /* SDAnimatedImageRep.h in Headers */,\n\t\t\t\tF463DEB020D5C466D4613947AE4BE16F /* SDAnimatedImageView.h in Headers */,\n\t\t\t\t42822E48A1441AD8E0011D37C1625B36 /* SDAnimatedImageView+WebCache.h in Headers */,\n\t\t\t\t84B624227D73D3746CEFD48E49D74635 /* SDAssociatedObject.h in Headers */,\n\t\t\t\t18303B692A81A7D708973A6B9CBA75D8 /* SDAsyncBlockOperation.h in Headers */,\n\t\t\t\tF161112B04B9AC7D276D9F588BA6E313 /* SDDeviceHelper.h in Headers */,\n\t\t\t\tFE0189D2FE038AD82C4CCF5A801A50A3 /* SDDiskCache.h in Headers */,\n\t\t\t\tA24B4B60656BA387B9979BD877A23983 /* SDDisplayLink.h in Headers */,\n\t\t\t\tF077E74D9855D0D7FCF570F8E8ED4A1E /* SDFileAttributeHelper.h in Headers */,\n\t\t\t\tA2CE92DE43AB450DE1AAA129BFBADCBE /* SDGraphicsImageRenderer.h in Headers */,\n\t\t\t\t809A09224ABB6A00BEF6B72EFAB30B4E /* SDImageAPNGCoder.h in Headers */,\n\t\t\t\t336BA7F271A33087B951BA4C6C6B2C6F /* SDImageAssetManager.h in Headers */,\n\t\t\t\t33C0E2EFD1C8046A2020D25FD1F1611F /* SDImageAWebPCoder.h in Headers */,\n\t\t\t\t0F4322740A001E3D7BFD2C333BCF907D /* SDImageCache.h in Headers */,\n\t\t\t\tE7FA1E1CD066D0335A95376C73E3F8ED /* SDImageCacheConfig.h in Headers */,\n\t\t\t\t5BBE7719912593F1DEFF8E763EAD4ED6 /* SDImageCacheDefine.h in Headers */,\n\t\t\t\t909CBA577868D6E976AC82340B50343E /* SDImageCachesManager.h in Headers */,\n\t\t\t\tE8D519B63C2077979F799769F9A35072 /* SDImageCachesManagerOperation.h in Headers */,\n\t\t\t\t0FFA0C960F26666918569059FB8E92BC /* SDImageCoder.h in Headers */,\n\t\t\t\t519B33DCAE0FB73CC313A2C2AD434449 /* SDImageCoderHelper.h in Headers */,\n\t\t\t\t8821E3636BB86560FC2F2D2CFF545F16 /* SDImageCodersManager.h in Headers */,\n\t\t\t\t523861A018452CE8BB166B59A7872BDA /* SDImageFrame.h in Headers */,\n\t\t\t\tC7E8A80BE6BE5452380D8CA71F278B8A /* SDImageGIFCoder.h in Headers */,\n\t\t\t\t80D4A72C26C2EF865F9DCA400D2F1E70 /* SDImageGraphics.h in Headers */,\n\t\t\t\t99709E1C4991C49EE5601FF9461B2969 /* SDImageHEICCoder.h in Headers */,\n\t\t\t\t11E79385CD0DA86166E63D21E7E078E9 /* SDImageIOAnimatedCoder.h in Headers */,\n\t\t\t\t168AB5EA0EBEB75D0434B55D0B97AD47 /* SDImageIOAnimatedCoderInternal.h in Headers */,\n\t\t\t\tE5C6051933677CDF392BF6356271A92E /* SDImageIOCoder.h in Headers */,\n\t\t\t\t67B3DCBA30FDEDA18E0D4E3B2C16C911 /* SDImageLoader.h in Headers */,\n\t\t\t\tC4A78B8FC2DC76FBCF43D9D53BF90767 /* SDImageLoadersManager.h in Headers */,\n\t\t\t\t8C5D0B2A7B52DF68D03820244993E91B /* SDImageTransformer.h in Headers */,\n\t\t\t\t8433F353F3016EFF0316F48188D6B651 /* SDInternalMacros.h in Headers */,\n\t\t\t\tC2D82385F4FDB67F6613CBBE8E2BD850 /* SDMemoryCache.h in Headers */,\n\t\t\t\tE556832E0C191FCFABB9E97C87D243EF /* SDmetamacros.h in Headers */,\n\t\t\t\t9C096C865369C21D252A0F4F90BE21D9 /* SDWeakProxy.h in Headers */,\n\t\t\t\tE515780850EBAD40342EBF2997BFC2D2 /* SDWebImage.h in Headers */,\n\t\t\t\t48920AFFC7C0E2FEA632DAA2BD63287D /* SDWebImage-umbrella.h in Headers */,\n\t\t\t\tB128DE666CCA7CF6B0F09411D8209A92 /* SDWebImageCacheKeyFilter.h in Headers */,\n\t\t\t\tDECA57AF64C5C257919649ECBB75F0B9 /* SDWebImageCacheSerializer.h in Headers */,\n\t\t\t\tFED292AF8AD5924263FC0A8D0B8AF26D /* SDWebImageCompat.h in Headers */,\n\t\t\t\t7D9E8F8A5D02148FCC2DBD6319BCC3D1 /* SDWebImageDefine.h in Headers */,\n\t\t\t\t5B69919844A3BD774BAABB186D6A524F /* SDWebImageDownloader.h in Headers */,\n\t\t\t\tF7289F163C285103D6CCAB39447153CA /* SDWebImageDownloaderConfig.h in Headers */,\n\t\t\t\t05D76FA82DD3C37B76FFC1689CEF9981 /* SDWebImageDownloaderDecryptor.h in Headers */,\n\t\t\t\t20004B99F5050F59E747AB8DFAD7E891 /* SDWebImageDownloaderOperation.h in Headers */,\n\t\t\t\tAD0CFDA140E346502935BA58225E6EF3 /* SDWebImageDownloaderRequestModifier.h in Headers */,\n\t\t\t\t2D7E7D5F025A1006C0D373B5884B6E52 /* SDWebImageDownloaderResponseModifier.h in Headers */,\n\t\t\t\t9917CEAD8CE1CEB7FEC031255AED8FA8 /* SDWebImageError.h in Headers */,\n\t\t\t\t8F88549F032EFFEA9C281860520CC879 /* SDWebImageIndicator.h in Headers */,\n\t\t\t\t07A41F67B40B3C6C6C3DB862F1F633F8 /* SDWebImageManager.h in Headers */,\n\t\t\t\t36F35669F3AFF65477B2366FC09A1B3F /* SDWebImageOperation.h in Headers */,\n\t\t\t\t6F4B172730B7293C1D988FBE34B45E20 /* SDWebImageOptionsProcessor.h in Headers */,\n\t\t\t\t8C9D609988FE2993BB116B4B00FAC57B /* SDWebImagePrefetcher.h in Headers */,\n\t\t\t\t0311D5903A8C13AE6158796BC69AD994 /* SDWebImageTransition.h in Headers */,\n\t\t\t\tB04279CC3476C6D75EDE63B360B89DEC /* SDWebImageTransitionInternal.h in Headers */,\n\t\t\t\tA083AAC3481062E5DE223D480757A83B /* UIButton+WebCache.h in Headers */,\n\t\t\t\tF4811CFAC05932CE436CC2C32BAD91E6 /* UIColor+SDHexString.h in Headers */,\n\t\t\t\tD7BA04ADFE3104907F100E9370184A65 /* UIImage+ExtendedCacheData.h in Headers */,\n\t\t\t\t4A27F890C33243C4548A25318264B375 /* UIImage+ForceDecode.h in Headers */,\n\t\t\t\tDBBAC864AD405BED53782364E0F0D5F3 /* UIImage+GIF.h in Headers */,\n\t\t\t\t26BF15D648EFA59FCA18AE285AC5B2A1 /* UIImage+MemoryCacheCost.h in Headers */,\n\t\t\t\t73F2DE8B48DC2F7C87529AB3901B9E94 /* UIImage+Metadata.h in Headers */,\n\t\t\t\t278F5B2C01E923AA0C691D79BD0F321F /* UIImage+MultiFormat.h in Headers */,\n\t\t\t\tD556C63635E7A83C7A9B04FB104F7339 /* UIImage+Transform.h in Headers */,\n\t\t\t\t37E3C820BC838123661E1391BEAF8092 /* UIImageView+HighlightedWebCache.h in Headers */,\n\t\t\t\t0BFA90EFCD3407716FFC60D140325188 /* UIImageView+WebCache.h in Headers */,\n\t\t\t\tD975B260AB44081399BCB612916CE675 /* UIView+WebCache.h in Headers */,\n\t\t\t\t2F85FF5597762E2E3C6961C6DD690A60 /* UIView+WebCacheOperation.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t18C6945B276FCD1F88687DAA6C122954 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE4CA0B80D962B7042730CCA24DF7A6CE /* Appirater.h in Headers */,\n\t\t\t\t4E024B5A716EC026E33AC8EF18023F4C /* Appirater-umbrella.h in Headers */,\n\t\t\t\t41286FFA3116FB4073CFA821DFB09A03 /* AppiraterDelegate.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t29E404AD0982126E200F09A0FBE7DCF1 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE50990C8CCC727688A0EC4D123CDD295 /* nanopb-umbrella.h in Headers */,\n\t\t\t\t5ABA716A48A3468C5B83F83D69DDF5D2 /* pb.h in Headers */,\n\t\t\t\tFA1435956493F6C517F5A097360C11D2 /* pb_common.h in Headers */,\n\t\t\t\tE78F445F25943A96E2AE21A4AD7EEA67 /* pb_decode.h in Headers */,\n\t\t\t\tECB05ADC1FE7A52E0D9ACCB9B027EF2B /* pb_encode.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3BD6EB14C2F3B8C73B1A7BF26F2227EC /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t74C6F951FCB4661E545409C0AF80D2E7 /* GoogleUtilities-umbrella.h in Headers */,\n\t\t\t\tF10FCC767B08C019DEE8FFB1516299EA /* GULAppDelegateSwizzler.h in Headers */,\n\t\t\t\t5C4E850422971D9660A700996C75898F /* GULAppDelegateSwizzler_Private.h in Headers */,\n\t\t\t\t86DDBF748A2FAB2E5426D9C62F4E97B6 /* GULAppEnvironmentUtil.h in Headers */,\n\t\t\t\t42C1C2FC054DE4C8F98D5D9EABB99732 /* GULApplication.h in Headers */,\n\t\t\t\t9EBE4FF936493E44E9CF7A19860170A8 /* GULHeartbeatDateStorable.h in Headers */,\n\t\t\t\t89A0AC3A2E24FDA5CEDF545C0050C90C /* GULHeartbeatDateStorage.h in Headers */,\n\t\t\t\tE62B328C763183320A9105E6E8EB1860 /* GULHeartbeatDateStorageUserDefaults.h in Headers */,\n\t\t\t\tE8D668C3BC3581332C51EAE1359D2022 /* GULKeychainStorage.h in Headers */,\n\t\t\t\t0184B6B56F7F8EC2CAA4300B5344B419 /* GULKeychainUtils.h in Headers */,\n\t\t\t\tC0EB460750BF5FBED872DD25D3B316CB /* GULLogger.h in Headers */,\n\t\t\t\tDB048A769D5DB1BE84466C9EA4EBBF1B /* GULLoggerCodes.h in Headers */,\n\t\t\t\t242C08FFF99332102B7BF8E2590DA079 /* GULLoggerLevel.h in Headers */,\n\t\t\t\tA70259457F23AD83937DF1CA0DAF46D0 /* GULMutableDictionary.h in Headers */,\n\t\t\t\tE9AD74230A2E90C1FE84024CA1917ACC /* GULNetwork.h in Headers */,\n\t\t\t\tC50420FA308E51F5885CE0A2BA817622 /* GULNetworkConstants.h in Headers */,\n\t\t\t\tDBDF09CBE34BC99BD85677273C4B6296 /* GULNetworkInternal.h in Headers */,\n\t\t\t\tD9B8E5DA0091D211AACED8612BA1153B /* GULNetworkLoggerProtocol.h in Headers */,\n\t\t\t\tB5AFC5251D252C4CF6AC6A609E167BFF /* GULNetworkMessageCode.h in Headers */,\n\t\t\t\t551EE2BA0A3A93F089EF76F85871B5EE /* GULNetworkURLSession.h in Headers */,\n\t\t\t\t02252699D8D416E0AD793B30C95C4BD6 /* GULNSData+zlib.h in Headers */,\n\t\t\t\t7FC014E10F04D9761116EE2481087F70 /* GULOriginalIMPConvenienceMacros.h in Headers */,\n\t\t\t\t81534784497FC1ECE74D5C18D43AF3EB /* GULReachabilityChecker.h in Headers */,\n\t\t\t\t2D3E6969DF4465FC38E09B23A2562DE2 /* GULReachabilityChecker+Internal.h in Headers */,\n\t\t\t\tBBB3C52BD5CE5A8F90FBD5650B283EA1 /* GULReachabilityMessageCode.h in Headers */,\n\t\t\t\tC40413C3772DC573FF3086BAB7D1EE28 /* GULSceneDelegateSwizzler.h in Headers */,\n\t\t\t\t611CE969CEC379BB77D8885D915A8095 /* GULSceneDelegateSwizzler_Private.h in Headers */,\n\t\t\t\tD88E2E3BC8A27A085ABC3AF8AF4C7F86 /* GULSecureCoding.h in Headers */,\n\t\t\t\t90A7255991F8B76C78A1C6A47F0BD3A5 /* GULSwizzler.h in Headers */,\n\t\t\t\t6A60904A4A5C9CB728F36E68131A5629 /* GULURLSessionDataResponse.h in Headers */,\n\t\t\t\t0B63C55C547C48DEE7EBAE9C9DFD3675 /* GULUserDefaults.h in Headers */,\n\t\t\t\tDE3AC691EE0E078459ECBE58059F1260 /* NSURLSession+GULPromises.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3C2A858ED01432DE4CA8738997604903 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t41522E9AD19ACF8675C10B4035405E95 /* FIRAnalyticsConfiguration.h in Headers */,\n\t\t\t\t4F5CFA3002CC0285EAA22323D1E017B7 /* FIRApp.h in Headers */,\n\t\t\t\t0D7F532169AFF271D684865CF89DA8A7 /* FIRAppAssociationRegistration.h in Headers */,\n\t\t\t\tC21AEB2BC0F95C132FDE2206B40199F9 /* FIRAppInternal.h in Headers */,\n\t\t\t\t701F3C59F0434AC67482392B26FB6F0A /* FIRBundleUtil.h in Headers */,\n\t\t\t\t32DD9B533A167E3D45FB7C01D4157D5B /* FIRComponent.h in Headers */,\n\t\t\t\t19BDF52B1C43F4A0EDAA7FA633B9BA88 /* FIRComponentContainer.h in Headers */,\n\t\t\t\tB1F3BDEEBCD13FE138D33F45470AFA71 /* FIRComponentContainerInternal.h in Headers */,\n\t\t\t\tD5573400F45ACFA5316D7AC2BA779056 /* FIRComponentType.h in Headers */,\n\t\t\t\tF646BABB56E9E66692865720E3FB71DA /* FIRConfiguration.h in Headers */,\n\t\t\t\t03860676C8B2758B55FA5C92421B12FC /* FIRConfigurationInternal.h in Headers */,\n\t\t\t\tCA04A500A668FCCEB250C8A61F0643DA /* FIRCoreDiagnosticsConnector.h in Headers */,\n\t\t\t\t48CB1FD2981BA256E4F2582237164A2F /* FIRCoreDiagnosticsData.h in Headers */,\n\t\t\t\t0C663893D044728B8050AD706689AA09 /* FIRCoreDiagnosticsInterop.h in Headers */,\n\t\t\t\t92851B2DB4A4C54E24A1720ADEC60E84 /* FIRDependency.h in Headers */,\n\t\t\t\tD00ADB6F62DCD79FF4AE5477907E4B08 /* FIRDiagnosticsData.h in Headers */,\n\t\t\t\tF417C8E4B3D73E496E4764CF2FE9EDDD /* FirebaseCore.h in Headers */,\n\t\t\t\tD3212FE5382F2D56A8C80829D8780188 /* FirebaseCore-umbrella.h in Headers */,\n\t\t\t\tFA10A9A289B0F3E86CCCE9E2A7E94EF2 /* FirebaseCoreInternal.h in Headers */,\n\t\t\t\t1DD6D013806F64DED16DD22BAED3C369 /* FIRFirebaseUserAgent.h in Headers */,\n\t\t\t\t5911F99F8CABED05F9F701DC450E4BC8 /* FIRHeartbeatInfo.h in Headers */,\n\t\t\t\t6A9D73033878EECC7CAD51C2C82AF26B /* FIRLibrary.h in Headers */,\n\t\t\t\tF4BE3CF05C223248D90AC0F46BAAB9FF /* FIRLogger.h in Headers */,\n\t\t\t\t593E6264A36C1B39D5885E85304C8916 /* FIRLoggerLevel.h in Headers */,\n\t\t\t\tB595EBF813D80EAD2870F0D888B6F1DE /* FIROptions.h in Headers */,\n\t\t\t\tE7AB534DD8C859013ADE863B6D2CBA7D /* FIROptionsInternal.h in Headers */,\n\t\t\t\t95D0E52FDA5F7738F1D6F56696279BF8 /* FIRVersion.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4FB87B3C00E20BB81A2110643D08AC3E /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t72BE14CDABBE9D94A85828F987136A6E /* FBLPromise.h in Headers */,\n\t\t\t\t3919CF80EC56ACAB6A3808C398ED1968 /* FBLPromise+All.h in Headers */,\n\t\t\t\tCA050FC8C58FA008C11AB981F0AC4363 /* FBLPromise+Always.h in Headers */,\n\t\t\t\t83ACE2DB5F2F7F9352D11E9BD334AD96 /* FBLPromise+Any.h in Headers */,\n\t\t\t\t57F70A5C8A2F7A13B0E33409440F4ABD /* FBLPromise+Async.h in Headers */,\n\t\t\t\t23490DF877054EEA5F983AD117033631 /* FBLPromise+Await.h in Headers */,\n\t\t\t\tDC8E06FD7CA80D1461C4E73105FD45AC /* FBLPromise+Catch.h in Headers */,\n\t\t\t\t565EF7659358278D993E12356980AE0C /* FBLPromise+Delay.h in Headers */,\n\t\t\t\t1554350BBDCB525AA477C1F345852437 /* FBLPromise+Do.h in Headers */,\n\t\t\t\tF5734286C309C6E2FF84E06DA25F51EF /* FBLPromise+Race.h in Headers */,\n\t\t\t\t96E8F1107963D738A8DD84FF5D7C4563 /* FBLPromise+Recover.h in Headers */,\n\t\t\t\tD63055B89D739A7EA319FBE861ADEED5 /* FBLPromise+Reduce.h in Headers */,\n\t\t\t\t407A10BF833B480FECDAFC51A259D6D4 /* FBLPromise+Retry.h in Headers */,\n\t\t\t\t05214C0A74E896C781C8CB7719A9984C /* FBLPromise+Testing.h in Headers */,\n\t\t\t\tBD5380B89F6EA6442F55F457CB377251 /* FBLPromise+Then.h in Headers */,\n\t\t\t\t1471F3BFCD49A1FBD39DA3CD4C3DA8B9 /* FBLPromise+Timeout.h in Headers */,\n\t\t\t\t2D5F3E52A136C35D74B92551B645D588 /* FBLPromise+Validate.h in Headers */,\n\t\t\t\t0FC35E1D19F49ACD5B5957B86D32D4EA /* FBLPromise+Wrap.h in Headers */,\n\t\t\t\t1CBE26399B4391159FDD5EF576CA6592 /* FBLPromiseError.h in Headers */,\n\t\t\t\tE92BFF50D3F84D5D8BA6E845FAEF8DA3 /* FBLPromisePrivate.h in Headers */,\n\t\t\t\t57D8A29DA38A71184A984913BBC01CEC /* FBLPromises.h in Headers */,\n\t\t\t\t2C4FBEAF9B8A4CEAF32D5EA477EB6531 /* PromisesObjC-umbrella.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6EE8726894AAD543472DED1FFF731ED9 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF17E3C439BBF49E6486B54C84DD0C190 /* FIRCoreDiagnostics.h in Headers */,\n\t\t\t\tEF75B2C28FA102334A044548123860E2 /* FIRCoreDiagnosticsData.h in Headers */,\n\t\t\t\t6F9B1AAD95146EC2AE89F5B821D611D6 /* FIRCoreDiagnosticsInterop.h in Headers */,\n\t\t\t\t6B83391B3231B704CBEADFE1F3ABE0F1 /* firebasecore.nanopb.h in Headers */,\n\t\t\t\t1058BF78DCB651C56D33B7198AA0D355 /* FirebaseCoreDiagnostics-umbrella.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t9D4712D998CD283461FDCE793EF01F34 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t77B7C664156789B282A6AECEB7F380C7 /* FIRAppInternal.h in Headers */,\n\t\t\t\t78E730C2966F82AB15136ED2AFC85095 /* FIRComponent.h in Headers */,\n\t\t\t\t878C1E830C12ED8A433F6FD3DAC38946 /* FIRComponentContainer.h in Headers */,\n\t\t\t\tD7068278536821417BB567EEED782F73 /* FIRComponentType.h in Headers */,\n\t\t\t\t8C9EAF8201E92AB60FFE3A04A6A1D47B /* FIRCoreDiagnosticsConnector.h in Headers */,\n\t\t\t\t72C3E949015B30F289F28DEDE6BA8F84 /* FIRCurrentDateProvider.h in Headers */,\n\t\t\t\tA4AA6C3C19244F1FF335C090930C609A /* FIRDependency.h in Headers */,\n\t\t\t\tBCD010E21F3444C11F5F87821E7F832D /* FirebaseCoreInternal.h in Headers */,\n\t\t\t\tF1372E076B4B28D2923EA22ED4D6DFCA /* FirebaseInstallations.h in Headers */,\n\t\t\t\t8D3BB2AEBD692793E70D2D3A2BED2135 /* FirebaseInstallations-umbrella.h in Headers */,\n\t\t\t\t2711092C95505064BFF763747C805405 /* FirebaseInstallationsInternal.h in Headers */,\n\t\t\t\t7AE82F1B24F7A2E9B28BAF431611111F /* FIRHeartbeatInfo.h in Headers */,\n\t\t\t\tA5D6F583F2BCDF15588F8BA972A682CE /* FIRInstallations.h in Headers */,\n\t\t\t\t4EDE67DB34FEC06E0EC09F4CCC914EF8 /* FIRInstallationsAPIService.h in Headers */,\n\t\t\t\t67337806BBF45E0F89460C0ECB98F7CC /* FIRInstallationsAuthTokenResult.h in Headers */,\n\t\t\t\tED39F6A91DF2FC44DD73DEE50BF7D393 /* FIRInstallationsAuthTokenResultInternal.h in Headers */,\n\t\t\t\t8BFCDB90BD5C326BE36EE7599F016413 /* FIRInstallationsBackoffController.h in Headers */,\n\t\t\t\t9ADF36BDEE9C92870ACB3F6E17CB0136 /* FIRInstallationsErrors.h in Headers */,\n\t\t\t\t377AF2CA4D196DF568CEF1FB627B9B51 /* FIRInstallationsErrorUtil.h in Headers */,\n\t\t\t\t1D635C91D8BC72532AAD16B6C063D7C0 /* FIRInstallationsHTTPError.h in Headers */,\n\t\t\t\t975390A7158A9A542B397F21D63DDE3F /* FIRInstallationsIDController.h in Headers */,\n\t\t\t\t6C301FF2C25C6329F7EA45C87F96C660 /* FIRInstallationsIIDStore.h in Headers */,\n\t\t\t\t2A866696A7C9DB4CB42A963DE9551B40 /* FIRInstallationsIIDTokenStore.h in Headers */,\n\t\t\t\t7A1EBC1F342550748C7D0A21F7BFA7D6 /* FIRInstallationsItem.h in Headers */,\n\t\t\t\t07E6B04D64953307335FF701FF858427 /* FIRInstallationsItem+RegisterInstallationAPI.h in Headers */,\n\t\t\t\t6EFEF0AC86E0308D25D125522708DD7F /* FIRInstallationsLogger.h in Headers */,\n\t\t\t\t7AF1433C05B27E85A58B5222B73620BB /* FIRInstallationsSingleOperationPromiseCache.h in Headers */,\n\t\t\t\t242A43C50C10362A01FA1F662EF7CF2A /* FIRInstallationsStatus.h in Headers */,\n\t\t\t\t6F333D5505E952CF9C517DAE5114AC2D /* FIRInstallationsStore.h in Headers */,\n\t\t\t\tEFAB05A7F5A8FC35E27F219708D544AD /* FIRInstallationsStoredAuthToken.h in Headers */,\n\t\t\t\t658CF66D84C572191E43DBCA78450144 /* FIRInstallationsStoredItem.h in Headers */,\n\t\t\t\tC8161051C207F9AECD0562B6B9E0E579 /* FIRLibrary.h in Headers */,\n\t\t\t\t2A43AC77BE9EF6259E27876705069383 /* FIRLogger.h in Headers */,\n\t\t\t\t9173483B65737D0C0DD2D1F3427AFE45 /* FIROptionsInternal.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tAAEE67A053DA6BFFD832AC12B98C70ED /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3C1CC94B45A08AF7DC9A6DAF03574A52 /* Pods-Spotify-umbrella.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tE3A6282DA9E6C688D6415ABB30AAD875 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t9E6AB9E70A18A858DCBC3B7D57575F47 /* cct.nanopb.h in Headers */,\n\t\t\t\tBDE45185614935653E3E24E4F8AE8812 /* GDTCCTCompressionHelper.h in Headers */,\n\t\t\t\tE4153F4FB8707C1B1B62815836B8F358 /* GDTCCTNanopbHelpers.h in Headers */,\n\t\t\t\t4D9A4DD4DA000DB1A7233197AB5C9998 /* GDTCCTUploader.h in Headers */,\n\t\t\t\tE2657EA2FA2825ED6DBE1C1BFEA5907C /* GDTCCTUploadOperation.h in Headers */,\n\t\t\t\t0A251DC0DF1E1EE8AC74D44C769312C3 /* GDTCORAssert.h in Headers */,\n\t\t\t\tBFC98970FF0DF6305A33A564BD19BF7C /* GDTCORClock.h in Headers */,\n\t\t\t\t2E658D649B1C8158B79BC43FFC5B298E /* GDTCORConsoleLogger.h in Headers */,\n\t\t\t\t6DA57657B2030D8076B7B341150BC06F /* GDTCORDirectorySizeTracker.h in Headers */,\n\t\t\t\t41EB77C2185B44AC4251285C57FD024F /* GDTCOREndpoints.h in Headers */,\n\t\t\t\tC326A2B1DC92AC4C4C105C1D73C78E13 /* GDTCOREndpoints_Private.h in Headers */,\n\t\t\t\t773B2DCA4762991C7F8FAE2FC860253D /* GDTCOREvent.h in Headers */,\n\t\t\t\tCF8968D878454B5BAE07037D28947D93 /* GDTCOREvent+GDTCCTSupport.h in Headers */,\n\t\t\t\tB82109186D3614122E6130F9710A241F /* GDTCOREvent_Private.h in Headers */,\n\t\t\t\tEB3A214553ED6CFAF04498A2DBAFE0EF /* GDTCOREventDataObject.h in Headers */,\n\t\t\t\tCA180BD40DFE51946C1F45D45D5E3784 /* GDTCOREventTransformer.h in Headers */,\n\t\t\t\tFE7AB9DA939B0E528ED9F339C6DCC201 /* GDTCORFlatFileStorage.h in Headers */,\n\t\t\t\t86A4EDC386D953055E2EFD288F8549E7 /* GDTCORFlatFileStorage+Promises.h in Headers */,\n\t\t\t\t457289616B6777C1D443FBC91A2F0325 /* GDTCORLifecycle.h in Headers */,\n\t\t\t\tE20DFCFF1B1EA67C678445D94AFC6782 /* GDTCORPlatform.h in Headers */,\n\t\t\t\t01CB8221A492BC65C076670906A3D08E /* GDTCORReachability.h in Headers */,\n\t\t\t\t116DB4571C6E70C54479C15F140245AE /* GDTCORReachability_Private.h in Headers */,\n\t\t\t\t2D874A9744A25E43B747743945547339 /* GDTCORRegistrar.h in Headers */,\n\t\t\t\t71093AA6681FFAD2FA263E3FADE983D1 /* GDTCORRegistrar_Private.h in Headers */,\n\t\t\t\tA3F8A995C1C713901F9B4503D4103A47 /* GDTCORStorageEventSelector.h in Headers */,\n\t\t\t\t23D8684E3F488264A90E5954D59B902C /* GDTCORStorageProtocol.h in Headers */,\n\t\t\t\t7A6E617487687A7EC3ED28D9090EC0E4 /* GDTCORTargets.h in Headers */,\n\t\t\t\tF8FE94E2FE6E57F616878424F22528CA /* GDTCORTransformer.h in Headers */,\n\t\t\t\tA0857AD2616E974FC2D53A08EC963D28 /* GDTCORTransformer_Private.h in Headers */,\n\t\t\t\t9749F5178C242B199D8F80DBC55F1041 /* GDTCORTransport.h in Headers */,\n\t\t\t\t7D41A53C422B8849362A0A50C943F0E1 /* GDTCORTransport_Private.h in Headers */,\n\t\t\t\t6F030A5B151E155313EFC0C843C68018 /* GDTCORUploadBatch.h in Headers */,\n\t\t\t\tBE6B23777B825686F33ED40AABA4F17C /* GDTCORUploadCoordinator.h in Headers */,\n\t\t\t\t6337C7DF0D550595E0FC08E973C61709 /* GDTCORUploader.h in Headers */,\n\t\t\t\tE9BF3DACAEE3509B06DBDA16478ED73F /* GoogleDataTransport.h in Headers */,\n\t\t\t\tD288AE30D1159545D1E3CDB721EA5841 /* GoogleDataTransport-umbrella.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\t2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 46F0398C816ED3AA63BC7D085DC1F978 /* Build configuration list for PBXNativeTarget \"PromisesObjC\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t4FB87B3C00E20BB81A2110643D08AC3E /* Headers */,\n\t\t\t\tC1CF4B15D01CD8E372C0028680453569 /* Copy . Private Headers */,\n\t\t\t\t88441CA33AAB2BA346D73F3E23B24BC1 /* Copy . Public Headers */,\n\t\t\t\t2362F9FEF0DF2A76C2B1EA4130714BDE /* Sources */,\n\t\t\t\tF0861647ADFD6A6E877396A52F43B90A /* Frameworks */,\n\t\t\t\t7979E800B2981CF5A3261B4DB562886F /* Resources */,\n\t\t\t\t8BE12CEDA6334EF21206A8668571B037 /* Create Symlinks to Header Folders */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = PromisesObjC;\n\t\t\tproductName = FBLPromises;\n\t\t\tproductReference = 3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t329161CB25D509AB980F6AF24CA7547D /* Pods-Spotify */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F9932C06D533E1975770B00862F43DBE /* Build configuration list for PBXNativeTarget \"Pods-Spotify\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tAAEE67A053DA6BFFD832AC12B98C70ED /* Headers */,\n\t\t\t\tBB25ABCA5E3180D0B10028570ACE7E37 /* Sources */,\n\t\t\t\tF9DE14B7D99DBDE04A0AC39B6C4F83E3 /* Frameworks */,\n\t\t\t\t1E8AB121F0B1EA326E5FF93A31A85B08 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t13B6A2818085404337546918562D2A58 /* PBXTargetDependency */,\n\t\t\t\t0FCFAC8662107973C6B3833F8221E054 /* PBXTargetDependency */,\n\t\t\t\t1FDE3859A86742A341F1C4B4A8709B65 /* PBXTargetDependency */,\n\t\t\t\t05418E3E8DB5758F81B68AA1AFE84497 /* PBXTargetDependency */,\n\t\t\t\tAFE857B2C1F21EEB8EB7DD94E4956E90 /* PBXTargetDependency */,\n\t\t\t\t7A7789E4FA83CCD3B641714A3466F165 /* PBXTargetDependency */,\n\t\t\t\t395489EFA954E16360E8BADF0B7F052F /* PBXTargetDependency */,\n\t\t\t\tB08F1C872AAD239599E5E808A891DE1E /* PBXTargetDependency */,\n\t\t\t\t4CF797E9B128427F0965C0BC52003A00 /* PBXTargetDependency */,\n\t\t\t\tF71CBD8551E56023AD9C7EC515E0F71C /* PBXTargetDependency */,\n\t\t\t\t018BD7B2414A119D291C56A682084ECF /* PBXTargetDependency */,\n\t\t\t\tA1161D8622C2DC03EAB4D7D9F4C33503 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"Pods-Spotify\";\n\t\t\tproductName = Pods_Spotify;\n\t\t\tproductReference = 97DFD7435A40FB6C7611C58681006DC8 /* Pods-Spotify */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t3847153A6E5EEFB86565BA840768F429 /* SDWebImage */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = BABD4A24CFCBE5B6FE4680AA062FCF04 /* Build configuration list for PBXNativeTarget \"SDWebImage\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t104737A7F2F8176AF07A40A019B4DC37 /* Headers */,\n\t\t\t\t4B6FB7A17469A2800E7231A1444746CB /* Sources */,\n\t\t\t\tFB6A1E8A43CF1D3ADFB49BA355F0DEA1 /* Frameworks */,\n\t\t\t\tDC20DB2B5A8B3C34EAC16992C6449775 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = SDWebImage;\n\t\t\tproductName = SDWebImage;\n\t\t\tproductReference = B0B214D775196BA7CA8E17E53048A493 /* SDWebImage */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EECB93EB4A16F755B006CF1CB0DE9A22 /* Build configuration list for PBXNativeTarget \"FirebaseCore\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t3C2A858ED01432DE4CA8738997604903 /* Headers */,\n\t\t\t\tE1D3B401B4C2E4B3A4F768E6DA5C8F14 /* Sources */,\n\t\t\t\tADD00E3E8A0426067D803A942C3BA84C /* Frameworks */,\n\t\t\t\tFE94F70A1A799458E1F82D5F18A02AE4 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tC229E2B3E24D709FC76B001754EFA1EF /* PBXTargetDependency */,\n\t\t\t\t201B11D0246FB95D4543FB6BE95EF698 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = FirebaseCore;\n\t\t\tproductName = FirebaseCore;\n\t\t\tproductReference = E2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t5C0371EE948D0357B8EE0E34ABB44BF0 /* GoogleDataTransport */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 9F539D1E2A2664475FDEEE8A0269B722 /* Build configuration list for PBXNativeTarget \"GoogleDataTransport\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tE3A6282DA9E6C688D6415ABB30AAD875 /* Headers */,\n\t\t\t\t2D65A612FEAB4C79C4228721C3B473E7 /* Sources */,\n\t\t\t\tDA11FA7A020AFDCA73B93EDF3D3F1073 /* Frameworks */,\n\t\t\t\t9747C1EB513D24C4C51D4CC2EE56F574 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t7E29F90F20C2FBF0E612ED469B18B7F8 /* PBXTargetDependency */,\n\t\t\t\t8AA30AE8AB0BFA17B7E024F8E7E96BDC /* PBXTargetDependency */,\n\t\t\t\t85FEAC43D8F304E679980E6B43979D20 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = GoogleDataTransport;\n\t\t\tproductName = GoogleDataTransport;\n\t\t\tproductReference = 856B5CD56F194FAD26EA91620B66D614 /* GoogleDataTransport */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t620E05868772C10B4920DC7E324F2C87 /* FirebaseCoreDiagnostics */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F1704FE42FCDBE50057E175108258411 /* Build configuration list for PBXNativeTarget \"FirebaseCoreDiagnostics\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6EE8726894AAD543472DED1FFF731ED9 /* Headers */,\n\t\t\t\tB696C829F99E67EEF6DF2D6048F1EE28 /* Sources */,\n\t\t\t\tD8CEF8654739A822265F965518353CC2 /* Frameworks */,\n\t\t\t\t3B88A2AE4E79B707F0B45A336C40956B /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tA8C51E5D5646759D40788B521985C440 /* PBXTargetDependency */,\n\t\t\t\t0F96D323478F9DB4B93A3015A06674B7 /* PBXTargetDependency */,\n\t\t\t\t951408F8CDF7F8851879BBD03CA335CB /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = FirebaseCoreDiagnostics;\n\t\t\tproductName = FirebaseCoreDiagnostics;\n\t\t\tproductReference = 8CC9178C366942FD6FF6A115604EAD58 /* FirebaseCoreDiagnostics */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = E8B9EEC407F92382DE95FD8E4661E000 /* Build configuration list for PBXNativeTarget \"FirebaseInstallations\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t9D4712D998CD283461FDCE793EF01F34 /* Headers */,\n\t\t\t\tC11285BF080C3F0235B5C0730640FD1C /* Sources */,\n\t\t\t\tD7D014542D95DD38C8C2502010D4CD43 /* Frameworks */,\n\t\t\t\tC3A13DEB80BBD9B7449455172FD1FE8C /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t77FE8B60CDB8A7EE71694A946F1D253A /* PBXTargetDependency */,\n\t\t\t\t978C41BEAC6DA5656985B8AC107682DF /* PBXTargetDependency */,\n\t\t\t\t5B83E357C22146EA67403D7A55EEDE16 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = FirebaseInstallations;\n\t\t\tproductName = FirebaseInstallations;\n\t\t\tproductReference = 13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2C558C338876A0E05F2989B002E36AF0 /* Build configuration list for PBXNativeTarget \"GoogleUtilities\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t3BD6EB14C2F3B8C73B1A7BF26F2227EC /* Headers */,\n\t\t\t\t6C798BFA74D7509FE9165B55DD4F7984 /* Sources */,\n\t\t\t\tA9D2F93060742D670740AA52D4F1A7BE /* Frameworks */,\n\t\t\t\t0640D57AE09D405801C7DE0987AB64A0 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tCB5398E5AA2AE6280A5A199E1C1B4DC6 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = GoogleUtilities;\n\t\t\tproductName = GoogleUtilities;\n\t\t\tproductReference = B43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tCE9FA8ACD6205C77B753798CD736FAEF /* Appirater */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = AE99F33A27C881BD800348FEEB1F30ED /* Build configuration list for PBXNativeTarget \"Appirater\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t18C6945B276FCD1F88687DAA6C122954 /* Headers */,\n\t\t\t\t2CB09AF1060077D0DF2C1F44242EF097 /* Sources */,\n\t\t\t\t751E8AA0AFD15DFD93F5C1D10458E77C /* Frameworks */,\n\t\t\t\t771D9E5FCBE5E71EDCB5627928B0C598 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t4D830A4469F8E53C2692049849EE1926 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = Appirater;\n\t\t\tproductName = Appirater;\n\t\t\tproductReference = 23D4D9F87518207E73E88D8FBC7C8DE3 /* Appirater */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tD2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = DE2E2EB059407E49369C43F9C869DE26 /* Build configuration list for PBXNativeTarget \"nanopb\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t29E404AD0982126E200F09A0FBE7DCF1 /* Headers */,\n\t\t\t\t233B17B303030E7271F339D634D6D491 /* Sources */,\n\t\t\t\t557258F7F82A8926BA01926A0CB40E15 /* Frameworks */,\n\t\t\t\t25A696811D01AA3CB193F0776F075E7C /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = nanopb;\n\t\t\tproductName = nanopb;\n\t\t\tproductReference = 06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tE56E80821D169C98E99A62EBCBC60B2C /* Appirater-Appirater */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = A48EEF29879720928C371CC9994578C8 /* Build configuration list for PBXNativeTarget \"Appirater-Appirater\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tA8FBB3E0FEA1E4F406E6833EF981197D /* Sources */,\n\t\t\t\t2F90AC4B1394693187B33E9454925C26 /* Frameworks */,\n\t\t\t\t05AC6C41AA92542B0304B49BCF06A720 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Appirater-Appirater\";\n\t\t\tproductName = Appirater;\n\t\t\tproductReference = 1E9CD753F6BD26760EFAA1DF57482D50 /* Appirater-Appirater */;\n\t\t\tproductType = \"com.apple.product-type.bundle\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tBFDFE7DC352907FC980B868725387E98 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1240;\n\t\t\t\tLastUpgradeCheck = 1240;\n\t\t\t};\n\t\t\tbuildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject \"Pods\" */;\n\t\t\tcompatibilityVersion = \"Xcode 10.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tBase,\n\t\t\t\tar,\n\t\t\t\tca,\n\t\t\t\tcs,\n\t\t\t\tda,\n\t\t\t\tde,\n\t\t\t\tel,\n\t\t\t\ten,\n\t\t\t\tes,\n\t\t\t\tfa,\n\t\t\t\tfi,\n\t\t\t\tfr,\n\t\t\t\the,\n\t\t\t\thu,\n\t\t\t\thy,\n\t\t\t\tid,\n\t\t\t\tit,\n\t\t\t\tja,\n\t\t\t\tko,\n\t\t\t\tms,\n\t\t\t\tnb,\n\t\t\t\tnl,\n\t\t\t\tpl,\n\t\t\t\tpt,\n\t\t\t\t\"pt-BR\",\n\t\t\t\tro,\n\t\t\t\tru,\n\t\t\t\tsk,\n\t\t\t\tsv,\n\t\t\t\tth,\n\t\t\t\ttr,\n\t\t\t\tuk,\n\t\t\t\tvi,\n\t\t\t\t\"zh-Hans\",\n\t\t\t\t\"zh-Hant\",\n\t\t\t);\n\t\t\tmainGroup = CF1408CF629C7361332E53B88F7BD30C;\n\t\t\tproductRefGroup = 1FC49855849F77DD042774C08FB9A2BD /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tCE9FA8ACD6205C77B753798CD736FAEF /* Appirater */,\n\t\t\t\tE56E80821D169C98E99A62EBCBC60B2C /* Appirater-Appirater */,\n\t\t\t\t072CEA044D2EF26F03496D5996BBF59F /* Firebase */,\n\t\t\t\tC49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */,\n\t\t\t\t4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */,\n\t\t\t\t620E05868772C10B4920DC7E324F2C87 /* FirebaseCoreDiagnostics */,\n\t\t\t\t87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */,\n\t\t\t\tB53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */,\n\t\t\t\t5C0371EE948D0357B8EE0E34ABB44BF0 /* GoogleDataTransport */,\n\t\t\t\t8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */,\n\t\t\t\tD2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */,\n\t\t\t\t329161CB25D509AB980F6AF24CA7547D /* Pods-Spotify */,\n\t\t\t\t2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */,\n\t\t\t\t3847153A6E5EEFB86565BA840768F429 /* SDWebImage */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t05AC6C41AA92542B0304B49BCF06A720 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t44C7A4ACB41F2B0E588E01C98A0BBE31 /* ar.lproj in Resources */,\n\t\t\t\tACC1D2855B9D8168F64EAAB7869DE334 /* ca.lproj in Resources */,\n\t\t\t\t326BA8EC7036E90AE3AE390C40069CAA /* cs.lproj in Resources */,\n\t\t\t\tC02890A41D0AB13F90A47695B7F2867F /* da.lproj in Resources */,\n\t\t\t\tF1CFF76FC50BF026284051C6CAB9B389 /* de.lproj in Resources */,\n\t\t\t\t8C207CEE5189EAF1C9408F8FCE291E11 /* el.lproj in Resources */,\n\t\t\t\tDBCEB21658D3825FA81F27822AADAD11 /* en.lproj in Resources */,\n\t\t\t\t7CA7517C4920C00FDAB34D5152390BA6 /* es.lproj in Resources */,\n\t\t\t\t868244D3347466936301E48DA39BE842 /* fa.lproj in Resources */,\n\t\t\t\t92B70011891306D90A55DC048EEE2DCC /* fi.lproj in Resources */,\n\t\t\t\tE5C7FA5788C38AD0308CC3B712DD53A2 /* fr.lproj in Resources */,\n\t\t\t\t8E2FC561736D6CE4D3D7F50A4DE1A540 /* he.lproj in Resources */,\n\t\t\t\t97E10B0D702DED48D5FD1062AA27E9AB /* hu.lproj in Resources */,\n\t\t\t\tE9358141369A46CD15097FD5B56279AC /* hy.lproj in Resources */,\n\t\t\t\tB48A893A8058A155BCFA6211E8BBAEE4 /* id.lproj in Resources */,\n\t\t\t\t83747CB2CE756E6DE235E7A419CE6B64 /* it.lproj in Resources */,\n\t\t\t\t22A29883D6BD2C46CFCB90EFE1E6B1B6 /* ja.lproj in Resources */,\n\t\t\t\t3339C7240948FC777912F0CCA95C3073 /* ko.lproj in Resources */,\n\t\t\t\tF56971E69EB803E06C38E2751620E1E8 /* ms.lproj in Resources */,\n\t\t\t\t762A59E0FF6F1A92B360C6E0A5E4A7CA /* nb.lproj in Resources */,\n\t\t\t\t3C22E2D2D6CDBD066DEDBEA8CEB50170 /* nl.lproj in Resources */,\n\t\t\t\tDD5D476FF518ACB3772717620E7D393A /* pl.lproj in Resources */,\n\t\t\t\tA179E49E5148E014ACB35B3234A79829 /* pt.lproj in Resources */,\n\t\t\t\t6BDCB1B9157D9AF6B3A78C0E0619FFA2 /* pt-BR.lproj in Resources */,\n\t\t\t\t5C10B5CF2AEA5FB4A63F282ECA9F7CB7 /* ro.lproj in Resources */,\n\t\t\t\tC6CF8D2EE14A91A98FC8E5BA749F6D3C /* ru.lproj in Resources */,\n\t\t\t\t7E7E08BEE28A0144B41743F4C265B0AC /* sk.lproj in Resources */,\n\t\t\t\t1E49C6EF4C021764307A50165CAA713A /* sv.lproj in Resources */,\n\t\t\t\tB309A5100D011205E23108FA864CEE9F /* th.lproj in Resources */,\n\t\t\t\t3E24B31FF1BB232157618DC8EE918071 /* tr.lproj in Resources */,\n\t\t\t\t0AA4EFD2D280F30CA93FD51643349602 /* uk.lproj in Resources */,\n\t\t\t\tF421606C12494E53B7F6B5EAE13352F1 /* vi.lproj in Resources */,\n\t\t\t\t425F70D9B529938D9F19EE92FDBAA4E5 /* zh-Hans.lproj in Resources */,\n\t\t\t\tA331C78D95C334AC3C328874419FB071 /* zh-Hant.lproj in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t0640D57AE09D405801C7DE0987AB64A0 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t1E8AB121F0B1EA326E5FF93A31A85B08 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t25A696811D01AA3CB193F0776F075E7C /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3B88A2AE4E79B707F0B45A336C40956B /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t771D9E5FCBE5E71EDCB5627928B0C598 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t493EEC1796ACFA77A28E7630060A059E /* Appirater-Appirater in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t7979E800B2981CF5A3261B4DB562886F /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t9747C1EB513D24C4C51D4CC2EE56F574 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3A13DEB80BBD9B7449455172FD1FE8C /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDC20DB2B5A8B3C34EAC16992C6449775 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tFE94F70A1A799458E1F82D5F18A02AE4 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t36517C47DEF3A4F55B4079EB176CAC62 /* [CP] Copy XCFrameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Copy XCFrameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t8BE12CEDA6334EF21206A8668571B037 /* Create Symlinks to Header Folders */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Create Symlinks to Header Folders\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"cd \\\"$CONFIGURATION_BUILD_DIR/$WRAPPER_NAME\\\" || exit 1\\nif [ ! -d Versions ]; then\\n  # Not a versioned framework, so no need to do anything\\n  exit 0\\nfi\\n\\npublic_path=\\\"${PUBLIC_HEADERS_FOLDER_PATH#$CONTENTS_FOLDER_PATH/}\\\"\\nif [ ! -f \\\"$public_path\\\" ]; then\\n  ln -fs \\\"${PUBLIC_HEADERS_FOLDER_PATH#$WRAPPER_NAME/}\\\" \\\"$public_path\\\"\\nfi\\n\\nprivate_path=\\\"${PRIVATE_HEADERS_FOLDER_PATH#$CONTENTS_FOLDER_PATH/}\\\"\\nif [ ! -f \\\"$private_path\\\" ]; then\\n  ln -fs \\\"${PRIVATE_HEADERS_FOLDER_PATH#$WRAPPER_NAME/}\\\" \\\"$private_path\\\"\\nfi\\n\";\n\t\t};\n\t\tCB5AF08085F7665FEB6F74BC117BDB28 /* [CP] Copy XCFrameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Copy XCFrameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t233B17B303030E7271F339D634D6D491 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF3824BB13CE13E5071200A50EA544D21 /* nanopb-dummy.m in Sources */,\n\t\t\t\t5FCA234EC54B026FF4FE2CCCFCB1EE7E /* pb_common.c in Sources */,\n\t\t\t\tF269152E11B82F412D3BD37F3E13E6C1 /* pb_decode.c in Sources */,\n\t\t\t\t573CBCA281A2BB0F097329EE28BCFE60 /* pb_encode.c in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2362F9FEF0DF2A76C2B1EA4130714BDE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA65D64846FFDD7178C8708AF52B5CECF /* FBLPromise.m in Sources */,\n\t\t\t\t34816FB2D38145B7EC7D7A14CF5C93D8 /* FBLPromise+All.m in Sources */,\n\t\t\t\t71A8CC130B0CB8E978F51381AFD722C7 /* FBLPromise+Always.m in Sources */,\n\t\t\t\t7EF58E7AF295CBE99496A96A5D8C13EA /* FBLPromise+Any.m in Sources */,\n\t\t\t\tE96C68381CF2BD5D022DE8DC47200C53 /* FBLPromise+Async.m in Sources */,\n\t\t\t\tF270EDD68B781B1BE74FE134DADC2FE1 /* FBLPromise+Await.m in Sources */,\n\t\t\t\t25FE5A4220B051E800D649E94BDCF418 /* FBLPromise+Catch.m in Sources */,\n\t\t\t\t38B61754E5D4BFD359FDE9EF1BE4A661 /* FBLPromise+Delay.m in Sources */,\n\t\t\t\t64DF55F7B991438E693B9A078807E55B /* FBLPromise+Do.m in Sources */,\n\t\t\t\t499C6F529CC2F5D8A828374ED7DE1069 /* FBLPromise+Race.m in Sources */,\n\t\t\t\t3464ADF2B770D2FE01006027F4882723 /* FBLPromise+Recover.m in Sources */,\n\t\t\t\tAC11317554C3B930BCC98EB6937EEC91 /* FBLPromise+Reduce.m in Sources */,\n\t\t\t\t832067DBD9BAC003B8E5687562E6BBCE /* FBLPromise+Retry.m in Sources */,\n\t\t\t\tD6742E4A0E030524C50C7BFD7FEB7292 /* FBLPromise+Testing.m in Sources */,\n\t\t\t\t79B821DE59EE806496A9FD4FF3FEDAB7 /* FBLPromise+Then.m in Sources */,\n\t\t\t\t9F4966331D34AA8CE85C4E7161B8D732 /* FBLPromise+Timeout.m in Sources */,\n\t\t\t\tFA9814200D820A4CB4EE5032B8E5973A /* FBLPromise+Validate.m in Sources */,\n\t\t\t\t2797DBBF0C00C0C9AED6C496F1AA1CB8 /* FBLPromise+Wrap.m in Sources */,\n\t\t\t\t1E1FF13F9AB197201C44EEC0D4E9E9EF /* FBLPromiseError.m in Sources */,\n\t\t\t\t41382DAAC306E1762433B4D291DAD21D /* PromisesObjC-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2CB09AF1060077D0DF2C1F44242EF097 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t55A09541F17B3F7BD4C62636A15F6212 /* Appirater.m in Sources */,\n\t\t\t\t475453293C1679D47716F8E17703824E /* Appirater-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D65A612FEAB4C79C4228721C3B473E7 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF3BF79D7923FCC0DBCCE33CC97D7134B /* cct.nanopb.c in Sources */,\n\t\t\t\tED9E9EC31A5AC510BBF8568956DCA102 /* GDTCCTCompressionHelper.m in Sources */,\n\t\t\t\t6F7307112195D5B6083F450AB2657AE2 /* GDTCCTNanopbHelpers.m in Sources */,\n\t\t\t\tEF78F3AE3374BED3DC0FBF7B944B9057 /* GDTCCTUploader.m in Sources */,\n\t\t\t\t3BA8E6BD1A15686C195985599A525C84 /* GDTCCTUploadOperation.m in Sources */,\n\t\t\t\t50FB78A15928E090B123F944AF92656A /* GDTCORAssert.m in Sources */,\n\t\t\t\t56E2818C97A95CF9EC25FF22E92B0F3E /* GDTCORClock.m in Sources */,\n\t\t\t\t6ABBB7192F4FA78A90D45CA78172AC86 /* GDTCORConsoleLogger.m in Sources */,\n\t\t\t\t4649E8C6659D310A609EF296697D6C4F /* GDTCORDirectorySizeTracker.m in Sources */,\n\t\t\t\tC4E92D0B4B466595D3F4649BD0827A15 /* GDTCOREndpoints.m in Sources */,\n\t\t\t\tB98DAA42533894F17AD50F5DA1EFD347 /* GDTCOREvent.m in Sources */,\n\t\t\t\tFE42751E23F9C15EB7A8D8D0569D95F1 /* GDTCOREvent+GDTCCTSupport.m in Sources */,\n\t\t\t\tEAABECDA1C6109F989C004C1DCEBE07E /* GDTCORFlatFileStorage.m in Sources */,\n\t\t\t\tFE4C5664159A808BD7984CB35D69CFAB /* GDTCORFlatFileStorage+Promises.m in Sources */,\n\t\t\t\tF3B6F6BEAD0AFF34EAE82B95A7C56037 /* GDTCORLifecycle.m in Sources */,\n\t\t\t\tDA16EA1A389CE66496E2FCBCCDA0D0ED /* GDTCORPlatform.m in Sources */,\n\t\t\t\t388894A87C75381A940680CDD02C263E /* GDTCORReachability.m in Sources */,\n\t\t\t\t036B849251F9D940A08CE9945DF158D2 /* GDTCORRegistrar.m in Sources */,\n\t\t\t\t65F85B6A937820FAA8F2ACA55AAC93D7 /* GDTCORStorageEventSelector.m in Sources */,\n\t\t\t\t153AB0D2CFAFC43A733B6B2A551FBE76 /* GDTCORTransformer.m in Sources */,\n\t\t\t\tF02178012C14330925DC2AB2DF60482B /* GDTCORTransport.m in Sources */,\n\t\t\t\t2749C745E4CCB505CACD055CAAF7B51A /* GDTCORUploadBatch.m in Sources */,\n\t\t\t\tF4232EBD3CD57E497ECED11C9BECC958 /* GDTCORUploadCoordinator.m in Sources */,\n\t\t\t\t2E1CFA6F381B7FD85B94D8043BA56219 /* GoogleDataTransport-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4B6FB7A17469A2800E7231A1444746CB /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t21D05279AA20EE7A1707A76C11BBCC00 /* NSBezierPath+SDRoundedCorners.m in Sources */,\n\t\t\t\t474163E6CF20CA1AC3698759F2B6D51B /* NSButton+WebCache.m in Sources */,\n\t\t\t\tFF66F3E7374A9398D5B08AA23273BC0E /* NSData+ImageContentType.m in Sources */,\n\t\t\t\t994327308CC7ECE7850C804FA0EA5F21 /* NSImage+Compatibility.m in Sources */,\n\t\t\t\t9CEB5B454088D6BCC3A11C759A76161A /* SDAnimatedImage.m in Sources */,\n\t\t\t\t0C76BA74E22A5CFD8207C10026401D80 /* SDAnimatedImagePlayer.m in Sources */,\n\t\t\t\t24DA814C2F7EA7C4187E2BF0B6466E9A /* SDAnimatedImageRep.m in Sources */,\n\t\t\t\tD88076DA0593D2835645CA5A92FFA37C /* SDAnimatedImageView.m in Sources */,\n\t\t\t\tAA3AE0DF5E35D3E0D2CAE7972D69373E /* SDAnimatedImageView+WebCache.m in Sources */,\n\t\t\t\t4F5982101CB9FB68613E826F137B5E95 /* SDAssociatedObject.m in Sources */,\n\t\t\t\t498AB54D6531F0B57EAAD113AA0CF0F9 /* SDAsyncBlockOperation.m in Sources */,\n\t\t\t\t58FAE3A59FBE896EBBDACB0808067CA5 /* SDDeviceHelper.m in Sources */,\n\t\t\t\t275F99E74511043432C892810081DCAF /* SDDiskCache.m in Sources */,\n\t\t\t\t9D7EBB3A7377C116526B8A511F8CE245 /* SDDisplayLink.m in Sources */,\n\t\t\t\t2C762E5C654B718C19CC98FEB27C2DA4 /* SDFileAttributeHelper.m in Sources */,\n\t\t\t\tB88C351562CE8FA4255EA9023213BE4E /* SDGraphicsImageRenderer.m in Sources */,\n\t\t\t\t854D7A4A2872566E4D06870518053225 /* SDImageAPNGCoder.m in Sources */,\n\t\t\t\t3015C91C523C5133A639F57DE0425100 /* SDImageAssetManager.m in Sources */,\n\t\t\t\tD7D077F0FA5CAC32ACB65372453C701F /* SDImageAWebPCoder.m in Sources */,\n\t\t\t\t0D2B3D451D64A5A0AE5CE51E975D7494 /* SDImageCache.m in Sources */,\n\t\t\t\t888BEE4C3B238AC407C59D2194939AB9 /* SDImageCacheConfig.m in Sources */,\n\t\t\t\t138DFC533930F784B55D9BB8AACC0E06 /* SDImageCacheDefine.m in Sources */,\n\t\t\t\t4623448C58E0E271F0DF5F4CC6CAFD0D /* SDImageCachesManager.m in Sources */,\n\t\t\t\t78AE96580BD551EB905F72C21AB81E97 /* SDImageCachesManagerOperation.m in Sources */,\n\t\t\t\t64CDB33E49BDBE16653C88756E26B8CB /* SDImageCoder.m in Sources */,\n\t\t\t\tE9CF46857D61D2A8AF4C3722C27C61C6 /* SDImageCoderHelper.m in Sources */,\n\t\t\t\tDB68D9AFA817850ED9EBBE7F3F378AF5 /* SDImageCodersManager.m in Sources */,\n\t\t\t\t007F57C0030B0CA201A359FD816A3CE1 /* SDImageFrame.m in Sources */,\n\t\t\t\t164DEB7B33A09DD8663942511488AD16 /* SDImageGIFCoder.m in Sources */,\n\t\t\t\tF0E28CEF30861F3589A4A662CEA76D80 /* SDImageGraphics.m in Sources */,\n\t\t\t\tE33A7CDF3107CD3426ADD0D906100CD4 /* SDImageHEICCoder.m in Sources */,\n\t\t\t\t96479C9C76FDC513C03ADD58168F6911 /* SDImageIOAnimatedCoder.m in Sources */,\n\t\t\t\t536E9C0D3855A6AF7CADCB9FBAFC613D /* SDImageIOCoder.m in Sources */,\n\t\t\t\tABEAA41C35A6CD25C93E622FB129C379 /* SDImageLoader.m in Sources */,\n\t\t\t\t3F567CE353442AE137B71B258409F5DA /* SDImageLoadersManager.m in Sources */,\n\t\t\t\tA9A87DA629538D239C4B7401EB56AEB5 /* SDImageTransformer.m in Sources */,\n\t\t\t\t61CD5A24511DC980EFF397CF57AC50F5 /* SDInternalMacros.m in Sources */,\n\t\t\t\t0D0AF4DF934B7BE39EC6E287B003BBA6 /* SDMemoryCache.m in Sources */,\n\t\t\t\t4075297FF5A21C84EF513521FD7B34EF /* SDWeakProxy.m in Sources */,\n\t\t\t\t0DEECB4887F8ED8A8304156D1C440639 /* SDWebImage-dummy.m in Sources */,\n\t\t\t\t67B0CAAD8E88B9A2357C41E73EA2EB48 /* SDWebImageCacheKeyFilter.m in Sources */,\n\t\t\t\t05102BD9E7BCB80DC7B64A34D0E7850B /* SDWebImageCacheSerializer.m in Sources */,\n\t\t\t\tE4AF87F8012F919F00E2E8698A1A3C33 /* SDWebImageCompat.m in Sources */,\n\t\t\t\t49F97D8BA4E81A5E0EF866A293392AF2 /* SDWebImageDefine.m in Sources */,\n\t\t\t\tD68F08F717E95BABFB43AE705D943426 /* SDWebImageDownloader.m in Sources */,\n\t\t\t\tFE05A1BF611E69C94BC7A9EADBE10B2F /* SDWebImageDownloaderConfig.m in Sources */,\n\t\t\t\tDE0BA471FB4FC10C0B25BDE4F22F5B76 /* SDWebImageDownloaderDecryptor.m in Sources */,\n\t\t\t\tDB61822BEA875B413C858E1166590C9F /* SDWebImageDownloaderOperation.m in Sources */,\n\t\t\t\tC27BD8C6B4E713A8E7B7B76B80E45823 /* SDWebImageDownloaderRequestModifier.m in Sources */,\n\t\t\t\tFB359FC2B8375E01A8A8F84D3C50EE82 /* SDWebImageDownloaderResponseModifier.m in Sources */,\n\t\t\t\t5F49C3C9A3733CD50642E0B57D405D44 /* SDWebImageError.m in Sources */,\n\t\t\t\t343B53EB998CC5B609B8DE84BAD882E0 /* SDWebImageIndicator.m in Sources */,\n\t\t\t\tFE4845B6FDD260059CDF9E26965CA31B /* SDWebImageManager.m in Sources */,\n\t\t\t\tBE649A29E5FB32C54FDAE55994804F6D /* SDWebImageOperation.m in Sources */,\n\t\t\t\t7A424FED21A399FE2610DCB710A4A3FB /* SDWebImageOptionsProcessor.m in Sources */,\n\t\t\t\t62A22A4C10675F9B65C7677CFD6C4676 /* SDWebImagePrefetcher.m in Sources */,\n\t\t\t\t3B72C235C1AB8944333C2322F08B6B46 /* SDWebImageTransition.m in Sources */,\n\t\t\t\tC55A2D001850D3F407D968CFF1C545E2 /* UIButton+WebCache.m in Sources */,\n\t\t\t\tAE89C60F9CD4D6E1400DD304CE2A2B9E /* UIColor+SDHexString.m in Sources */,\n\t\t\t\tBCB7B61DB37BA3EDB8CBBF258DC66446 /* UIImage+ExtendedCacheData.m in Sources */,\n\t\t\t\tF497CD01EF6568475FD363A248D78A4B /* UIImage+ForceDecode.m in Sources */,\n\t\t\t\tDEE74CD0E78DE0DB4056A8A3244B6ED1 /* UIImage+GIF.m in Sources */,\n\t\t\t\t412EE262DCED176A73591124DBDBA97C /* UIImage+MemoryCacheCost.m in Sources */,\n\t\t\t\t28532908E40E423052AA43B0000028BF /* UIImage+Metadata.m in Sources */,\n\t\t\t\t5B3271A67137276C4B2CD554BAB9F4DA /* UIImage+MultiFormat.m in Sources */,\n\t\t\t\tBF9A6E2CB8F67686C4B7E04538664919 /* UIImage+Transform.m in Sources */,\n\t\t\t\tC4762BD85B320B9EBE199F7CDFBCED12 /* UIImageView+HighlightedWebCache.m in Sources */,\n\t\t\t\t10E9E4249C8C22A571EBFECF3C0676CC /* UIImageView+WebCache.m in Sources */,\n\t\t\t\tA3BFF0CDB72BC173BEA1C8ADDBDB0D1D /* UIView+WebCache.m in Sources */,\n\t\t\t\t429E5CC928985357D07058FDEE8069FA /* UIView+WebCacheOperation.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6C798BFA74D7509FE9165B55DD4F7984 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t11A2D8485890983668BBBDB3BE7602AC /* GoogleUtilities-dummy.m in Sources */,\n\t\t\t\t685481CA7A154E8AAE00089FC07BDC74 /* GULAppDelegateSwizzler.m in Sources */,\n\t\t\t\tB3580A5C39E7E3B32DE3AC015B6DA74A /* GULAppEnvironmentUtil.m in Sources */,\n\t\t\t\t06A3ABB4421B935533DD7D039442ADCF /* GULHeartbeatDateStorage.m in Sources */,\n\t\t\t\tAF8528758C11B8B5E020066DE3EF45B8 /* GULHeartbeatDateStorageUserDefaults.m in Sources */,\n\t\t\t\tA20FADF8B2F5E792711B7E906B93E692 /* GULKeychainStorage.m in Sources */,\n\t\t\t\tFB0E00B080CD4EE84EF1BF65C47F3185 /* GULKeychainUtils.m in Sources */,\n\t\t\t\t74B90EA2A2E4ADC58C8693B6FB534D85 /* GULLogger.m in Sources */,\n\t\t\t\t3CDE39AF868FA2AFB18B9739A7F71A7F /* GULMutableDictionary.m in Sources */,\n\t\t\t\t7975CB02E10D105FA23A30B254C25F4F /* GULNetwork.m in Sources */,\n\t\t\t\tDD9CF5BA0F1AF0448E29B8E7FE427C20 /* GULNetworkConstants.m in Sources */,\n\t\t\t\tEE207039B394C5D8BBA475814B4E9830 /* GULNetworkURLSession.m in Sources */,\n\t\t\t\tB233AA226EBC0EB5843452893330638B /* GULNSData+zlib.m in Sources */,\n\t\t\t\t87EE04B662C6A6A6E3731E657170FBB8 /* GULReachabilityChecker.m in Sources */,\n\t\t\t\tD1D3F45D15F5C5775073C7747ED94B55 /* GULSceneDelegateSwizzler.m in Sources */,\n\t\t\t\t8D374E688F039AFD9D5F03C0A24DC4B6 /* GULSecureCoding.m in Sources */,\n\t\t\t\tF4310C2EF76937100D2C74EBB593BFC4 /* GULSwizzler.m in Sources */,\n\t\t\t\tF2EC479E66AABB97FBFB289846C339EF /* GULURLSessionDataResponse.m in Sources */,\n\t\t\t\t85DBD9AB9CEC227EB078B8EC52906809 /* GULUserDefaults.m in Sources */,\n\t\t\t\t4AD40F5B3B6CBC790C65872ACCC69B0B /* NSURLSession+GULPromises.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tA8FBB3E0FEA1E4F406E6833EF981197D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tB696C829F99E67EEF6DF2D6048F1EE28 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEF17DB58C7BE9A3304D466EF87041014 /* FIRCoreDiagnostics.m in Sources */,\n\t\t\t\t421ADEBE65337F1EB365DD161EBAC21C /* firebasecore.nanopb.c in Sources */,\n\t\t\t\tDE2AB52CD8EFC8E819452F737447F4B0 /* FirebaseCoreDiagnostics-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tBB25ABCA5E3180D0B10028570ACE7E37 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tAE1F2017E0DEFDFDFA2143A647D2BC15 /* Pods-Spotify-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC11285BF080C3F0235B5C0730640FD1C /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t044993D3D534546E1F168C7CABEFD382 /* FIRCurrentDateProvider.m in Sources */,\n\t\t\t\t694921E04F46359CCC4C2A3DF0ADBD04 /* FirebaseInstallations-dummy.m in Sources */,\n\t\t\t\tACFBB1893DBF761BB053683178D43A45 /* FIRInstallations.m in Sources */,\n\t\t\t\tD0C26B55798A5A3824920D1D426AEE51 /* FIRInstallationsAPIService.m in Sources */,\n\t\t\t\t0C8BD39D8D79C1A9BEFC904C457DCE89 /* FIRInstallationsAuthTokenResult.m in Sources */,\n\t\t\t\t5331944436C43951CC5FA7788DEE9BCF /* FIRInstallationsBackoffController.m in Sources */,\n\t\t\t\tF2B107BBDDF18E390CE5F31FEAC37B5B /* FIRInstallationsErrorUtil.m in Sources */,\n\t\t\t\tD9CFDF531DF1146A1A3E694A360CB0A7 /* FIRInstallationsHTTPError.m in Sources */,\n\t\t\t\tB48E2B8546BDCA558F808B1CB4849CEF /* FIRInstallationsIDController.m in Sources */,\n\t\t\t\t4844A5C12A400CAABFD7CF2283FDAEAC /* FIRInstallationsIIDStore.m in Sources */,\n\t\t\t\t83F5B3ABAFBB47CDA2E64D9C879F2167 /* FIRInstallationsIIDTokenStore.m in Sources */,\n\t\t\t\t05133941F28BBE0615644D0AFEC73AF3 /* FIRInstallationsItem.m in Sources */,\n\t\t\t\t2AF06216CDA7D6C38831BB201F73B566 /* FIRInstallationsItem+RegisterInstallationAPI.m in Sources */,\n\t\t\t\t2CC0D5EBD928AAABF1DB1AE58E8710B3 /* FIRInstallationsLogger.m in Sources */,\n\t\t\t\t4795853F6479422BFD716A20342E99EB /* FIRInstallationsSingleOperationPromiseCache.m in Sources */,\n\t\t\t\tD4D727FEE4399BCF942F3512A383917B /* FIRInstallationsStore.m in Sources */,\n\t\t\t\t5F1DA411EF4EF25F7278116F9DBD8FB8 /* FIRInstallationsStoredAuthToken.m in Sources */,\n\t\t\t\t0C80C3D7BC320914043FB768C88C8587 /* FIRInstallationsStoredItem.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tE1D3B401B4C2E4B3A4F768E6DA5C8F14 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC6C08B108C2F5D3E6828AFC268E87341 /* FIRAnalyticsConfiguration.m in Sources */,\n\t\t\t\t03C3E562593A65D5184DAE4A6DDD883F /* FIRApp.m in Sources */,\n\t\t\t\tC14230A8434F2DC9A5100B4DF5EDA4B4 /* FIRAppAssociationRegistration.m in Sources */,\n\t\t\t\t9B9D9E2182957C42538AD42CF824823B /* FIRBundleUtil.m in Sources */,\n\t\t\t\t55770A7793FDC52677664F24B19FC7C6 /* FIRComponent.m in Sources */,\n\t\t\t\t8B6E3CBB15DD0345506BCEA811AEAA43 /* FIRComponentContainer.m in Sources */,\n\t\t\t\t74849A92CED98D844690D9779D6F6DD1 /* FIRComponentType.m in Sources */,\n\t\t\t\t67B3965694762B918FFBF665F842D881 /* FIRConfiguration.m in Sources */,\n\t\t\t\t3098423E501E28F376604CE13D8CD5E0 /* FIRCoreDiagnosticsConnector.m in Sources */,\n\t\t\t\t0CC10185DD0B362B0934EDE2C557D7E0 /* FIRDependency.m in Sources */,\n\t\t\t\t052F793DE768D1EDB5C1EC87A5A21F58 /* FIRDiagnosticsData.m in Sources */,\n\t\t\t\t2C4D5AB870A681E4EA5340FBD70FA010 /* FirebaseCore-dummy.m in Sources */,\n\t\t\t\tFA24FF48B63577BA0DC691E35C9F7FA9 /* FIRFirebaseUserAgent.m in Sources */,\n\t\t\t\tBE141B44BBCE0650A03846E0D38F86EC /* FIRHeartbeatInfo.m in Sources */,\n\t\t\t\t84F3CB5D0530A295C9D23F675A5904B5 /* FIRLogger.m in Sources */,\n\t\t\t\tF595C8E6D01D6FFEC46D540A198AD062 /* FIROptions.m in Sources */,\n\t\t\t\t6CFA7E848AADCF3237F5D70EB4019775 /* FIRVersion.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t018BD7B2414A119D291C56A682084ECF /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = SDWebImage;\n\t\t\ttarget = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */;\n\t\t\ttargetProxy = 179483F0AEF1C518BA00B35B81A30639 /* PBXContainerItemProxy */;\n\t\t};\n\t\t05418E3E8DB5758F81B68AA1AFE84497 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCore;\n\t\t\ttarget = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */;\n\t\t\ttargetProxy = B16C5D96A221C36E30318D4000EF80F2 /* PBXContainerItemProxy */;\n\t\t};\n\t\t07F7AACA5DCE705327010DA25FBEF165 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCore;\n\t\t\ttarget = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */;\n\t\t\ttargetProxy = 5A2B9082AADF585B09978FD211A672E2 /* PBXContainerItemProxy */;\n\t\t};\n\t\t0F96D323478F9DB4B93A3015A06674B7 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 5ED9D700A988839F2AED6A8424F05591 /* PBXContainerItemProxy */;\n\t\t};\n\t\t0FCFAC8662107973C6B3833F8221E054 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = Firebase;\n\t\t\ttarget = 072CEA044D2EF26F03496D5996BBF59F /* Firebase */;\n\t\t\ttargetProxy = D34555543663478CC798C373DD6F3097 /* PBXContainerItemProxy */;\n\t\t};\n\t\t12F6562F185F60896BBCDADD4019778E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = nanopb;\n\t\t\ttarget = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */;\n\t\t\ttargetProxy = 3068F1E435C57EA32BE211ECBD073BC6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t13B6A2818085404337546918562D2A58 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = Appirater;\n\t\t\ttarget = CE9FA8ACD6205C77B753798CD736FAEF /* Appirater */;\n\t\t\ttargetProxy = 4AE8370CEECA1D1E24DE01B095051767 /* PBXContainerItemProxy */;\n\t\t};\n\t\t17945370CE1B53AF222677EE98E01A93 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 1EA446CB14655B63DDF173D56348CF0C /* PBXContainerItemProxy */;\n\t\t};\n\t\t1FDE3859A86742A341F1C4B4A8709B65 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseAnalytics;\n\t\t\ttarget = C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */;\n\t\t\ttargetProxy = 3EABBDC05624720577DC38CFFE35516E /* PBXContainerItemProxy */;\n\t\t};\n\t\t201B11D0246FB95D4543FB6BE95EF698 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 6536CA055DA2CE1A6BC4ECCA78BE9E3D /* PBXContainerItemProxy */;\n\t\t};\n\t\t395489EFA954E16360E8BADF0B7F052F /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleAppMeasurement;\n\t\t\ttarget = B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */;\n\t\t\ttargetProxy = FDD63A1FAEDABC2F1E1949DCC5AF3165 /* PBXContainerItemProxy */;\n\t\t};\n\t\t4CF797E9B128427F0965C0BC52003A00 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 13D9CFCD8B7BD73E7C9DE7108252C17E /* PBXContainerItemProxy */;\n\t\t};\n\t\t4D830A4469F8E53C2692049849EE1926 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = \"Appirater-Appirater\";\n\t\t\ttarget = E56E80821D169C98E99A62EBCBC60B2C /* Appirater-Appirater */;\n\t\t\ttargetProxy = 41A499968FD5AC9EAE0375E50C6432F6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t5B83E357C22146EA67403D7A55EEDE16 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = PromisesObjC;\n\t\t\ttarget = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */;\n\t\t\ttargetProxy = 75A52B3F3AF7540549FE42CCD7D77E21 /* PBXContainerItemProxy */;\n\t\t};\n\t\t60B836A00436698D56971C2DF9FACBD3 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseAnalytics;\n\t\t\ttarget = C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */;\n\t\t\ttargetProxy = 299349E1BCD52B21826853337CF6A1C4 /* PBXContainerItemProxy */;\n\t\t};\n\t\t77FE8B60CDB8A7EE71694A946F1D253A /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCore;\n\t\t\ttarget = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */;\n\t\t\ttargetProxy = ECA56526923E8FA4E91B31255FA8A6C0 /* PBXContainerItemProxy */;\n\t\t};\n\t\t7A7789E4FA83CCD3B641714A3466F165 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseInstallations;\n\t\t\ttarget = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */;\n\t\t\ttargetProxy = BC0ECFA70CF24D5AD9BA339E3D2F9476 /* PBXContainerItemProxy */;\n\t\t};\n\t\t7AFDA11FCD515215D24F9BDC345530D3 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseInstallations;\n\t\t\ttarget = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */;\n\t\t\ttargetProxy = 8C5626444E1A84EEEC6B1F447CDC3835 /* PBXContainerItemProxy */;\n\t\t};\n\t\t7DA3592F4AED73F685BA39AED564AB8C /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 2F4219A4D7ABBC820468F9119F658E52 /* PBXContainerItemProxy */;\n\t\t};\n\t\t7E29F90F20C2FBF0E612ED469B18B7F8 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 019A23FE239BD69A9982DFBA9D477A03 /* PBXContainerItemProxy */;\n\t\t};\n\t\t85FEAC43D8F304E679980E6B43979D20 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = nanopb;\n\t\t\ttarget = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */;\n\t\t\ttargetProxy = 42781FFD2FA1F2EDE97339A0136EDCD2 /* PBXContainerItemProxy */;\n\t\t};\n\t\t8AA30AE8AB0BFA17B7E024F8E7E96BDC /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = PromisesObjC;\n\t\t\ttarget = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */;\n\t\t\ttargetProxy = 4605540DE00C391F1995371BAF739423 /* PBXContainerItemProxy */;\n\t\t};\n\t\t951408F8CDF7F8851879BBD03CA335CB /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = nanopb;\n\t\t\ttarget = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */;\n\t\t\ttargetProxy = A977FEFABC64BF1427A465B2BB858E38 /* PBXContainerItemProxy */;\n\t\t};\n\t\t978C41BEAC6DA5656985B8AC107682DF /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleUtilities;\n\t\t\ttarget = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */;\n\t\t\ttargetProxy = 64BB0EA73EC74FA5D442D982996CEE10 /* PBXContainerItemProxy */;\n\t\t};\n\t\tA1161D8622C2DC03EAB4D7D9F4C33503 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = nanopb;\n\t\t\ttarget = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */;\n\t\t\ttargetProxy = 1CA617FF6BC13C778A37FCD64EB5171C /* PBXContainerItemProxy */;\n\t\t};\n\t\tA8C51E5D5646759D40788B521985C440 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleDataTransport;\n\t\t\ttarget = 5C0371EE948D0357B8EE0E34ABB44BF0 /* GoogleDataTransport */;\n\t\t\ttargetProxy = D09E65E94D05A8E445515725C350BE0D /* PBXContainerItemProxy */;\n\t\t};\n\t\tAFE857B2C1F21EEB8EB7DD94E4956E90 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCoreDiagnostics;\n\t\t\ttarget = 620E05868772C10B4920DC7E324F2C87 /* FirebaseCoreDiagnostics */;\n\t\t\ttargetProxy = 0CCABEB11C23BF29F6C694531602F292 /* PBXContainerItemProxy */;\n\t\t};\n\t\tB08F1C872AAD239599E5E808A891DE1E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleDataTransport;\n\t\t\ttarget = 5C0371EE948D0357B8EE0E34ABB44BF0 /* GoogleDataTransport */;\n\t\t\ttargetProxy = E01CEC52D49138FF303416CCAC27428F /* PBXContainerItemProxy */;\n\t\t};\n\t\tC229E2B3E24D709FC76B001754EFA1EF /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCoreDiagnostics;\n\t\t\ttarget = 620E05868772C10B4920DC7E324F2C87 /* FirebaseCoreDiagnostics */;\n\t\t\ttargetProxy = 4AF8ADE52426F73572B9DCF5DAF9E166 /* PBXContainerItemProxy */;\n\t\t};\n\t\tCB5398E5AA2AE6280A5A199E1C1B4DC6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = PromisesObjC;\n\t\t\ttarget = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */;\n\t\t\ttargetProxy = E36D5F0B788F0DF60B17237B05CF025C /* PBXContainerItemProxy */;\n\t\t};\n\t\tD4BF4589DADC31160B77BB8112E61B37 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = nanopb;\n\t\t\ttarget = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */;\n\t\t\ttargetProxy = 66522F2C26FB2DA91D7F26867BBFD45D /* PBXContainerItemProxy */;\n\t\t};\n\t\tE57689F1671B9303E2E6FC780D60D89A /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = GoogleAppMeasurement;\n\t\t\ttarget = B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */;\n\t\t\ttargetProxy = 107F5D2853F4AAFB42A81181FDB1E1DD /* PBXContainerItemProxy */;\n\t\t};\n\t\tE7A21F113AF491DD9E75451709813C86 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = FirebaseCore;\n\t\t\ttarget = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */;\n\t\t\ttargetProxy = 017C8F825B2F93FFCB2F173D75B0623D /* PBXContainerItemProxy */;\n\t\t};\n\t\tF71CBD8551E56023AD9C7EC515E0F71C /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = PromisesObjC;\n\t\t\ttarget = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */;\n\t\t\ttargetProxy = FF55F8919770C873139545DDB9B82E39 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t00403A510F1318D67AA55C1B4DCB17FB /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = FC6A0016A0D695FE4F0D2BCB7B58E53B /* SDWebImage.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/SDWebImage/SDWebImage-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/SDWebImage/SDWebImage-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/SDWebImage/SDWebImage.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = SDWebImage;\n\t\t\t\tPRODUCT_NAME = SDWebImage;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t0C87BBC2FC7A3B2EE909C0E531227BDB /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = CE9EF082FAA32B5B2D0B0C7CC14C11E6 /* Appirater.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/Appirater/Appirater-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Appirater/Appirater-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Appirater/Appirater.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = Appirater;\n\t\t\t\tPRODUCT_NAME = Appirater;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t0D9DB464E7E8F78ACFF191182E388FEC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = F582A3CDAC1DDA3FCEA8CB2C13293A4D /* Firebase.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t12221EC8440A840E28E5CC199D922CA0 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = B74D76E7DA492E2DD4E2C7CE3A5874F9 /* Appirater.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/Appirater/Appirater-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Appirater/Appirater-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Appirater/Appirater.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = Appirater;\n\t\t\t\tPRODUCT_NAME = Appirater;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t134E3B546F96D2583CC628D41DBDB180 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 4D06A1E8D589DEE651EA569B253B9DA6 /* GoogleUtilities.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/GoogleUtilities/GoogleUtilities.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = GoogleUtilities;\n\t\t\t\tPRODUCT_NAME = GoogleUtilities;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t1D34E69BAFE3E030F9A2D5B95C86A102 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C5674D03956C9BD31033CABEEFE4F2E1 /* PromisesObjC.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/PromisesObjC/PromisesObjC-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/PromisesObjC/PromisesObjC.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FBLPromises;\n\t\t\t\tPRODUCT_NAME = FBLPromises;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t1DAF018696B7F8174780EDABB5475B36 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = B526E38BA63C966AF02EA09F26802535 /* PromisesObjC.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/PromisesObjC/PromisesObjC-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/PromisesObjC/PromisesObjC.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FBLPromises;\n\t\t\t\tPRODUCT_NAME = FBLPromises;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t28EC231B69D7402FF9B7D4F4C4D0F3C8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 02EBCB4694F493398B30D145521759BB /* Pods-Spotify.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = NO;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Pods-Spotify/Pods-Spotify-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.4;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Pods-Spotify/Pods-Spotify.modulemap\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tOTHER_LIBTOOLFLAGS = \"\";\n\t\t\t\tPODS_ROOT = \"$(SRCROOT)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D52ABB3E2BF011FFF739456894CD19F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = BE37397A0A9B84C77A7B34A9406A3952 /* GoogleDataTransport.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/GoogleDataTransport/GoogleDataTransport-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/GoogleDataTransport/GoogleDataTransport.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = GoogleDataTransport;\n\t\t\t\tPRODUCT_NAME = GoogleDataTransport;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t332926E851FE7305012BBEC55FFC5AEF /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = B74D76E7DA492E2DD4E2C7CE3A5874F9 /* Appirater.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tCONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Appirater\";\n\t\t\t\tIBSC_MODULE = Appirater;\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Appirater/ResourceBundle-Appirater-Appirater-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tPRODUCT_NAME = Appirater;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tWRAPPER_EXTENSION = bundle;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t48EC2697B4F9A66BC24175655B4A998F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = AA8BA4718A81C87F777362D613444D44 /* Firebase.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4E3EE982B78A1A75CC6801762E8BE464 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C52C466DF84E99205E54E0AEC7DF14B2 /* FirebaseCoreDiagnostics.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseCoreDiagnostics;\n\t\t\t\tPRODUCT_NAME = FirebaseCoreDiagnostics;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546A2D53BEC6F376A6E2D211570B5396 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 83D038C4E24C71BFAE211A6E0CDA58BA /* nanopb.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/nanopb/nanopb-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/nanopb/nanopb-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/nanopb/nanopb.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = nanopb;\n\t\t\t\tPRODUCT_NAME = nanopb;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t58F714734C27F841BF6B29B3CCDA724A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 8B4E22AE507DF453D28673AD92339EB1 /* FirebaseInstallations.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseInstallations;\n\t\t\t\tPRODUCT_NAME = FirebaseInstallations;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t5A47CD60E027340722BF16BAD14FC1C4 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 4E43BB424620088D2FC848F87869992C /* FirebaseInstallations.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseInstallations;\n\t\t\t\tPRODUCT_NAME = FirebaseInstallations;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t5F4590E8E717F8F4D96D01E8C70174C2 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 27EFCAB3E6A3DE572444045971D498C5 /* GoogleAppMeasurement.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6DDFA8139140EA62C563D6E8645B44CF /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = FAE1DA94ED4CE423E2B4A57176826E98 /* FirebaseAnalytics.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t71243899B61152433AAE34EE86456EE7 /* 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_LOCALIZABILITY_NONLOCALIZED = YES;\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++14\";\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_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"POD_CONFIGURATION_RELEASE=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 = 14.4;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSTRIP_INSTALLED_PRODUCT = NO;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tSYMROOT = \"${SRCROOT}/../build\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t748047E47075D6AC3282B32DDE15B438 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = BA393B4B24C719DDDC878C0A08B2D1BB /* GoogleDataTransport.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/GoogleDataTransport/GoogleDataTransport-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/GoogleDataTransport/GoogleDataTransport.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = GoogleDataTransport;\n\t\t\t\tPRODUCT_NAME = GoogleDataTransport;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t75D70EEEA0A456E14F7338A7F342964E /* 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_LOCALIZABILITY_NONLOCALIZED = YES;\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++14\";\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\"POD_CONFIGURATION_DEBUG=1\",\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 = 14.4;\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\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSTRIP_INSTALLED_PRODUCT = NO;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tSYMROOT = \"${SRCROOT}/../build\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7678840E7DB9D444CD0C242F0787F45D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 695ADBFC9C4D04D17897085D1ABBBAA7 /* GoogleAppMeasurement.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7A93960A243AF7227E8EBFB56CD4EAA7 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 2368DD7767138A73CD7D9EADED904481 /* FirebaseCore.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseCore/FirebaseCore-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseCore/FirebaseCore.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseCore;\n\t\t\t\tPRODUCT_NAME = FirebaseCore;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tAF21AE07DDE4F10D240706F04AD4567F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = ACE81B64A65F8AF15E7C822CDF6A73E6 /* FirebaseCore.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseCore/FirebaseCore-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseCore/FirebaseCore.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseCore;\n\t\t\t\tPRODUCT_NAME = FirebaseCore;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tB0A83E2B33F87D1C7856C6DF93404465 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 32073165CB0BA8A73E608799A7994586 /* SDWebImage.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/SDWebImage/SDWebImage-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/SDWebImage/SDWebImage-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/SDWebImage/SDWebImage.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = SDWebImage;\n\t\t\t\tPRODUCT_NAME = SDWebImage;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tDA067B3AF66E86FD25FFB915E435453E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = CE9EF082FAA32B5B2D0B0C7CC14C11E6 /* Appirater.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tCONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Appirater\";\n\t\t\t\tIBSC_MODULE = Appirater;\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Appirater/ResourceBundle-Appirater-Appirater-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tPRODUCT_NAME = Appirater;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tWRAPPER_EXTENSION = bundle;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tDFD5C00CB965B63CB8D2E4C518CF8B54 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = DD050D11898BDC1AE3F6FC357A319586 /* FirebaseCoreDiagnostics.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = FirebaseCoreDiagnostics;\n\t\t\t\tPRODUCT_NAME = FirebaseCoreDiagnostics;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tE468F7D6C45D35D750FB1213735ABBD5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C5E56AF681704D05296BF6544BFD6DBC /* nanopb.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_PREFIX_HEADER = \"Target Support Files/nanopb/nanopb-prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/nanopb/nanopb-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/nanopb/nanopb.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = nanopb;\n\t\t\t\tPRODUCT_NAME = nanopb;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tE83625FA8D055DEE663B783F0918F038 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 04119D68F2961D5912F24F5066E00D0D /* FirebaseAnalytics.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEB2683577A50A4F30A82DDF33DFE8068 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = D934FF1B0DBCF555CAF470E0CF5AA900 /* GoogleUtilities.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/GoogleUtilities/GoogleUtilities.modulemap\";\n\t\t\t\tPRODUCT_MODULE_NAME = GoogleUtilities;\n\t\t\t\tPRODUCT_NAME = GoogleUtilities;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) \";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tECD847006548A7DD0D41165F6B50CA85 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 20DAC9944D4D96AD4E142D77D43D9F68 /* Pods-Spotify.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = NO;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Pods-Spotify/Pods-Spotify-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.4;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Pods-Spotify/Pods-Spotify.modulemap\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tOTHER_LIBTOOLFLAGS = \"\";\n\t\t\t\tPODS_ROOT = \"$(SRCROOT)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t252336D783BCD0B4415B0521B0962F14 /* Build configuration list for PBXAggregateTarget \"FirebaseAnalytics\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tE83625FA8D055DEE663B783F0918F038 /* Debug */,\n\t\t\t\t6DDFA8139140EA62C563D6E8645B44CF /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2C558C338876A0E05F2989B002E36AF0 /* Build configuration list for PBXNativeTarget \"GoogleUtilities\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEB2683577A50A4F30A82DDF33DFE8068 /* Debug */,\n\t\t\t\t134E3B546F96D2583CC628D41DBDB180 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t46F0398C816ED3AA63BC7D085DC1F978 /* Build configuration list for PBXNativeTarget \"PromisesObjC\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t1D34E69BAFE3E030F9A2D5B95C86A102 /* Debug */,\n\t\t\t\t1DAF018696B7F8174780EDABB5475B36 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject \"Pods\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t75D70EEEA0A456E14F7338A7F342964E /* Debug */,\n\t\t\t\t71243899B61152433AAE34EE86456EE7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t9F539D1E2A2664475FDEEE8A0269B722 /* Build configuration list for PBXNativeTarget \"GoogleDataTransport\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t748047E47075D6AC3282B32DDE15B438 /* Debug */,\n\t\t\t\t2D52ABB3E2BF011FFF739456894CD19F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tA48EEF29879720928C371CC9994578C8 /* Build configuration list for PBXNativeTarget \"Appirater-Appirater\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t332926E851FE7305012BBEC55FFC5AEF /* Debug */,\n\t\t\t\tDA067B3AF66E86FD25FFB915E435453E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tAE99F33A27C881BD800348FEEB1F30ED /* Build configuration list for PBXNativeTarget \"Appirater\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t12221EC8440A840E28E5CC199D922CA0 /* Debug */,\n\t\t\t\t0C87BBC2FC7A3B2EE909C0E531227BDB /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tB703E077B86E18E406CBE29C0DBD8D5F /* Build configuration list for PBXAggregateTarget \"GoogleAppMeasurement\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7678840E7DB9D444CD0C242F0787F45D /* Debug */,\n\t\t\t\t5F4590E8E717F8F4D96D01E8C70174C2 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tBABD4A24CFCBE5B6FE4680AA062FCF04 /* Build configuration list for PBXNativeTarget \"SDWebImage\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tB0A83E2B33F87D1C7856C6DF93404465 /* Debug */,\n\t\t\t\t00403A510F1318D67AA55C1B4DCB17FB /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC6E4A38F24896DABC7A364E6DB2C7A7F /* Build configuration list for PBXAggregateTarget \"Firebase\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t48EC2697B4F9A66BC24175655B4A998F /* Debug */,\n\t\t\t\t0D9DB464E7E8F78ACFF191182E388FEC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tDE2E2EB059407E49369C43F9C869DE26 /* Build configuration list for PBXNativeTarget \"nanopb\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546A2D53BEC6F376A6E2D211570B5396 /* Debug */,\n\t\t\t\tE468F7D6C45D35D750FB1213735ABBD5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tE8B9EEC407F92382DE95FD8E4661E000 /* Build configuration list for PBXNativeTarget \"FirebaseInstallations\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t5A47CD60E027340722BF16BAD14FC1C4 /* Debug */,\n\t\t\t\t58F714734C27F841BF6B29B3CCDA724A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEECB93EB4A16F755B006CF1CB0DE9A22 /* Build configuration list for PBXNativeTarget \"FirebaseCore\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tAF21AE07DDE4F10D240706F04AD4567F /* Debug */,\n\t\t\t\t7A93960A243AF7227E8EBFB56CD4EAA7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF1704FE42FCDBE50057E175108258411 /* Build configuration list for PBXNativeTarget \"FirebaseCoreDiagnostics\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4E3EE982B78A1A75CC6801762E8BE464 /* Debug */,\n\t\t\t\tDFD5C00CB965B63CB8D2E4C518CF8B54 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF9932C06D533E1975770B00862F43DBE /* Build configuration list for PBXNativeTarget \"Pods-Spotify\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t28EC231B69D7402FF9B7D4F4C4D0F3C8 /* Debug */,\n\t\t\t\tECD847006548A7DD0D41165F6B50CA85 /* 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 = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n}\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/Appirater-Appirater.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"E56E80821D169C98E99A62EBCBC60B2C\"\n               BuildableName = \"Appirater.bundle\"\n               BlueprintName = \"Appirater-Appirater\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/Appirater.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"CE9FA8ACD6205C77B753798CD736FAEF\"\n               BuildableName = \"Appirater.framework\"\n               BlueprintName = \"Appirater\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/Firebase.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"072CEA044D2EF26F03496D5996BBF59F\"\n               BuildableName = \"Firebase\"\n               BlueprintName = \"Firebase\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C49E7A4D59E5C8BE8DE9FB1EFB150185\"\n               BuildableName = \"FirebaseAnalytics\"\n               BlueprintName = \"FirebaseAnalytics\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/FirebaseCore.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4402AFF83DBDC4DD07E198685FDC2DF2\"\n               BuildableName = \"FirebaseCore.framework\"\n               BlueprintName = \"FirebaseCore\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/FirebaseCoreDiagnostics.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"620E05868772C10B4920DC7E324F2C87\"\n               BuildableName = \"FirebaseCoreDiagnostics.framework\"\n               BlueprintName = \"FirebaseCoreDiagnostics\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/FirebaseInstallations.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"87803597EB3F20FC46472B85392EC4FD\"\n               BuildableName = \"FirebaseInstallations.framework\"\n               BlueprintName = \"FirebaseInstallations\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"B53D977A951AFC38B21751B706C1DF83\"\n               BuildableName = \"GoogleAppMeasurement\"\n               BlueprintName = \"GoogleAppMeasurement\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/GoogleDataTransport.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"5C0371EE948D0357B8EE0E34ABB44BF0\"\n               BuildableName = \"GoogleDataTransport.framework\"\n               BlueprintName = \"GoogleDataTransport\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/GoogleUtilities.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"8D7F5D5DD528D21A72DC87ADA5B12E2D\"\n               BuildableName = \"GoogleUtilities.framework\"\n               BlueprintName = \"GoogleUtilities\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/Pods-Spotify.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"329161CB25D509AB980F6AF24CA7547D\"\n               BuildableName = \"Pods_Spotify.framework\"\n               BlueprintName = \"Pods-Spotify\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/PromisesObjC.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2BBF7206D7FAC92C82A042A99C4A98F8\"\n               BuildableName = \"FBLPromises.framework\"\n               BlueprintName = \"PromisesObjC\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/SDWebImage.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"3847153A6E5EEFB86565BA840768F429\"\n               BuildableName = \"SDWebImage.framework\"\n               BlueprintName = \"SDWebImage\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/nanopb.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"D2B5E7DCCBBFB32341D857D01211A1A3\"\n               BuildableName = \"nanopb.framework\"\n               BlueprintName = \"nanopb\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Pods/Pods.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/xcschememanagement.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>SchemeUserState</key>\n\t<dict>\n\t\t<key>Appirater-Appirater.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t\t<key>Appirater.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t\t<key>Firebase.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<key>FirebaseAnalytics.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<key>FirebaseCore.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>4</integer>\n\t\t</dict>\n\t\t<key>FirebaseCoreDiagnostics.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>5</integer>\n\t\t</dict>\n\t\t<key>FirebaseInstallations.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>6</integer>\n\t\t</dict>\n\t\t<key>GoogleAppMeasurement.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>7</integer>\n\t\t</dict>\n\t\t<key>GoogleDataTransport.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>8</integer>\n\t\t</dict>\n\t\t<key>GoogleUtilities.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>9</integer>\n\t\t</dict>\n\t\t<key>Pods-Spotify.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>11</integer>\n\t\t</dict>\n\t\t<key>PromisesObjC.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>12</integer>\n\t\t</dict>\n\t\t<key>SDWebImage.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>13</integer>\n\t\t</dict>\n\t\t<key>nanopb.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false/>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>10</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/PromisesObjC/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Pods/PromisesObjC/README.md",
    "content": "[![Apache\nLicense](https://img.shields.io/github/license/google/promises.svg)](LICENSE)\n[![Travis](https://api.travis-ci.org/google/promises.svg?branch=master)](https://travis-ci.org/google/promises)\n[![Gitter Chat](https://badges.gitter.im/google/promises.svg)](https://gitter.im/google/promises)\n\n![Platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS-blue.svg?longCache=true&style=flat)\n![Languages](https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg?longCache=true&style=flat)\n![Package Managers](https://img.shields.io/badge/supports-Bazel%20%7C%20SwiftPM%20%7C%20CocoaPods%20%7C%20Carthage-yellow.svg?longCache=true&style=flat)\n\n# Promises\n\nPromises is a modern framework that provides a synchronization construct for\nObjective-C and Swift to facilitate writing asynchronous code.\n\n*   [Introduction](g3doc/index.md)\n    *   [The problem with async\n        code](g3doc/index.md#the-problem-with-async-code)\n    *   [Promises to the rescue](g3doc/index.md#promises-to-the-rescue)\n    *   [What is a promise?](g3doc/index.md#what-is-a-promise)\n*   [Framework](g3doc/index.md#framework)\n    *   [Features](g3doc/index.md#features)\n    *   [Benchmark](g3doc/index.md#benchmark)\n*   [Getting started](g3doc/index.md#getting-started)\n    *   [Add dependency](g3doc/index.md#add-dependency)\n    *   [Import](g3doc/index.md#import)\n    *   [Adopt](g3doc/index.md#adopt)\n*   [Basics](g3doc/index.md#basics)\n    *   [Creating promises](g3doc/index.md#creating-promises)\n        *   [Async](g3doc/index.md#async)\n        *   [Do](g3doc/index.md#do)\n        *   [Pending](g3doc/index.md#pending)\n        *   [Resolved](g3doc/index.md#create-a-resolved-promise)\n    *   [Observing fulfillment](g3doc/index.md#observing-fulfillment)\n        *   [Then](g3doc/index.md#then)\n    *   [Observing rejection](g3doc/index.md#observing-rejection)\n        *   [Catch](g3doc/index.md#catch)\n*   [Extensions](g3doc/index.md#extensions)\n    *   [All](g3doc/index.md#all)\n    *   [Always](g3doc/index.md#always)\n    *   [Any](g3doc/index.md#any)\n    *   [AwaitPromise](g3doc/index.md#awaitpromise)\n    *   [Delay](g3doc/index.md#delay)\n    *   [Race](g3doc/index.md#race)\n    *   [Recover](g3doc/index.md#recover)\n    *   [Reduce](g3doc/index.md#reduce)\n    *   [Retry](g3doc/index.md#retry)\n    *   [Timeout](g3doc/index.md#timeout)\n    *   [Validate](g3doc/index.md#validate)\n    *   [Wrap](g3doc/index.md#wrap)\n*   [Advanced topics](g3doc/index.md#advanced-topics)\n    *   [Default dispatch queue](g3doc/index.md#default-dispatch-queue)\n    *   [Ownership and retain\n        cycles](g3doc/index.md#ownership-and-retain-cycles)\n    *   [Testing](g3doc/index.md#testing)\n    *   [Objective-C <-> Swift\n        interoperability](g3doc/index.md#objective-c---swift-interoperability)\n    *   [Dot-syntax in Objective-C](g3doc/index.md#dot-syntax-in-objective-c)\n*   [Anti-patterns](g3doc/index.md#anti-patterns)\n    *   [Broken chain](g3doc/index.md#broken-chain)\n    *   [Nested promises](g3doc/index.md#nested-promises)\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+All.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+All.h\"\n\n#import \"FBLPromise+Async.h\"\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (AllAdditions)\n\n+ (FBLPromise<NSArray *> *)all:(NSArray *)promises {\n  return [self onQueue:self.defaultDispatchQueue all:promises];\n}\n\n+ (FBLPromise<NSArray *> *)onQueue:(dispatch_queue_t)queue all:(NSArray *)allPromises {\n  NSParameterAssert(queue);\n  NSParameterAssert(allPromises);\n\n  if (allPromises.count == 0) {\n    return [[FBLPromise alloc] initWithResolution:@[]];\n  }\n  NSMutableArray *promises = [allPromises mutableCopy];\n  return [FBLPromise\n      onQueue:queue\n        async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n          for (NSUInteger i = 0; i < promises.count; ++i) {\n            id promise = promises[i];\n            if ([promise isKindOfClass:self]) {\n              continue;\n            } else if ([promise isKindOfClass:[NSError class]]) {\n              reject(promise);\n              return;\n            } else {\n              [promises replaceObjectAtIndex:i\n                                  withObject:[[FBLPromise alloc] initWithResolution:promise]];\n            }\n          }\n          for (FBLPromise *promise in promises) {\n            [promise observeOnQueue:queue\n                fulfill:^(id __unused _) {\n                  // Wait until all are fulfilled.\n                  for (FBLPromise *promise in promises) {\n                    if (!promise.isFulfilled) {\n                      return;\n                    }\n                  }\n                  // If called multiple times, only the first one affects the result.\n                  fulfill([promises valueForKey:NSStringFromSelector(@selector(value))]);\n                }\n                reject:^(NSError *error) {\n                  reject(error);\n                }];\n          }\n        }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_AllAdditions)\n\n+ (FBLPromise<NSArray *> * (^)(NSArray *))all {\n  return ^(NSArray<FBLPromise *> *promises) {\n    return [self all:promises];\n  };\n}\n\n+ (FBLPromise<NSArray *> * (^)(dispatch_queue_t, NSArray *))allOn {\n  return ^(dispatch_queue_t queue, NSArray<FBLPromise *> *promises) {\n    return [self onQueue:queue all:promises];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Always.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Always.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (AlwaysAdditions)\n\n- (FBLPromise *)always:(FBLPromiseAlwaysWorkBlock)work {\n  return [self onQueue:FBLPromise.defaultDispatchQueue always:work];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue always:(FBLPromiseAlwaysWorkBlock)work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self chainOnQueue:queue\n      chainedFulfill:^id(id value) {\n        work();\n        return value;\n      }\n      chainedReject:^id(NSError *error) {\n        work();\n        return error;\n      }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_AlwaysAdditions)\n\n- (FBLPromise * (^)(FBLPromiseAlwaysWorkBlock))always {\n  return ^(FBLPromiseAlwaysWorkBlock work) {\n    return [self always:work];\n  };\n}\n\n- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseAlwaysWorkBlock))alwaysOn {\n  return ^(dispatch_queue_t queue, FBLPromiseAlwaysWorkBlock work) {\n    return [self onQueue:queue always:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Any.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Any.h\"\n\n#import \"FBLPromise+Async.h\"\n#import \"FBLPromisePrivate.h\"\n\nstatic NSArray *FBLPromiseCombineValuesAndErrors(NSArray<FBLPromise *> *promises) {\n  NSMutableArray *combinedValuesAndErrors = [[NSMutableArray alloc] init];\n  for (FBLPromise *promise in promises) {\n    if (promise.isFulfilled) {\n      [combinedValuesAndErrors addObject:promise.value ?: [NSNull null]];\n      continue;\n    }\n    if (promise.isRejected) {\n      [combinedValuesAndErrors addObject:promise.error];\n      continue;\n    }\n    assert(!promise.isPending);\n  };\n  return combinedValuesAndErrors;\n}\n\n@implementation FBLPromise (AnyAdditions)\n\n+ (FBLPromise<NSArray *> *)any:(NSArray *)promises {\n  return [self onQueue:FBLPromise.defaultDispatchQueue any:promises];\n}\n\n+ (FBLPromise<NSArray *> *)onQueue:(dispatch_queue_t)queue any:(NSArray *)anyPromises {\n  NSParameterAssert(queue);\n  NSParameterAssert(anyPromises);\n\n  if (anyPromises.count == 0) {\n    return [[FBLPromise alloc] initWithResolution:@[]];\n  }\n  NSMutableArray *promises = [anyPromises mutableCopy];\n  return [FBLPromise\n      onQueue:queue\n        async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n          for (NSUInteger i = 0; i < promises.count; ++i) {\n            id promise = promises[i];\n            if ([promise isKindOfClass:self]) {\n              continue;\n            } else {\n              [promises replaceObjectAtIndex:i\n                                  withObject:[[FBLPromise alloc] initWithResolution:promise]];\n            }\n          }\n          for (FBLPromise *promise in promises) {\n            [promise observeOnQueue:queue\n                fulfill:^(id __unused _) {\n                  // Wait until all are resolved.\n                  for (FBLPromise *promise in promises) {\n                    if (promise.isPending) {\n                      return;\n                    }\n                  }\n                  // If called multiple times, only the first one affects the result.\n                  fulfill(FBLPromiseCombineValuesAndErrors(promises));\n                }\n                reject:^(NSError *error) {\n                  BOOL atLeastOneIsFulfilled = NO;\n                  for (FBLPromise *promise in promises) {\n                    if (promise.isPending) {\n                      return;\n                    }\n                    if (promise.isFulfilled) {\n                      atLeastOneIsFulfilled = YES;\n                    }\n                  }\n                  if (atLeastOneIsFulfilled) {\n                    fulfill(FBLPromiseCombineValuesAndErrors(promises));\n                  } else {\n                    reject(error);\n                  }\n                }];\n          }\n        }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_AnyAdditions)\n\n+ (FBLPromise<NSArray *> * (^)(NSArray *))any {\n  return ^(NSArray *promises) {\n    return [self any:promises];\n  };\n}\n\n+ (FBLPromise<NSArray *> * (^)(dispatch_queue_t, NSArray *))anyOn {\n  return ^(dispatch_queue_t queue, NSArray *promises) {\n    return [self onQueue:queue any:promises];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Async.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Async.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (AsyncAdditions)\n\n+ (instancetype)async:(FBLPromiseAsyncWorkBlock)work {\n  return [self onQueue:self.defaultDispatchQueue async:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue async:(FBLPromiseAsyncWorkBlock)work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{\n    work(\n        ^(id __nullable value) {\n          if ([value isKindOfClass:[FBLPromise class]]) {\n            [(FBLPromise *)value observeOnQueue:queue\n                fulfill:^(id __nullable value) {\n                  [promise fulfill:value];\n                }\n                reject:^(NSError *error) {\n                  [promise reject:error];\n                }];\n          } else {\n            [promise fulfill:value];\n          }\n        },\n        ^(NSError *error) {\n          [promise reject:error];\n        });\n  });\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_AsyncAdditions)\n\n+ (FBLPromise* (^)(FBLPromiseAsyncWorkBlock))async {\n  return ^(FBLPromiseAsyncWorkBlock work) {\n    return [self async:work];\n  };\n}\n\n+ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAsyncWorkBlock))asyncOn {\n  return ^(dispatch_queue_t queue, FBLPromiseAsyncWorkBlock work) {\n    return [self onQueue:queue async:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Await.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Await.h\"\n\n#import \"FBLPromisePrivate.h\"\n\nid __nullable FBLPromiseAwait(FBLPromise *promise, NSError **outError) {\n  assert(promise);\n\n  static dispatch_once_t onceToken;\n  static dispatch_queue_t queue;\n  dispatch_once(&onceToken, ^{\n    queue = dispatch_queue_create(\"com.google.FBLPromises.Await\", DISPATCH_QUEUE_CONCURRENT);\n  });\n  dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);\n  id __block resolution;\n  NSError __block *blockError;\n  [promise chainOnQueue:queue\n      chainedFulfill:^id(id value) {\n        resolution = value;\n        dispatch_semaphore_signal(semaphore);\n        return value;\n      }\n      chainedReject:^id(NSError *error) {\n        blockError = error;\n        dispatch_semaphore_signal(semaphore);\n        return error;\n      }];\n  dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);\n  if (outError) {\n    *outError = blockError;\n  }\n  return resolution;\n}\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Catch.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Catch.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (CatchAdditions)\n\n- (FBLPromise *)catch:(FBLPromiseCatchWorkBlock)reject {\n  return [self onQueue:FBLPromise.defaultDispatchQueue catch:reject];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue catch:(FBLPromiseCatchWorkBlock)reject {\n  NSParameterAssert(queue);\n  NSParameterAssert(reject);\n\n  return [self chainOnQueue:queue\n             chainedFulfill:nil\n              chainedReject:^id(NSError *error) {\n                reject(error);\n                return error;\n              }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_CatchAdditions)\n\n- (FBLPromise* (^)(FBLPromiseCatchWorkBlock))catch {\n  return ^(FBLPromiseCatchWorkBlock catch) {\n    return [self catch:catch];\n  };\n}\n\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseCatchWorkBlock))catchOn {\n  return ^(dispatch_queue_t queue, FBLPromiseCatchWorkBlock catch) {\n    return [self onQueue:queue catch:catch];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Delay.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Delay.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (DelayAdditions)\n\n- (FBLPromise *)delay:(NSTimeInterval)interval {\n  return [self onQueue:FBLPromise.defaultDispatchQueue delay:interval];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue delay:(NSTimeInterval)interval {\n  NSParameterAssert(queue);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  [self observeOnQueue:queue\n      fulfill:^(id __nullable value) {\n        dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{\n          [promise fulfill:value];\n        });\n      }\n      reject:^(NSError *error) {\n        [promise reject:error];\n      }];\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_DelayAdditions)\n\n- (FBLPromise * (^)(NSTimeInterval))delay {\n  return ^(NSTimeInterval interval) {\n    return [self delay:interval];\n  };\n}\n\n- (FBLPromise * (^)(dispatch_queue_t, NSTimeInterval))delayOn {\n  return ^(dispatch_queue_t queue, NSTimeInterval interval) {\n    return [self onQueue:queue delay:interval];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Do.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Do.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (DoAdditions)\n\n+ (instancetype)do:(FBLPromiseDoWorkBlock)work {\n  return [self onQueue:self.defaultDispatchQueue do:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue do:(FBLPromiseDoWorkBlock)work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{\n    id value = work();\n    if ([value isKindOfClass:[FBLPromise class]]) {\n      [(FBLPromise *)value observeOnQueue:queue\n          fulfill:^(id __nullable value) {\n            [promise fulfill:value];\n          }\n          reject:^(NSError *error) {\n            [promise reject:error];\n          }];\n    } else {\n      [promise fulfill:value];\n    }\n  });\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_DoAdditions)\n\n+ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseDoWorkBlock))doOn {\n  return ^(dispatch_queue_t queue, FBLPromiseDoWorkBlock work) {\n    return [self onQueue:queue do:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Race.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Race.h\"\n\n#import \"FBLPromise+Async.h\"\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (RaceAdditions)\n\n+ (instancetype)race:(NSArray *)promises {\n  return [self onQueue:self.defaultDispatchQueue race:promises];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue race:(NSArray *)racePromises {\n  NSParameterAssert(queue);\n  NSAssert(racePromises.count > 0, @\"No promises to observe\");\n\n  NSArray *promises = [racePromises copy];\n  return [FBLPromise onQueue:queue\n                       async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                         for (id promise in promises) {\n                           if (![promise isKindOfClass:self]) {\n                             fulfill(promise);\n                             return;\n                           }\n                         }\n                         // Subscribe all, but only the first one to resolve will change\n                         // the resulting promise's state.\n                         for (FBLPromise *promise in promises) {\n                           [promise observeOnQueue:queue fulfill:fulfill reject:reject];\n                         }\n                       }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_RaceAdditions)\n\n+ (FBLPromise * (^)(NSArray *))race {\n  return ^(NSArray *promises) {\n    return [self race:promises];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, NSArray *))raceOn {\n  return ^(dispatch_queue_t queue, NSArray *promises) {\n    return [self onQueue:queue race:promises];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Recover.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Recover.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (RecoverAdditions)\n\n- (FBLPromise *)recover:(FBLPromiseRecoverWorkBlock)recovery {\n  return [self onQueue:FBLPromise.defaultDispatchQueue recover:recovery];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue recover:(FBLPromiseRecoverWorkBlock)recovery {\n  NSParameterAssert(queue);\n  NSParameterAssert(recovery);\n\n  return [self chainOnQueue:queue\n             chainedFulfill:nil\n              chainedReject:^id(NSError *error) {\n                return recovery(error);\n              }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_RecoverAdditions)\n\n- (FBLPromise * (^)(FBLPromiseRecoverWorkBlock))recover {\n  return ^(FBLPromiseRecoverWorkBlock recovery) {\n    return [self recover:recovery];\n  };\n}\n\n- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRecoverWorkBlock))recoverOn {\n  return ^(dispatch_queue_t queue, FBLPromiseRecoverWorkBlock recovery) {\n    return [self onQueue:queue recover:recovery];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Reduce.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Reduce.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (ReduceAdditions)\n\n- (FBLPromise *)reduce:(NSArray *)items combine:(FBLPromiseReducerBlock)reducer {\n  return [self onQueue:FBLPromise.defaultDispatchQueue reduce:items combine:reducer];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                 reduce:(NSArray *)items\n                combine:(FBLPromiseReducerBlock)reducer {\n  NSParameterAssert(queue);\n  NSParameterAssert(items);\n  NSParameterAssert(reducer);\n\n  FBLPromise *promise = self;\n  for (id item in items) {\n    promise = [promise chainOnQueue:queue\n                     chainedFulfill:^id(id value) {\n                       return reducer(value, item);\n                     }\n                      chainedReject:nil];\n  }\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_ReduceAdditions)\n\n- (FBLPromise * (^)(NSArray *, FBLPromiseReducerBlock))reduce {\n  return ^(NSArray *items, FBLPromiseReducerBlock reducer) {\n    return [self reduce:items combine:reducer];\n  };\n}\n\n- (FBLPromise * (^)(dispatch_queue_t, NSArray *, FBLPromiseReducerBlock))reduceOn {\n  return ^(dispatch_queue_t queue, NSArray *items, FBLPromiseReducerBlock reducer) {\n    return [self onQueue:queue reduce:items combine:reducer];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Retry.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Retry.h\"\n\n#import \"FBLPromisePrivate.h\"\n\nNSInteger const FBLPromiseRetryDefaultAttemptsCount = 1;\nNSTimeInterval const FBLPromiseRetryDefaultDelayInterval = 1.0;\n\nstatic void FBLPromiseRetryAttempt(FBLPromise *promise, dispatch_queue_t queue, NSInteger count,\n                                   NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate,\n                                   FBLPromiseRetryWorkBlock work) {\n  __auto_type retrier = ^(id __nullable value) {\n    if ([value isKindOfClass:[NSError class]]) {\n      if (count <= 0 || (predicate && !predicate(count, value))) {\n        [promise reject:value];\n      } else {\n        dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{\n          FBLPromiseRetryAttempt(promise, queue, count - 1, interval, predicate, work);\n        });\n      }\n    } else {\n      [promise fulfill:value];\n    }\n  };\n  id value = work();\n  if ([value isKindOfClass:[FBLPromise class]]) {\n    [(FBLPromise *)value observeOnQueue:queue fulfill:retrier reject:retrier];\n  } else  {\n    retrier(value);\n  }\n}\n\n@implementation FBLPromise (RetryAdditions)\n\n+ (FBLPromise *)retry:(FBLPromiseRetryWorkBlock)work {\n  return [self onQueue:FBLPromise.defaultDispatchQueue retry:work];\n}\n\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue retry:(FBLPromiseRetryWorkBlock)work {\n  return [self onQueue:queue attempts:FBLPromiseRetryDefaultAttemptsCount retry:work];\n}\n\n+ (FBLPromise *)attempts:(NSInteger)count retry:(FBLPromiseRetryWorkBlock)work {\n  return [self onQueue:FBLPromise.defaultDispatchQueue attempts:count retry:work];\n}\n\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue\n               attempts:(NSInteger)count\n                  retry:(FBLPromiseRetryWorkBlock)work {\n  return [self onQueue:queue\n              attempts:count\n                 delay:FBLPromiseRetryDefaultDelayInterval\n             condition:nil\n                 retry:work];\n}\n\n+ (FBLPromise *)attempts:(NSInteger)count\n                   delay:(NSTimeInterval)interval\n               condition:(nullable FBLPromiseRetryPredicateBlock)predicate\n                   retry:(FBLPromiseRetryWorkBlock)work {\n  return [self onQueue:FBLPromise.defaultDispatchQueue\n              attempts:count\n                 delay:interval\n             condition:predicate\n                 retry:work];\n}\n\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue\n               attempts:(NSInteger)count\n                  delay:(NSTimeInterval)interval\n              condition:(nullable FBLPromiseRetryPredicateBlock)predicate\n                  retry:(FBLPromiseRetryWorkBlock)work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  FBLPromiseRetryAttempt(promise, queue, count, interval, predicate, work);\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_RetryAdditions)\n\n+ (FBLPromise * (^)(FBLPromiseRetryWorkBlock))retry {\n  return ^id(FBLPromiseRetryWorkBlock work) {\n    return [self retry:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRetryWorkBlock))retryOn {\n  return ^id(dispatch_queue_t queue, FBLPromiseRetryWorkBlock work) {\n    return [self onQueue:queue retry:work];\n  };\n}\n\n+ (FBLPromise * (^)(NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock,\n                    FBLPromiseRetryWorkBlock))retryAgain {\n  return ^id(NSInteger count, NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate,\n             FBLPromiseRetryWorkBlock work) {\n    return [self attempts:count delay:interval condition:predicate retry:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock,\n                    FBLPromiseRetryWorkBlock))retryAgainOn {\n  return ^id(dispatch_queue_t queue, NSInteger count, NSTimeInterval interval,\n             FBLPromiseRetryPredicateBlock predicate, FBLPromiseRetryWorkBlock work) {\n    return [self onQueue:queue attempts:count delay:interval condition:predicate retry:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Testing.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Testing.h\"\n\nBOOL FBLWaitForPromisesWithTimeout(NSTimeInterval timeout) {\n  BOOL isTimedOut = NO;\n  NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout];\n  static NSTimeInterval const minimalTimeout = 0.01;\n  static int64_t const minimalTimeToWait = (int64_t)(minimalTimeout * NSEC_PER_SEC);\n  dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, minimalTimeToWait);\n  dispatch_group_t dispatchGroup = FBLPromise.dispatchGroup;\n  NSRunLoop *runLoop = NSRunLoop.currentRunLoop;\n  while (dispatch_group_wait(dispatchGroup, waitTime)) {\n    isTimedOut = timeoutDate.timeIntervalSinceNow < 0.0;\n    if (isTimedOut) {\n      break;\n    }\n    [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:minimalTimeout]];\n  }\n  return !isTimedOut;\n}\n\n@implementation FBLPromise (TestingAdditions)\n\n// These properties are implemented in the FBLPromise class itself.\n@dynamic isPending;\n@dynamic isFulfilled;\n@dynamic isRejected;\n@dynamic value;\n@dynamic error;\n\n+ (dispatch_group_t)dispatchGroup {\n  static dispatch_group_t gDispatchGroup;\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    gDispatchGroup = dispatch_group_create();\n  });\n  return gDispatchGroup;\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Then.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Then.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (ThenAdditions)\n\n- (FBLPromise *)then:(FBLPromiseThenWorkBlock)work {\n  return [self onQueue:FBLPromise.defaultDispatchQueue then:work];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue then:(FBLPromiseThenWorkBlock)work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self chainOnQueue:queue chainedFulfill:work chainedReject:nil];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_ThenAdditions)\n\n- (FBLPromise* (^)(FBLPromiseThenWorkBlock))then {\n  return ^(FBLPromiseThenWorkBlock work) {\n    return [self then:work];\n  };\n}\n\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseThenWorkBlock))thenOn {\n  return ^(dispatch_queue_t queue, FBLPromiseThenWorkBlock work) {\n    return [self onQueue:queue then:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Timeout.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Timeout.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (TimeoutAdditions)\n\n- (FBLPromise *)timeout:(NSTimeInterval)interval {\n  return [self onQueue:FBLPromise.defaultDispatchQueue timeout:interval];\n}\n\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue timeout:(NSTimeInterval)interval {\n  NSParameterAssert(queue);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  [self observeOnQueue:queue\n      fulfill:^(id __nullable value) {\n        [promise fulfill:value];\n      }\n      reject:^(NSError *error) {\n        [promise reject:error];\n      }];\n  typeof(self) __weak weakPromise = promise;\n  dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{\n    NSError *timedOutError = [[NSError alloc] initWithDomain:FBLPromiseErrorDomain\n                                                        code:FBLPromiseErrorCodeTimedOut\n                                                    userInfo:nil];\n    [weakPromise reject:timedOutError];\n  });\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_TimeoutAdditions)\n\n- (FBLPromise* (^)(NSTimeInterval))timeout {\n  return ^(NSTimeInterval interval) {\n    return [self timeout:interval];\n  };\n}\n\n- (FBLPromise* (^)(dispatch_queue_t, NSTimeInterval))timeoutOn {\n  return ^(dispatch_queue_t queue, NSTimeInterval interval) {\n    return [self onQueue:queue timeout:interval];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Validate.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Validate.h\"\n\n#import \"FBLPromisePrivate.h\"\n\n@implementation FBLPromise (ValidateAdditions)\n\n- (FBLPromise*)validate:(FBLPromiseValidateWorkBlock)predicate {\n  return [self onQueue:FBLPromise.defaultDispatchQueue validate:predicate];\n}\n\n- (FBLPromise*)onQueue:(dispatch_queue_t)queue validate:(FBLPromiseValidateWorkBlock)predicate {\n  NSParameterAssert(queue);\n  NSParameterAssert(predicate);\n\n  FBLPromiseChainedFulfillBlock chainedFulfill = ^id(id value) {\n    return predicate(value) ? value :\n                              [[NSError alloc] initWithDomain:FBLPromiseErrorDomain\n                                                         code:FBLPromiseErrorCodeValidationFailure\n                                                     userInfo:nil];\n  };\n  return [self chainOnQueue:queue chainedFulfill:chainedFulfill chainedReject:nil];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_ValidateAdditions)\n\n- (FBLPromise* (^)(FBLPromiseValidateWorkBlock))validate {\n  return ^(FBLPromiseValidateWorkBlock predicate) {\n    return [self validate:predicate];\n  };\n}\n\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseValidateWorkBlock))validateOn {\n  return ^(dispatch_queue_t queue, FBLPromiseValidateWorkBlock predicate) {\n    return [self onQueue:queue validate:predicate];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Wrap.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Wrap.h\"\n\n#import \"FBLPromise+Async.h\"\n\n@implementation FBLPromise (WrapAdditions)\n\n+ (instancetype)wrapCompletion:(void (^)(FBLPromiseCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapCompletion:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n         wrapCompletion:(void (^)(FBLPromiseCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) {\n                   work(^{\n                     fulfill(nil);\n                   });\n                 }];\n}\n\n+ (instancetype)wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapObjectCompletion:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) {\n                   work(^(id __nullable value) {\n                     fulfill(value);\n                   });\n                 }];\n}\n\n+ (instancetype)wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapErrorCompletion:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(nil);\n                     }\n                   });\n                 }];\n}\n\n+ (instancetype)wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapObjectOrErrorCompletion:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(id __nullable value, NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(value);\n                     }\n                   });\n                 }];\n}\n\n+ (instancetype)wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapErrorOrObjectCompletion:work];\n}\n\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(NSError *__nullable error, id __nullable value) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(value);\n                     }\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSArray *> *)wrap2ObjectsOrErrorCompletion:\n    (void (^)(FBLPromise2ObjectsOrErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrap2ObjectsOrErrorCompletion:work];\n}\n\n+ (FBLPromise<NSArray *> *)onQueue:(dispatch_queue_t)queue\n     wrap2ObjectsOrErrorCompletion:(void (^)(FBLPromise2ObjectsOrErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(id __nullable value1, id __nullable value2, NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(@[ value1 ?: [NSNull null], value2 ?: [NSNull null] ]);\n                     }\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapBoolCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n                 wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) {\n                   work(^(BOOL value) {\n                     fulfill(@(value));\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapBoolOrErrorCompletion:\n    (void (^)(FBLPromiseBoolOrErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapBoolOrErrorCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n          wrapBoolOrErrorCompletion:(void (^)(FBLPromiseBoolOrErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(BOOL value, NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(@(value));\n                     }\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapIntegerCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n              wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) {\n                   work(^(NSInteger value) {\n                     fulfill(@(value));\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapIntegerOrErrorCompletion:\n    (void (^)(FBLPromiseIntegerOrErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapIntegerOrErrorCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n       wrapIntegerOrErrorCompletion:(void (^)(FBLPromiseIntegerOrErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(NSInteger value, NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(@(value));\n                     }\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapDoubleCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n               wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:(dispatch_queue_t)queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) {\n                   work(^(double value) {\n                     fulfill(@(value));\n                   });\n                 }];\n}\n\n+ (FBLPromise<NSNumber *> *)wrapDoubleOrErrorCompletion:\n    (void (^)(FBLPromiseDoubleOrErrorCompletion))work {\n  return [self onQueue:self.defaultDispatchQueue wrapDoubleOrErrorCompletion:work];\n}\n\n+ (FBLPromise<NSNumber *> *)onQueue:(dispatch_queue_t)queue\n        wrapDoubleOrErrorCompletion:(void (^)(FBLPromiseDoubleOrErrorCompletion))work {\n  NSParameterAssert(queue);\n  NSParameterAssert(work);\n\n  return [self onQueue:queue\n                 async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {\n                   work(^(double value, NSError *__nullable error) {\n                     if (error) {\n                       reject(error);\n                     } else {\n                       fulfill(@(value));\n                     }\n                   });\n                 }];\n}\n\n@end\n\n@implementation FBLPromise (DotSyntax_WrapAdditions)\n\n+ (FBLPromise * (^)(void (^)(FBLPromiseCompletion)))wrapCompletion {\n  return ^(void (^work)(FBLPromiseCompletion)) {\n    return [self wrapCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseCompletion)))wrapCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseCompletion)) {\n    return [self onQueue:queue wrapCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletion {\n  return ^(void (^work)(FBLPromiseObjectCompletion)) {\n    return [self wrapObjectCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseObjectCompletion)) {\n    return [self onQueue:queue wrapObjectCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletion {\n  return ^(void (^work)(FBLPromiseErrorCompletion)) {\n    return [self wrapErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseErrorCompletion)) {\n    return [self onQueue:queue wrapErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletion {\n  return ^(void (^work)(FBLPromiseObjectOrErrorCompletion)) {\n    return [self wrapObjectOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t,\n                    void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseObjectOrErrorCompletion)) {\n    return [self onQueue:queue wrapObjectOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletion {\n  return ^(void (^work)(FBLPromiseErrorOrObjectCompletion)) {\n    return [self wrapErrorOrObjectCompletion:work];\n  };\n}\n\n+ (FBLPromise * (^)(dispatch_queue_t,\n                    void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseErrorOrObjectCompletion)) {\n    return [self onQueue:queue wrapErrorOrObjectCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSArray *> * (^)(void (^)(FBLPromise2ObjectsOrErrorCompletion)))\n    wrap2ObjectsOrErrorCompletion {\n  return ^(void (^work)(FBLPromise2ObjectsOrErrorCompletion)) {\n    return [self wrap2ObjectsOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSArray *> * (^)(dispatch_queue_t, void (^)(FBLPromise2ObjectsOrErrorCompletion)))\n    wrap2ObjectsOrErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromise2ObjectsOrErrorCompletion)) {\n    return [self onQueue:queue wrap2ObjectsOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletion {\n  return ^(void (^work)(FBLPromiseBoolCompletion)) {\n    return [self wrapBoolCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t,\n                                void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseBoolCompletion)) {\n    return [self onQueue:queue wrapBoolCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseBoolOrErrorCompletion)))\n    wrapBoolOrErrorCompletion {\n  return ^(void (^work)(FBLPromiseBoolOrErrorCompletion)) {\n    return [self wrapBoolOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t, void (^)(FBLPromiseBoolOrErrorCompletion)))\n    wrapBoolOrErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseBoolOrErrorCompletion)) {\n    return [self onQueue:queue wrapBoolOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletion {\n  return ^(void (^work)(FBLPromiseIntegerCompletion)) {\n    return [self wrapIntegerCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t,\n                                void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseIntegerCompletion)) {\n    return [self onQueue:queue wrapIntegerCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseIntegerOrErrorCompletion)))\n    wrapIntegerOrErrorCompletion {\n  return ^(void (^work)(FBLPromiseIntegerOrErrorCompletion)) {\n    return [self wrapIntegerOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t, void (^)(FBLPromiseIntegerOrErrorCompletion)))\n    wrapIntegerOrErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseIntegerOrErrorCompletion)) {\n    return [self onQueue:queue wrapIntegerOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletion {\n  return ^(void (^work)(FBLPromiseDoubleCompletion)) {\n    return [self wrapDoubleCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t,\n                                void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseDoubleCompletion)) {\n    return [self onQueue:queue wrapDoubleCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(void (^)(FBLPromiseDoubleOrErrorCompletion)))\n    wrapDoubleOrErrorCompletion {\n  return ^(void (^work)(FBLPromiseDoubleOrErrorCompletion)) {\n    return [self wrapDoubleOrErrorCompletion:work];\n  };\n}\n\n+ (FBLPromise<NSNumber *> * (^)(dispatch_queue_t, void (^)(FBLPromiseDoubleOrErrorCompletion)))\n    wrapDoubleOrErrorCompletionOn {\n  return ^(dispatch_queue_t queue, void (^work)(FBLPromiseDoubleOrErrorCompletion)) {\n    return [self onQueue:queue wrapDoubleOrErrorCompletion:work];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromise.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromisePrivate.h\"\n\n/** All states a promise can be in. */\ntypedef NS_ENUM(NSInteger, FBLPromiseState) {\n  FBLPromiseStatePending = 0,\n  FBLPromiseStateFulfilled,\n  FBLPromiseStateRejected,\n};\n\ntypedef void (^FBLPromiseObserver)(FBLPromiseState state, id __nullable resolution);\n\nstatic dispatch_queue_t gFBLPromiseDefaultDispatchQueue;\n\n@implementation FBLPromise {\n  /** Current state of the promise. */\n  FBLPromiseState _state;\n  /**\n   Set of arbitrary objects to keep strongly while the promise is pending.\n   Becomes nil after the promise has been resolved.\n   */\n  NSMutableSet *__nullable _pendingObjects;\n  /**\n   Value to fulfill the promise with.\n   Can be nil if the promise is still pending, was resolved with nil or after it has been rejected.\n   */\n  id __nullable _value;\n  /**\n   Error to reject the promise with.\n   Can be nil if the promise is still pending or after it has been fulfilled.\n   */\n  NSError *__nullable _error;\n  /** List of observers to notify when the promise gets resolved. */\n  NSMutableArray<FBLPromiseObserver> *_observers;\n}\n\n+ (void)initialize {\n  if (self == [FBLPromise class]) {\n    gFBLPromiseDefaultDispatchQueue = dispatch_get_main_queue();\n  }\n}\n\n+ (dispatch_queue_t)defaultDispatchQueue {\n  @synchronized(self) {\n    return gFBLPromiseDefaultDispatchQueue;\n  }\n}\n\n+ (void)setDefaultDispatchQueue:(dispatch_queue_t)queue {\n  NSParameterAssert(queue);\n\n  @synchronized(self) {\n    gFBLPromiseDefaultDispatchQueue = queue;\n  }\n}\n\n+ (instancetype)pendingPromise {\n  return [[self alloc] initPending];\n}\n\n+ (instancetype)resolvedWith:(nullable id)resolution {\n  return [[self alloc] initWithResolution:resolution];\n}\n\n- (void)fulfill:(nullable id)value {\n  if ([value isKindOfClass:[NSError class]]) {\n    [self reject:(NSError *)value];\n  } else {\n    @synchronized(self) {\n      if (_state == FBLPromiseStatePending) {\n        _state = FBLPromiseStateFulfilled;\n        _value = value;\n        _pendingObjects = nil;\n        for (FBLPromiseObserver observer in _observers) {\n          observer(_state, _value);\n        }\n        _observers = nil;\n        dispatch_group_leave(FBLPromise.dispatchGroup);\n      }\n    }\n  }\n}\n\n- (void)reject:(NSError *)error {\n  NSAssert([error isKindOfClass:[NSError class]], @\"Invalid error type.\");\n\n  if (![error isKindOfClass:[NSError class]]) {\n    // Give up on invalid error type in Release mode.\n    @throw error;  // NOLINT\n  }\n  @synchronized(self) {\n    if (_state == FBLPromiseStatePending) {\n      _state = FBLPromiseStateRejected;\n      _error = error;\n      _pendingObjects = nil;\n      for (FBLPromiseObserver observer in _observers) {\n        observer(_state, _error);\n      }\n      _observers = nil;\n      dispatch_group_leave(FBLPromise.dispatchGroup);\n    }\n  }\n}\n\n#pragma mark - NSObject\n\n- (NSString *)description {\n  if (self.isFulfilled) {\n    return [NSString stringWithFormat:@\"<%@ %p> Fulfilled: %@\", NSStringFromClass([self class]),\n                                      self, self.value];\n  }\n  if (self.isRejected) {\n    return [NSString stringWithFormat:@\"<%@ %p> Rejected: %@\", NSStringFromClass([self class]),\n                                      self, self.error];\n  }\n  return [NSString stringWithFormat:@\"<%@ %p> Pending\", NSStringFromClass([self class]), self];\n}\n\n#pragma mark - Private\n\n- (instancetype)initPending {\n  self = [super init];\n  if (self) {\n    dispatch_group_enter(FBLPromise.dispatchGroup);\n  }\n  return self;\n}\n\n- (instancetype)initWithResolution:(nullable id)resolution {\n  self = [super init];\n  if (self) {\n    if ([resolution isKindOfClass:[NSError class]]) {\n      _state = FBLPromiseStateRejected;\n      _error = (NSError *)resolution;\n    } else {\n      _state = FBLPromiseStateFulfilled;\n      _value = resolution;\n    }\n  }\n  return self;\n}\n\n- (void)dealloc {\n  if (_state == FBLPromiseStatePending) {\n    dispatch_group_leave(FBLPromise.dispatchGroup);\n  }\n}\n\n- (BOOL)isPending {\n  @synchronized(self) {\n    return _state == FBLPromiseStatePending;\n  }\n}\n\n- (BOOL)isFulfilled {\n  @synchronized(self) {\n    return _state == FBLPromiseStateFulfilled;\n  }\n}\n\n- (BOOL)isRejected {\n  @synchronized(self) {\n    return _state == FBLPromiseStateRejected;\n  }\n}\n\n- (nullable id)value {\n  @synchronized(self) {\n    return _value;\n  }\n}\n\n- (NSError *__nullable)error {\n  @synchronized(self) {\n    return _error;\n  }\n}\n\n- (void)addPendingObject:(id)object {\n  NSParameterAssert(object);\n  \n  @synchronized(self) {\n    if (_state == FBLPromiseStatePending) {\n      if (!_pendingObjects) {\n        _pendingObjects = [[NSMutableSet alloc] init];\n      }\n      [_pendingObjects addObject:object];\n    }\n  }\n}\n\n- (void)observeOnQueue:(dispatch_queue_t)queue\n               fulfill:(FBLPromiseOnFulfillBlock)onFulfill\n                reject:(FBLPromiseOnRejectBlock)onReject {\n  NSParameterAssert(queue);\n  NSParameterAssert(onFulfill);\n  NSParameterAssert(onReject);\n\n  @synchronized(self) {\n    switch (_state) {\n      case FBLPromiseStatePending: {\n        if (!_observers) {\n          _observers = [[NSMutableArray alloc] init];\n        }\n        [_observers addObject:^(FBLPromiseState state, id __nullable resolution) {\n          dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{\n            switch (state) {\n              case FBLPromiseStatePending:\n                break;\n              case FBLPromiseStateFulfilled:\n                onFulfill(resolution);\n                break;\n              case FBLPromiseStateRejected:\n                onReject(resolution);\n                break;\n            }\n          });\n        }];\n        break;\n      }\n      case FBLPromiseStateFulfilled: {\n        dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{\n          onFulfill(self->_value);\n        });\n        break;\n      }\n      case FBLPromiseStateRejected: {\n        dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{\n          onReject(self->_error);\n        });\n        break;\n      }\n    }\n  }\n}\n\n- (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue\n              chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill\n               chainedReject:(FBLPromiseChainedRejectBlock)chainedReject {\n  NSParameterAssert(queue);\n\n  FBLPromise *promise = [[FBLPromise alloc] initPending];\n  __auto_type resolver = ^(id __nullable value) {\n    if ([value isKindOfClass:[FBLPromise class]]) {\n      [(FBLPromise *)value observeOnQueue:queue\n          fulfill:^(id __nullable value) {\n            [promise fulfill:value];\n          }\n          reject:^(NSError *error) {\n            [promise reject:error];\n          }];\n    } else {\n      [promise fulfill:value];\n    }\n  };\n  [self observeOnQueue:queue\n      fulfill:^(id __nullable value) {\n        value = chainedFulfill ? chainedFulfill(value) : value;\n        resolver(value);\n      }\n      reject:^(NSError *error) {\n        id value = chainedReject ? chainedReject(error) : error;\n        resolver(value);\n      }];\n  return promise;\n}\n\n@end\n\n@implementation FBLPromise (DotSyntaxAdditions)\n\n+ (instancetype (^)(void))pending {\n  return ^(void) {\n    return [self pendingPromise];\n  };\n}\n\n+ (instancetype (^)(id __nullable))resolved {\n  return ^(id resolution) {\n    return [self resolvedWith:resolution];\n  };\n}\n\n@end\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/FBLPromiseError.m",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromiseError.h\"\n\nNSErrorDomain const FBLPromiseErrorDomain = @\"com.google.FBLPromises.Error\";\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+All.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(AllAdditions)\n\n/**\n Wait until all of the given promises are fulfilled.\n If one of the given promises is rejected, then the returned promise is rejected with same error.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly.\n Promises resolved with `nil` become `NSNull` instances in the resulting array.\n\n @param promises Promises to wait for.\n @return Promise of an array containing the values of input promises in the same order.\n */\n+ (FBLPromise<NSArray *> *)all:(NSArray *)promises NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Wait until all of the given promises are fulfilled.\n If one of the given promises is rejected, then the returned promise is rejected with same error.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected FBLPromise correspondingly.\n Promises resolved with `nil` become `NSNull` instances in the resulting array.\n\n @param queue A queue to dispatch on.\n @param promises Promises to wait for.\n @return Promise of an array containing the values of input promises in the same order.\n */\n+ (FBLPromise<NSArray *> *)onQueue:(dispatch_queue_t)queue\n                               all:(NSArray *)promises NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `all` operators.\n Usage: FBLPromise.all(@[ ... ])\n */\n@interface FBLPromise<Value>(DotSyntax_AllAdditions)\n\n+ (FBLPromise<NSArray *> * (^)(NSArray *))all FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSArray *> * (^)(dispatch_queue_t, NSArray *))allOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Always.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(AlwaysAdditions)\n\ntypedef void (^FBLPromiseAlwaysWorkBlock)(void) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block that always executes, no matter if the receiver is rejected or fulfilled.\n @return A new pending promise to be resolved with same resolution as the receiver.\n */\n- (FBLPromise *)always:(FBLPromiseAlwaysWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to dispatch on.\n @param work A block that always executes, no matter if the receiver is rejected or fulfilled.\n @return A new pending promise to be resolved with same resolution as the receiver.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                 always:(FBLPromiseAlwaysWorkBlock)work NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `always` operators.\n Usage: promise.always(^{...})\n */\n@interface FBLPromise<Value>(DotSyntax_AlwaysAdditions)\n\n- (FBLPromise* (^)(FBLPromiseAlwaysWorkBlock))always FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAlwaysWorkBlock))alwaysOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Any.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(AnyAdditions)\n\n/**\n Waits until all of the given promises are either fulfilled or rejected.\n If all promises are rejected, then the returned promise is rejected with same error\n as the last one rejected.\n If at least one of the promises is fulfilled, the resulting promise is fulfilled with an array of\n values or `NSErrors`, matching the original order of fulfilled or rejected promises respectively.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly.\n Promises resolved with `nil` become `NSNull` instances in the resulting array.\n\n @param promises Promises to wait for.\n @return Promise of array containing the values or `NSError`s of input promises in the same order.\n */\n+ (FBLPromise<NSArray *> *)any:(NSArray *)promises NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Waits until all of the given promises are either fulfilled or rejected.\n If all promises are rejected, then the returned promise is rejected with same error\n as the last one rejected.\n If at least one of the promises is fulfilled, the resulting promise is fulfilled with an array of\n values or `NSError`s, matching the original order of fulfilled or rejected promises respectively.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly.\n Promises resolved with `nil` become `NSNull` instances in the resulting array.\n\n @param queue A queue to dispatch on.\n @param promises Promises to wait for.\n @return Promise of array containing the values or `NSError`s of input promises in the same order.\n */\n+ (FBLPromise<NSArray *> *)onQueue:(dispatch_queue_t)queue\n                               any:(NSArray *)promises NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `any` operators.\n Usage: FBLPromise.any(@[ ... ])\n */\n@interface FBLPromise<Value>(DotSyntax_AnyAdditions)\n\n+ (FBLPromise<NSArray *> * (^)(NSArray *))any FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSArray *> * (^)(dispatch_queue_t, NSArray *))anyOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Async.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(AsyncAdditions)\n\ntypedef void (^FBLPromiseFulfillBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseRejectBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseAsyncWorkBlock)(FBLPromiseFulfillBlock fulfill,\n                                         FBLPromiseRejectBlock reject) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise and executes `work` block asynchronously.\n\n @param work A block to perform any operations needed to resolve the promise.\n @return A new pending promise.\n */\n+ (instancetype)async:(FBLPromiseAsyncWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise and executes `work` block asynchronously on the given queue.\n\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @return A new pending promise.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n                  async:(FBLPromiseAsyncWorkBlock)work NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `async` operators.\n Usage: FBLPromise.async(^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_AsyncAdditions)\n\n+ (FBLPromise* (^)(FBLPromiseAsyncWorkBlock))async FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAsyncWorkBlock))asyncOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Await.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Waits for promise resolution. The current thread blocks until the promise is resolved.\n\n @param promise Promise to wait for.\n @param error Error the promise was rejected with, or `nil` if the promise was fulfilled.\n @return Value the promise was fulfilled with. If the promise was rejected, the return value\n         is always `nil`, but the error out arg is not.\n */\nFOUNDATION_EXTERN id __nullable FBLPromiseAwait(FBLPromise *promise,\n                                                NSError **error) NS_REFINED_FOR_SWIFT;\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Catch.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(CatchAdditions)\n\ntypedef void (^FBLPromiseCatchWorkBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise which eventually gets resolved with same resolution as the receiver.\n If receiver is rejected, then `reject` block is executed asynchronously.\n\n @param reject A block to handle the error that receiver was rejected with.\n @return A new pending promise.\n */\n- (FBLPromise *)catch:(FBLPromiseCatchWorkBlock)reject NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise which eventually gets resolved with same resolution as the receiver.\n If receiver is rejected, then `reject` block is executed asynchronously on the given queue.\n\n @param queue A queue to invoke the `reject` block on.\n @param reject A block to handle the error that receiver was rejected with.\n @return A new pending promise.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                  catch:(FBLPromiseCatchWorkBlock)reject NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `catch` operators.\n Usage: promise.catch(^(NSError *error) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_CatchAdditions)\n\n- (FBLPromise* (^)(FBLPromiseCatchWorkBlock))catch FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseCatchWorkBlock))catchOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Delay.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(DelayAdditions)\n\n/**\n Creates a new pending promise that fulfills with the same value as `self` after the `delay`, or\n rejects with the same error immediately.\n\n @param interval Time to wait in seconds.\n @return A new pending promise that fulfills at least `delay` seconds later than `self`, or rejects\n         with the same error immediately.\n */\n- (FBLPromise *)delay:(NSTimeInterval)interval NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a new pending promise that fulfills with the same value as `self` after the `delay`, or\n rejects with the same error immediately.\n\n @param queue A queue to dispatch on.\n @param interval Time to wait in seconds.\n @return A new pending promise that fulfills at least `delay` seconds later than `self`, or rejects\n         with the same error immediately.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                  delay:(NSTimeInterval)interval NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `delay` operators.\n Usage: promise.delay(...)\n */\n@interface FBLPromise<Value>(DotSyntax_DelayAdditions)\n\n- (FBLPromise * (^)(NSTimeInterval))delay FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise * (^)(dispatch_queue_t, NSTimeInterval))delayOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Do.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(DoAdditions)\n\ntypedef id __nullable (^FBLPromiseDoWorkBlock)(void) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise and executes `work` block asynchronously.\n\n @param work A block that returns a value or an error used to resolve the promise.\n @return A new pending promise.\n */\n+ (instancetype)do:(FBLPromiseDoWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise and executes `work` block asynchronously on the given queue.\n\n @param queue A queue to invoke the `work` block on.\n @param work A block that returns a value or an error used to resolve the promise.\n @return A new pending promise.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue do:(FBLPromiseDoWorkBlock)work NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `do` operators.\n Usage: FBLPromise.doOn(queue, ^(NSError *error) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_DoAdditions)\n\n+ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseDoWorkBlock))doOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Race.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(RaceAdditions)\n\n/**\n Wait until any of the given promises are fulfilled.\n If one of the promises is rejected, then the returned promise is rejected with same error.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly.\n\n @param promises Promises to wait for.\n @return A new pending promise to be resolved with the same resolution as the first promise, among\n         the given ones, which was resolved.\n */\n+ (instancetype)race:(NSArray *)promises NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Wait until any of the given promises are fulfilled.\n If one of the promises is rejected, then the returned promise is rejected with same error.\n If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`,\n it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly.\n\n @param queue A queue to dispatch on.\n @param promises Promises to wait for.\n @return A new pending promise to be resolved with the same resolution as the first promise, among\n         the given ones, which was resolved.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue race:(NSArray *)promises NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `race` operators.\n Usage: FBLPromise.race(@[ ... ])\n */\n@interface FBLPromise<Value>(DotSyntax_RaceAdditions)\n\n+ (FBLPromise * (^)(NSArray *))race FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise * (^)(dispatch_queue_t, NSArray *))raceOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Recover.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(RecoverAdditions)\n\ntypedef id __nullable (^FBLPromiseRecoverWorkBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Provides a new promise to recover in case the receiver gets rejected.\n\n @param recovery A block to handle the error that the receiver was rejected with.\n @return A new pending promise to use instead of the rejected one that gets resolved with resolution\n         returned from `recovery` block.\n */\n- (FBLPromise *)recover:(FBLPromiseRecoverWorkBlock)recovery NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Provides a new promise to recover in case the receiver gets rejected.\n\n @param queue A queue to dispatch on.\n @param recovery A block to handle the error that the receiver was rejected with.\n @return A new pending promise to use instead of the rejected one that gets resolved with resolution\n         returned from `recovery` block.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                recover:(FBLPromiseRecoverWorkBlock)recovery NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `recover` operators.\n Usage: promise.recover(^id(NSError *error) {...})\n */\n@interface FBLPromise<Value>(DotSyntax_RecoverAdditions)\n\n- (FBLPromise * (^)(FBLPromiseRecoverWorkBlock))recover FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRecoverWorkBlock))recoverOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Reduce.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(ReduceAdditions)\n\ntypedef id __nullable (^FBLPromiseReducerBlock)(Value __nullable partial, id next)\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Sequentially reduces a collection of values to a single promise using a given combining block\n and the value `self` resolves with as initial value.\n\n @param items An array of values to process in order.\n @param reducer A block to combine an accumulating value and an element of the sequence into\n                the new accumulating value or a promise resolved with it, to be used in the next\n                call of the `reducer` or returned to the caller.\n @return A new pending promise returned from the last `reducer` invocation.\n         Or `self` if `items` is empty.\n */\n- (FBLPromise *)reduce:(NSArray *)items\n               combine:(FBLPromiseReducerBlock)reducer NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Sequentially reduces a collection of values to a single promise using a given combining block\n and the value `self` resolves with as initial value.\n\n @param queue A queue to dispatch on.\n @param items An array of values to process in order.\n @param reducer A block to combine an accumulating value and an element of the sequence into\n                the new accumulating value or a promise resolved with it, to be used in the next\n                call of the `reducer` or returned to the caller.\n @return A new pending promise returned from the last `reducer` invocation.\n         Or `self` if `items` is empty.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                 reduce:(NSArray *)items\n                combine:(FBLPromiseReducerBlock)reducer NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `reduce` operators.\n Usage: promise.reduce(values, ^id(id partial, id next) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_ReduceAdditions)\n\n- (FBLPromise * (^)(NSArray *, FBLPromiseReducerBlock))reduce FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise * (^)(dispatch_queue_t, NSArray *, FBLPromiseReducerBlock))reduceOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Retry.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/** The default number of retry attempts is 1. */\nFOUNDATION_EXTERN NSInteger const FBLPromiseRetryDefaultAttemptsCount NS_REFINED_FOR_SWIFT;\n\n/** The default delay interval before making a retry attempt is 1.0 second. */\nFOUNDATION_EXTERN NSTimeInterval const FBLPromiseRetryDefaultDelayInterval NS_REFINED_FOR_SWIFT;\n\n@interface FBLPromise<Value>(RetryAdditions)\n\ntypedef id __nullable (^FBLPromiseRetryWorkBlock)(void) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef BOOL (^FBLPromiseRetryPredicateBlock)(NSInteger, NSError *) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously, or rejects with the same error after all retry attempts have\n been exhausted. Defaults to `FBLPromiseRetryDefaultAttemptsCount` attempt(s) on rejection where the\n `work` block is retried after a delay of `FBLPromiseRetryDefaultDelayInterval` second(s).\n\n @param work A block that executes asynchronously on the default queue and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted.\n */\n+ (FBLPromise *)retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously on the given `queue`, or rejects with the same error after all\n retry attempts have been exhausted. Defaults to `FBLPromiseRetryDefaultAttemptsCount` attempt(s) on\n rejection where the `work` block is retried on the given `queue` after a delay of\n `FBLPromiseRetryDefaultDelayInterval` second(s).\n\n @param queue A queue to invoke the `work` block on.\n @param work A block that executes asynchronously on the given `queue` and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted.\n */\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                  retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously, or rejects with the same error after all retry attempts have\n been exhausted.\n\n @param count Max number of retry attempts. The `work` block will be executed once if the specified\n              count is less than or equal to zero.\n @param work A block that executes asynchronously on the default queue and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted.\n */\n+ (FBLPromise *)attempts:(NSInteger)count\n                   retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously on the given `queue`, or rejects with the same error after all\n retry attempts have been exhausted.\n\n @param queue A queue to invoke the `work` block on.\n @param count Max number of retry attempts. The `work` block will be executed once if the specified\n              count is less than or equal to zero.\n @param work A block that executes asynchronously on the given `queue` and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted.\n */\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue\n               attempts:(NSInteger)count\n                  retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously, or rejects with the same error after all retry attempts have\n been exhausted. On rejection, the `work` block is retried after the given delay `interval` and will\n continue to retry until the number of specified attempts have been exhausted or will bail early if\n the given condition is not met.\n\n @param count Max number of retry attempts. The `work` block will be executed once if the specified\n              count is less than or equal to zero.\n @param interval Time to wait before the next retry attempt.\n @param predicate Condition to check before the next retry attempt. The predicate block provides the\n                  the number of remaining retry attempts and the error that the promise was rejected\n                  with.\n @param work A block that executes asynchronously on the default queue and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted or if\n         the given condition is not met.\n */\n+ (FBLPromise *)attempts:(NSInteger)count\n                   delay:(NSTimeInterval)interval\n               condition:(nullable FBLPromiseRetryPredicateBlock)predicate\n                   retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise that fulfills with the same value as the promise returned from `work`\n block, which executes asynchronously on the given `queue`, or rejects with the same error after all\n retry attempts have been exhausted. On rejection, the `work` block is retried after the given\n delay `interval` and will continue to retry until the number of specified attempts have been\n exhausted or will bail early if the given condition is not met.\n\n @param queue A queue to invoke the `work` block on.\n @param count Max number of retry attempts. The `work` block will be executed once if the specified\n              count is less than or equal to zero.\n @param interval Time to wait before the next retry attempt.\n @param predicate Condition to check before the next retry attempt. The predicate block provides the\n                  the number of remaining retry attempts and the error that the promise was rejected\n                  with.\n @param work A block that executes asynchronously on the given `queue` and returns a value or an\n             error used to resolve the promise.\n @return A new pending promise that fulfills with the same value as the promise returned from `work`\n         block, or rejects with the same error after all retry attempts have been exhausted or if\n         the given condition is not met.\n */\n+ (FBLPromise *)onQueue:(dispatch_queue_t)queue\n               attempts:(NSInteger)count\n                  delay:(NSTimeInterval)interval\n              condition:(nullable FBLPromiseRetryPredicateBlock)predicate\n                  retry:(FBLPromiseRetryWorkBlock)work NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise+Retry` operators.\n Usage: FBLPromise.retry(^id { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_RetryAdditions)\n\n+ (FBLPromise * (^)(FBLPromiseRetryWorkBlock))retry FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRetryWorkBlock))retryOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise * (^)(NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock __nullable,\n                    FBLPromiseRetryWorkBlock))retryAgain FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise * (^)(dispatch_queue_t, NSInteger, NSTimeInterval,\n                    FBLPromiseRetryPredicateBlock __nullable,\n                    FBLPromiseRetryWorkBlock))retryAgainOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Testing.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Waits for all scheduled promises blocks.\n\n @param timeout Maximum time to wait.\n @return YES if all promises blocks have completed before the timeout and NO otherwise.\n */\nFOUNDATION_EXTERN BOOL FBLWaitForPromisesWithTimeout(NSTimeInterval timeout) NS_REFINED_FOR_SWIFT;\n\n@interface FBLPromise<Value>(TestingAdditions)\n\n/**\n Dispatch group for promises that is typically used to wait for all scheduled blocks.\n */\n@property(class, nonatomic, readonly) dispatch_group_t dispatchGroup NS_REFINED_FOR_SWIFT;\n\n/**\n Properties to get the current state of the promise.\n */\n@property(nonatomic, readonly) BOOL isPending NS_REFINED_FOR_SWIFT;\n@property(nonatomic, readonly) BOOL isFulfilled NS_REFINED_FOR_SWIFT;\n@property(nonatomic, readonly) BOOL isRejected NS_REFINED_FOR_SWIFT;\n\n/**\n Value the promise was fulfilled with.\n Can be nil if the promise is still pending, was resolved with nil or after it has been rejected.\n */\n@property(nonatomic, readonly, nullable) Value value NS_REFINED_FOR_SWIFT;\n\n/**\n Error the promise was rejected with.\n Can be nil if the promise is still pending or after it has been fulfilled.\n */\n@property(nonatomic, readonly, nullable) NSError *error NS_REFINED_FOR_SWIFT;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Then.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(ThenAdditions)\n\ntypedef id __nullable (^FBLPromiseThenWorkBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise which eventually gets resolved with resolution returned from `work`\n block: either value, error or another promise. The `work` block is executed asynchronously only\n when the receiver is fulfilled. If receiver is rejected, the returned promise is also rejected with\n the same error.\n\n @param work A block to handle the value that receiver was fulfilled with.\n @return A new pending promise to be resolved with resolution returned from the `work` block.\n */\n- (FBLPromise *)then:(FBLPromiseThenWorkBlock)work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise which eventually gets resolved with resolution returned from `work`\n block: either value, error or another promise. The `work` block is executed asynchronously when the\n receiver is fulfilled. If receiver is rejected, the returned promise is also rejected with the same\n error.\n\n @param queue A queue to invoke the `work` block on.\n @param work A block to handle the value that receiver was fulfilled with.\n @return A new pending promise to be resolved with resolution returned from the `work` block.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                   then:(FBLPromiseThenWorkBlock)work NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `then` operators.\n Usage: promise.then(^id(id value) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_ThenAdditions)\n\n- (FBLPromise* (^)(FBLPromiseThenWorkBlock))then FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseThenWorkBlock))thenOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Timeout.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(TimeoutAdditions)\n\n/**\n Waits for a promise with the specified `timeout`.\n\n @param interval Time to wait in seconds.\n @return A new pending promise that gets either resolved with same resolution as the receiver or\n         rejected with `FBLPromiseErrorCodeTimedOut` error code in `FBLPromiseErrorDomain`.\n */\n- (FBLPromise *)timeout:(NSTimeInterval)interval NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Waits for a promise with the specified `timeout`.\n\n @param queue A queue to dispatch on.\n @param interval Time to wait in seconds.\n @return A new pending promise that gets either resolved with same resolution as the receiver or\n         rejected with `FBLPromiseErrorCodeTimedOut` error code in `FBLPromiseErrorDomain`.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n                timeout:(NSTimeInterval)interval NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `timeout` operators.\n Usage: promise.timeout(...)\n */\n@interface FBLPromise<Value>(DotSyntax_TimeoutAdditions)\n\n- (FBLPromise* (^)(NSTimeInterval))timeout FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise* (^)(dispatch_queue_t, NSTimeInterval))timeoutOn FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Validate.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface FBLPromise<Value>(ValidateAdditions)\n\ntypedef BOOL (^FBLPromiseValidateWorkBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Validates a fulfilled value or rejects the value if it can not be validated.\n\n @param predicate An expression to validate.\n @return A new pending promise that gets either resolved with same resolution as the receiver or\n         rejected with `FBLPromiseErrorCodeValidationFailure` error code in `FBLPromiseErrorDomain`.\n */\n- (FBLPromise *)validate:(FBLPromiseValidateWorkBlock)predicate NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Validates a fulfilled value or rejects the value if it can not be validated.\n\n @param queue A queue to dispatch on.\n @param predicate An expression to validate.\n @return A new pending promise that gets either resolved with same resolution as the receiver or\n         rejected with `FBLPromiseErrorCodeValidationFailure` error code in `FBLPromiseErrorDomain`.\n */\n- (FBLPromise *)onQueue:(dispatch_queue_t)queue\n               validate:(FBLPromiseValidateWorkBlock)predicate NS_REFINED_FOR_SWIFT;\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `validate` operators.\n Usage: promise.validate(^BOOL(id value) { ... })\n */\n@interface FBLPromise<Value>(DotSyntax_ValidateAdditions)\n\n- (FBLPromise * (^)(FBLPromiseValidateWorkBlock))validate FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseValidateWorkBlock))validateOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Wrap.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Different types of completion handlers available to be wrapped with promise.\n */\ntypedef void (^FBLPromiseCompletion)(void) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseObjectCompletion)(id __nullable) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseErrorCompletion)(NSError* __nullable) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseObjectOrErrorCompletion)(id __nullable, NSError* __nullable)\n    NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseErrorOrObjectCompletion)(NSError* __nullable, id __nullable)\n    NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromise2ObjectsOrErrorCompletion)(id __nullable, id __nullable,\n                                                    NSError* __nullable) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseBoolCompletion)(BOOL) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseBoolOrErrorCompletion)(BOOL, NSError* __nullable) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseIntegerCompletion)(NSInteger) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseIntegerOrErrorCompletion)(NSInteger, NSError* __nullable)\n    NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseDoubleCompletion)(double) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseDoubleOrErrorCompletion)(double, NSError* __nullable)\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Provides an easy way to convert methods that use common callback patterns into promises.\n */\n@interface FBLPromise<Value>(WrapAdditions)\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with `nil` when completion handler is invoked.\n */\n+ (instancetype)wrapCompletion:(void (^)(FBLPromiseCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with `nil` when completion handler is invoked.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n         wrapCompletion:(void (^)(FBLPromiseCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an object provided by completion handler.\n */\n+ (instancetype)wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an object provided by completion handler.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an error provided by completion handler.\n If error is `nil`, fulfills with `nil`, otherwise rejects with the error.\n */\n+ (instancetype)wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an error provided by completion handler.\n If error is `nil`, fulfills with `nil`, otherwise rejects with the error.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an object provided by completion handler if error is `nil`.\n Otherwise, rejects with the error.\n */\n+ (instancetype)wrapObjectOrErrorCompletion:\n    (void (^)(FBLPromiseObjectOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an object provided by completion handler if error is `nil`.\n Otherwise, rejects with the error.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an error or object provided by completion handler. If error\n is not `nil`, rejects with the error.\n */\n+ (instancetype)wrapErrorOrObjectCompletion:\n    (void (^)(FBLPromiseErrorOrObjectCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an error or object provided by completion handler. If error\n is not `nil`, rejects with the error.\n */\n+ (instancetype)onQueue:(dispatch_queue_t)queue\n    wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an array of objects provided by completion handler in order\n if error is `nil`. Otherwise, rejects with the error.\n */\n+ (FBLPromise<NSArray*>*)wrap2ObjectsOrErrorCompletion:\n    (void (^)(FBLPromise2ObjectsOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an array of objects provided by completion handler in order\n if error is `nil`. Otherwise, rejects with the error.\n */\n+ (FBLPromise<NSArray*>*)onQueue:(dispatch_queue_t)queue\n    wrap2ObjectsOrErrorCompletion:(void (^)(FBLPromise2ObjectsOrErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping YES/NO.\n */\n+ (FBLPromise<NSNumber*>*)wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping YES/NO.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n               wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping YES/NO when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)wrapBoolOrErrorCompletion:\n    (void (^)(FBLPromiseBoolOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping YES/NO when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n        wrapBoolOrErrorCompletion:(void (^)(FBLPromiseBoolOrErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping an integer.\n */\n+ (FBLPromise<NSNumber*>*)wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping an integer.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n            wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping an integer when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)wrapIntegerOrErrorCompletion:\n    (void (^)(FBLPromiseIntegerOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping an integer when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n     wrapIntegerOrErrorCompletion:(void (^)(FBLPromiseIntegerOrErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping a double.\n */\n+ (FBLPromise<NSNumber*>*)wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping a double.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n             wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping a double when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)wrapDoubleOrErrorCompletion:\n    (void (^)(FBLPromiseDoubleOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n @param queue A queue to invoke the `work` block on.\n @param work A block to perform any operations needed to resolve the promise.\n @returns A promise that resolves with an `NSNumber` wrapping a double when error is `nil`.\n Otherwise rejects with the error.\n */\n+ (FBLPromise<NSNumber*>*)onQueue:(dispatch_queue_t)queue\n      wrapDoubleOrErrorCompletion:(void (^)(FBLPromiseDoubleOrErrorCompletion handler))work\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\n/**\n Convenience dot-syntax wrappers for `FBLPromise` `wrap` operators.\n Usage: FBLPromise.wrapCompletion(^(FBLPromiseCompletion handler) {...})\n */\n@interface FBLPromise<Value>(DotSyntax_WrapAdditions)\n\n+ (FBLPromise* (^)(void (^)(FBLPromiseCompletion)))wrapCompletion FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseCompletion)))wrapCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletion FBL_PROMISES_DOT_SYNTAX\n    NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t,\n                   void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise* (^)(dispatch_queue_t,\n                   void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSArray*>* (^)(void (^)(FBLPromise2ObjectsOrErrorCompletion)))\n    wrap2ObjectsOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSArray*>* (^)(dispatch_queue_t, void (^)(FBLPromise2ObjectsOrErrorCompletion)))\n    wrap2ObjectsOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t,\n                              void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseBoolOrErrorCompletion)))wrapBoolOrErrorCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t,\n                              void (^)(FBLPromiseBoolOrErrorCompletion)))wrapBoolOrErrorCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t,\n                              void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseIntegerOrErrorCompletion)))\n    wrapIntegerOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t, void (^)(FBLPromiseIntegerOrErrorCompletion)))\n    wrapIntegerOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletion\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t,\n                              void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletionOn\n    FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(void (^)(FBLPromiseDoubleOrErrorCompletion)))\n    wrapDoubleOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (FBLPromise<NSNumber*>* (^)(dispatch_queue_t, void (^)(FBLPromiseDoubleOrErrorCompletion)))\n    wrapDoubleOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromiseError.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Promises synchronization construct in Objective-C.\n */\n@interface FBLPromise<__covariant Value> : NSObject\n\n/**\n Default dispatch queue used for `FBLPromise`, which is `main` if a queue is not specified.\n */\n@property(class) dispatch_queue_t defaultDispatchQueue NS_REFINED_FOR_SWIFT;\n\n/**\n Creates a pending promise.\n */\n+ (instancetype)pendingPromise NS_REFINED_FOR_SWIFT;\n\n/**\n Creates a resolved promise.\n\n @param resolution An object to resolve the promise with: either a value or an error.\n @return A new resolved promise.\n */\n+ (instancetype)resolvedWith:(nullable id)resolution NS_REFINED_FOR_SWIFT;\n\n/**\n Synchronously fulfills the promise with a value.\n\n @param value An arbitrary value to fulfill the promise with, including `nil`.\n */\n- (void)fulfill:(nullable Value)value NS_REFINED_FOR_SWIFT;\n\n/**\n Synchronously rejects the promise with an error.\n\n @param error An error to reject the promise with.\n */\n- (void)reject:(NSError *)error NS_REFINED_FOR_SWIFT;\n\n+ (instancetype)new NS_UNAVAILABLE;\n- (instancetype)init NS_UNAVAILABLE;\n@end\n\n@interface FBLPromise<Value>()\n\n/**\n Adds an object to the set of pending objects to keep strongly while the promise is pending.\n Used by the Swift wrappers to keep them alive until the underlying ObjC promise is resolved.\n\n @param object An object to add.\n */\n- (void)addPendingObject:(id)object NS_REFINED_FOR_SWIFT;\n\n@end\n\n#ifdef FBL_PROMISES_DOT_SYNTAX_IS_DEPRECATED\n#define FBL_PROMISES_DOT_SYNTAX __attribute__((deprecated))\n#else\n#define FBL_PROMISES_DOT_SYNTAX\n#endif\n\n@interface FBLPromise<Value>(DotSyntaxAdditions)\n\n/**\n Convenience dot-syntax wrappers for FBLPromise.\n Usage: FBLPromise.pending()\n        FBLPromise.resolved(value)\n\n */\n+ (instancetype (^)(void))pending FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n+ (instancetype (^)(id __nullable))resolved FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromiseError.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nFOUNDATION_EXTERN NSErrorDomain const FBLPromiseErrorDomain NS_REFINED_FOR_SWIFT;\n\n/**\n Possible error codes in `FBLPromiseErrorDomain`.\n */\ntypedef NS_ENUM(NSInteger, FBLPromiseErrorCode) {\n  /** Promise failed to resolve in time. */\n  FBLPromiseErrorCodeTimedOut = 1,\n  /** Validation predicate returned false. */\n  FBLPromiseErrorCodeValidationFailure = 2,\n} NS_REFINED_FOR_SWIFT;\n\nNS_INLINE BOOL FBLPromiseErrorIsTimedOut(NSError *error) NS_SWIFT_UNAVAILABLE(\"\") {\n  return error.domain == FBLPromiseErrorDomain &&\n         error.code == FBLPromiseErrorCodeTimedOut;\n}\n\nNS_INLINE BOOL FBLPromiseErrorIsValidationFailure(NSError *error) NS_SWIFT_UNAVAILABLE(\"\") {\n  return error.domain == FBLPromiseErrorDomain &&\n         error.code == FBLPromiseErrorCodeValidationFailure;\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromisePrivate.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+Testing.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Miscellaneous low-level private interfaces available to extend standard FBLPromise functionality.\n */\n@interface FBLPromise<Value>()\n\ntypedef void (^FBLPromiseOnFulfillBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef void (^FBLPromiseOnRejectBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(\"\");\ntypedef id __nullable (^__nullable FBLPromiseChainedFulfillBlock)(Value __nullable value)\n    NS_SWIFT_UNAVAILABLE(\"\");\ntypedef id __nullable (^__nullable FBLPromiseChainedRejectBlock)(NSError *error)\n    NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a pending promise.\n */\n- (instancetype)initPending NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Creates a resolved promise.\n\n @param resolution An object to resolve the promise with: either a value or an error.\n @return A new resolved promise.\n */\n- (instancetype)initWithResolution:(nullable id)resolution NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Invokes `fulfill` and `reject` blocks on `queue` when the receiver gets either fulfilled or\n rejected respectively.\n */\n- (void)observeOnQueue:(dispatch_queue_t)queue\n               fulfill:(FBLPromiseOnFulfillBlock)onFulfill\n                reject:(FBLPromiseOnRejectBlock)onReject NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Returns a new promise which gets resolved with the return value of `chainedFulfill` or\n `chainedReject` blocks respectively. The blocks are invoked when the receiver gets either\n fulfilled or rejected. If `nil` is passed to either block arg, the returned promise is resolved\n with the same resolution as the receiver.\n */\n- (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue\n              chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill\n               chainedReject:(FBLPromiseChainedRejectBlock)chainedReject NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromises.h",
    "content": "/**\n Copyright 2018 Google Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\n#import \"FBLPromise+All.h\"\n#import \"FBLPromise+Always.h\"\n#import \"FBLPromise+Any.h\"\n#import \"FBLPromise+Async.h\"\n#import \"FBLPromise+Await.h\"\n#import \"FBLPromise+Catch.h\"\n#import \"FBLPromise+Delay.h\"\n#import \"FBLPromise+Do.h\"\n#import \"FBLPromise+Race.h\"\n#import \"FBLPromise+Recover.h\"\n#import \"FBLPromise+Reduce.h\"\n#import \"FBLPromise+Retry.h\"\n#import \"FBLPromise+Then.h\"\n#import \"FBLPromise+Timeout.h\"\n#import \"FBLPromise+Validate.h\"\n#import \"FBLPromise+Wrap.h\"\n"
  },
  {
    "path": "Pods/SDWebImage/LICENSE",
    "content": "Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com\n \nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n \nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n \nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "Pods/SDWebImage/README.md",
    "content": "<p align=\"center\" >\n  <img src=\"https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/SDWebImage_logo.png\" title=\"SDWebImage logo\" float=left>\n</p>\n\n\n[![Build Status](http://img.shields.io/travis/SDWebImage/SDWebImage/master.svg?style=flat)](https://travis-ci.org/SDWebImage/SDWebImage)\n[![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)\n[![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)\n[![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg)](https://github.com/SDWebImage/SDWebImage)\n[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager/)\n[![Mac Catalyst compatible](https://img.shields.io/badge/Catalyst-compatible-brightgreen.svg)](https://developer.apple.com/documentation/xcode/creating_a_mac_version_of_your_ipad_app/)\n[![codecov](https://codecov.io/gh/SDWebImage/SDWebImage/branch/master/graph/badge.svg)](https://codecov.io/gh/SDWebImage/SDWebImage)\n\nThis library provides an async image downloader with cache support. For convenience, we added categories for UI elements like `UIImageView`, `UIButton`, `MKAnnotationView`.\n\n## Features\n\n- [x] Categories for `UIImageView`, `UIButton`, `MKAnnotationView` adding web image and cache management\n- [x] An asynchronous image downloader\n- [x] An asynchronous memory + disk image caching with automatic cache expiration handling\n- [x] A background image decompression to avoid frame rate drop\n- [x] [Progressive image loading](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#progressive-animation) (including animated image, like GIF showing in Web browser)\n- [x] [Thumbnail image decoding](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#thumbnail-decoding-550) to save CPU && Memory for large images\n- [x] [Extendable image coder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420) to support massive image format, like WebP\n- [x] [Full-stack solution for animated images](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) which keep a balance between CPU && Memory\n- [x] [Customizable and composable transformations](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#transformer-50) can be applied to the images right after download\n- [x] [Customizable and multiple caches system](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-cache-50)\n- [x] [Customizable and multiple loaders system](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-loader-50) to expand the capabilities, like [Photos Library](https://github.com/SDWebImage/SDWebImagePhotosPlugin)\n- [x] [Image loading indicators](https://github.com/SDWebImage/SDWebImage/wiki/How-to-use#use-view-indicator-50)\n- [x] [Image loading transition animation](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#image-transition-430)\n- [x] A guarantee that the same URL won't be downloaded several times\n- [x] A guarantee that bogus URLs won't be retried again and again\n- [x] A guarantee that main thread will never be blocked\n- [x] Modern Objective-C and better Swift support \n- [x] Performances!\n\n## Supported Image Formats\n\n- Image formats supported by Apple system (JPEG, PNG, TIFF, BMP, ...), including [GIF](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#gif-coder)/[APNG](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#apng-coder) animated image\n- HEIC format from iOS 11/macOS 10.13, including animated HEIC from iOS 13/macOS 10.15 via [SDWebImageHEICCoder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#heic-coder). For lower firmware, use coder plugin [SDWebImageHEIFCoder](https://github.com/SDWebImage/SDWebImageHEIFCoder)\n- WebP format from iOS 14/macOS 11.0 via [SDWebImageAWebPCoder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#awebp-coder). For lower firmware, use coder plugin [SDWebImageWebPCoder](https://github.com/SDWebImage/SDWebImageWebPCoder)\n- Support extendable coder plugins for new image formats like BPG, AVIF. And vector format like PDF, SVG. See all the list in [Image coder plugin List](https://github.com/SDWebImage/SDWebImage/wiki/Coder-Plugin-List)\n\n## Additional modules and Ecosystem\n\nIn order to keep SDWebImage focused and limited to the core features, but also allow extensibility and custom behaviors, during the 5.0 refactoring we focused on modularizing the library.\nAs such, we have moved/built new modules to [SDWebImage org](https://github.com/SDWebImage).\n\n#### SwiftUI\n[SwiftUI](https://developer.apple.com/xcode/swiftui/) is an innovative UI framework written in Swift to build user interfaces across all Apple platforms.\n\nWe support SwiftUI by building a brand new framework called [SDWebImageSwiftUI](https://github.com/SDWebImage/SDWebImageSwiftUI), which is built on top of SDWebImage core functions (caching, loading and animation).\n\nThe new framework introduce two View structs `WebImage` and `AnimatedImage` for SwiftUI world, `ImageIndicator` modifier for any View, `ImageManager` observable object for data source. Supports iOS 13+/macOS 10.15+/tvOS 13+/watchOS 6+ and Swift 5.1. Have a nice try and provide feedback!\n\n#### Coders for additional image formats\n- [SDWebImageWebPCoder](https://github.com/SDWebImage/SDWebImageWebPCoder) - coder for WebP format. iOS 8+/macOS 10.10+. Based on [libwebp](https://chromium.googlesource.com/webm/libwebp)\n- [SDWebImageHEIFCoder](https://github.com/SDWebImage/SDWebImageHEIFCoder) - coder for HEIF format, iOS 8+/macOS 10.10+ support. Based on [libheif](https://github.com/strukturag/libheif)\n- [SDWebImageBPGCoder](https://github.com/SDWebImage/SDWebImageBPGCoder) - coder for BPG format. Based on [libbpg](https://github.com/mirrorer/libbpg)\n- [SDWebImageFLIFCoder](https://github.com/SDWebImage/SDWebImageFLIFCoder) - coder for FLIF format. Based on [libflif](https://github.com/FLIF-hub/FLIF)\n- [SDWebImageAVIFCoder](https://github.com/SDWebImage/SDWebImageAVIFCoder) - coder for AVIF (AV1-based) format. Based on [libavif](https://github.com/AOMediaCodec/libavif)\n- [SDWebImagePDFCoder](https://github.com/SDWebImage/SDWebImagePDFCoder) - coder for PDF vector format. Using built-in frameworks\n- [SDWebImageSVGCoder](https://github.com/SDWebImage/SDWebImageSVGCoder) - coder for SVG vector format. Using built-in frameworks\n- [SDWebImageLottieCoder](https://github.com/SDWebImage/SDWebImageLottieCoder) - coder for Lottie animation format. Based on [rlottie](https://github.com/Samsung/rlottie)\n- and more from community!\n\n#### Custom Caches\n- [SDWebImageYYPlugin](https://github.com/SDWebImage/SDWebImageYYPlugin) - plugin to support caching images with [YYCache](https://github.com/ibireme/YYCache)\n- [SDWebImagePINPlugin](https://github.com/SDWebImage/SDWebImagePINPlugin) - plugin to support caching images with [PINCache](https://github.com/pinterest/PINCache)\n\n#### Custom Loaders\n- [SDWebImagePhotosPlugin](https://github.com/SDWebImage/SDWebImagePhotosPlugin) - plugin to support loading images from Photos (using `Photos.framework`) \n- [SDWebImageLinkPlugin](https://github.com/SDWebImage/SDWebImageLinkPlugin) - plugin to support loading images from rich link url, as well as `LPLinkView` (using `LinkPresentation.framework`) \n\n#### Integration with 3rd party libraries\n- [SDWebImageLottiePlugin](https://github.com/SDWebImage/SDWebImageLottiePlugin) - plugin to support [Lottie-iOS](https://github.com/airbnb/lottie-ios), vector animation rending with remote JSON files\n- [SDWebImageSVGKitPlugin](https://github.com/SDWebImage/SDWebImageLottiePlugin) - plugin to support [SVGKit](https://github.com/SVGKit/SVGKit), SVG rendering using Core Animation, iOS 8+/macOS 10.10+ support\n- [SDWebImageFLPlugin](https://github.com/SDWebImage/SDWebImageFLPlugin) - plugin to support [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) as the engine for animated GIFs\n- [SDWebImageYYPlugin](https://github.com/SDWebImage/SDWebImageYYPlugin) - plugin to integrate [YYImage](https://github.com/ibireme/YYImage) & [YYCache](https://github.com/ibireme/YYCache) for image rendering & caching\n\n#### Community driven popular libraries\n- [FirebaseUI](https://github.com/firebase/FirebaseUI-iOS) - Firebase Storage binding for query images, based on SDWebImage loader system\n- [react-native-fast-image](https://github.com/DylanVann/react-native-fast-image) - React Native fast image component, based on SDWebImage Animated Image solution\n- [flutter_image_compress](https://github.com/OpenFlutter/flutter_image_compress) - Flutter compresses image plugin, based on SDWebImage WebP coder plugin\n\n#### Make our lives easier\n- [libwebp-Xcode](https://github.com/SDWebImage/libwebp-Xcode) - A wrapper for [libwebp](https://chromium.googlesource.com/webm/libwebp) + an Xcode project.\n- [libheif-Xcode](https://github.com/SDWebImage/libheif-Xcode) - A wrapper for [libheif](https://github.com/strukturag/libheif) + an Xcode project.\n- [libavif-Xcode](https://github.com/SDWebImage/libavif-Xcode) - A wrapper for [libavif](https://github.com/AOMediaCodec/libavif) + an Xcode project.\n- and more third-party C/C++ image codec libraries with CocoaPods/Carthage/SwiftPM support.\n\nYou can use those directly, or create similar components of your own, by using the customizable architecture of SDWebImage.\n\n## Requirements\n\n- iOS 9.0 or later\n- tvOS 9.0 or later\n- watchOS 2.0 or later\n- macOS 10.11 or later (10.15 for Catalyst)\n- Xcode 11.0 or later\n\n#### Backwards compatibility\n\n- For iOS 8, macOS 10.10 or Xcode < 11, use [any 5.x version up to 5.9.5](https://github.com/SDWebImage/SDWebImage/releases/tag/5.9.5)\n- For iOS 7, macOS 10.9 or Xcode < 8, use [any 4.x version up to 4.4.6](https://github.com/SDWebImage/SDWebImage/releases/tag/4.4.6)\n- For macOS 10.8, use [any 4.x version up to 4.3.0](https://github.com/SDWebImage/SDWebImage/releases/tag/4.3.0)\n- For iOS 5 and 6, use [any 3.x version up to 3.7.6](https://github.com/SDWebImage/SDWebImage/releases/tag/3.7.6)\n- For iOS < 5.0, please use the last [2.0 version](https://github.com/SDWebImage/SDWebImage/tree/2.0-compat).\n\n## Getting Started\n\n- Read this Readme doc\n- Read the [How to use section](https://github.com/SDWebImage/SDWebImage#how-to-use)\n- Read the [Latest Documentation](https://sdwebimage.github.io/) and [CocoaDocs for old version](http://cocoadocs.org/docsets/SDWebImage/)\n- Try the example by downloading the project from Github or even easier using CocoaPods try `pod try SDWebImage`\n- Read the [Installation Guide](https://github.com/SDWebImage/SDWebImage/wiki/Installation-Guide)\n- Read the [SDWebImage 5.0 Migration Guide](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/SDWebImage-5.0-Migration-guide.md) to get an idea of the changes from 4.x to 5.x\n- Read the [SDWebImage 4.0 Migration Guide](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/SDWebImage-4.0-Migration-guide.md) to get an idea of the changes from 3.x to 4.x\n- Read the [Common Problems](https://github.com/SDWebImage/SDWebImage/wiki/Common-Problems) to find the solution for common problems \n- Go to the [Wiki Page](https://github.com/SDWebImage/SDWebImage/wiki) for more information such as [Advanced Usage](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage)\n\n## Who Uses It\n- Find out [who uses SDWebImage](https://github.com/SDWebImage/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list.\n\n## Communication\n\n- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage). (Tag 'sdwebimage')\n- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage).\n- If you **found a bug**, open an issue.\n- If you **have a feature request**, open an issue.\n- If you **need IRC channel**, use [Gitter](https://gitter.im/SDWebImage/community).\n\n## Contribution\n\n- If you **want to contribute**, read the [Contributing Guide](https://github.com/SDWebImage/SDWebImage/blob/master/.github/CONTRIBUTING.md)\n- For **development contribution guide**, read the [How-To-Contribute](https://github.com/SDWebImage/SDWebImage/wiki/How-to-Contribute)\n- For **understanding code architecture**, read the [Code Architecture Analysis](https://github.com/SDWebImage/SDWebImage/wiki/5.6-Code-Architecture-Analysis)\n\n## How To Use\n\n* Objective-C\n\n```objective-c\n#import <SDWebImage/SDWebImage.h>\n...\n[imageView sd_setImageWithURL:[NSURL URLWithString:@\"http://www.domain.com/path/to/image.jpg\"]\n             placeholderImage:[UIImage imageNamed:@\"placeholder.png\"]];\n```\n\n* Swift\n\n```swift\nimport SDWebImage\n\nimageView.sd_setImage(with: URL(string: \"http://www.domain.com/path/to/image.jpg\"), placeholderImage: UIImage(named: \"placeholder.png\"))\n```\n\n- For details about how to use the library and clear examples, see [The detailed How to use](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/HowToUse.md)\n\n## Animated Images (GIF) support\n\nIn 5.0, we introduced a brand new mechanism for supporting animated images. This includes animated image loading, rendering, decoding, and also supports customizations (for advanced users).\n\nThis animated image solution is available for `iOS`/`tvOS`/`macOS`. The `SDAnimatedImage` is subclass of `UIImage/NSImage`, and `SDAnimatedImageView` is subclass of `UIImageView/NSImageView`, to make them compatible with the common frameworks APIs.\n\nThe `SDAnimatedImageView` supports the familiar image loading category methods, works like drop-in replacement for `UIImageView/NSImageView`.\n\nDon't have `UIView` (like `WatchKit` or `CALayer`)? you can still use `SDAnimatedPlayer` the player engine for advanced playback and rendering.\n\nSee [Animated Image](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) for more detailed information.\n\n* Objective-C\n\n```objective-c\nSDAnimatedImageView *imageView = [SDAnimatedImageView new];\nSDAnimatedImage *animatedImage = [SDAnimatedImage imageNamed:@\"image.gif\"];\nimageView.image = animatedImage;\n```\n\n* Swift\n\n```swift\nlet imageView = SDAnimatedImageView()\nlet animatedImage = SDAnimatedImage(named: \"image.gif\")\nimageView.image = animatedImage\n```\n\n#### FLAnimatedImage integration has its own dedicated repo\nIn order to clean up things and make our core project do less things, we decided that the `FLAnimatedImage` integration does not belong here. From 5.0, this will still be available, but under a dedicated repo [SDWebImageFLPlugin](https://github.com/SDWebImage/SDWebImageFLPlugin).\n\n## Installation\n\nThere are four ways to use SDWebImage in your project:\n- using CocoaPods\n- using Carthage\n- using Swift Package Manager\n- manual install (build frameworks or embed Xcode Project)\n\n### Installation with CocoaPods\n\n[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the [Get Started](http://cocoapods.org/#get_started) section for more details.\n\n#### Podfile\n```\nplatform :ios, '8.0'\npod 'SDWebImage', '~> 5.0'\n```\n\n##### Swift and static framework\n\nSwift project previously had to use `use_frameworks!` to make all Pods into dynamic framework to let CocoaPods work.\n\nHowever, starting with `CocoaPods 1.5.0+` (with `Xcode 9+`), which supports to build both Objective-C && Swift code into static framework. You can use modular headers to use SDWebImage as static framework, without the need of `use_frameworks!`:\n\n```\nplatform :ios, '8.0'\n# Uncomment the next line when you want all Pods as static framework\n# use_modular_headers!\npod 'SDWebImage', :modular_headers => true\n```\n\nSee more on [CocoaPods 1.5.0 — Swift Static Libraries](http://blog.cocoapods.org/CocoaPods-1.5.0/)\n\nIf not, you still need to add `use_frameworks!` to use SDWebImage as dynamic framework:\n\n```\nplatform :ios, '8.0'\nuse_frameworks!\npod 'SDWebImage'\n```\n\n#### Subspecs\n\nThere are 2 subspecs available now: `Core` and `MapKit` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `MapKit`, you need to specify it). \n\nPodfile example:\n\n```\npod 'SDWebImage/MapKit'\n```\n\n### Installation with Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods.\n\nTo install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage)\n\nCarthage users can point to this repository and use whichever generated framework they'd like: SDWebImage, SDWebImageMapKit or both.\n\nMake the following entry in your Cartfile: `github \"SDWebImage/SDWebImage\"`\nThen run `carthage update`\nIf this is your first time using Carthage in the project, you'll need to go through some additional steps as explained [over at Carthage](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application).\n\n> NOTE: At this time, Carthage does not provide a way to build only specific repository subcomponents (or equivalent of CocoaPods's subspecs). All components and their dependencies will be built with the above command. However, you don't need to copy frameworks you aren't using into your project. For instance, if you aren't using `SDWebImageMapKit`, feel free to delete that framework from the Carthage Build directory after `carthage update` completes.\n\n### Installation with Swift Package Manager (Xcode 11+)\n\n[Swift Package Manager](https://swift.org/package-manager/) (SwiftPM) is a tool for managing the distribution of Swift code as well as C-family dependency. From Xcode 11, SwiftPM got natively integrated with Xcode.\n\nSDWebImage support SwiftPM from version 5.1.0. To use SwiftPM, you should use Xcode 11 to open your project. Click `File` -> `Swift Packages` -> `Add Package Dependency`, enter [SDWebImage repo's URL](https://github.com/SDWebImage/SDWebImage.git). Or you can login Xcode with your GitHub account and just type `SDWebImage` to search.\n\nAfter select the package, you can choose the dependency type (tagged version, branch or commit). Then Xcode will setup all the stuff for you.\n\nIf you're a framework author and use SDWebImage as a dependency, update your `Package.swift` file:\n\n```swift\nlet package = Package(\n    // 5.1.0 ..< 6.0.0\n    dependencies: [\n        .package(url: \"https://github.com/SDWebImage/SDWebImage.git\", from: \"5.1.0\")\n    ],\n    // ...\n)\n```\n\n### Manual Installation Guide\n\nSee more on [Manual install Guide](https://github.com/SDWebImage/SDWebImage/wiki/Installation-Guide#manual-installation-guide)\n\n### Import headers in your source files\n\nIn the source files where you need to use the library, import the umbrella header file:\n\n```objective-c\n#import <SDWebImage/SDWebImage.h>\n```\n\nIt's also recommend to use the module import syntax, available for CocoaPods(enable `modular_headers`)/Carthage/SwiftPM.\n\n```objecitivec\n@import SDWebImage;\n```\n\n### Build Project\n\nAt this point your workspace should build without error. If you are having problem, post to the Issue and the\ncommunity can help you solve it.\n\n## Data Collection Practices\nAs required by the [App privacy details on the App Store](https://developer.apple.com/app-store/app-privacy-details/), here's SDWebImage's list of [Data Collection Practices](https://sdwebimage.github.io/DataCollection/index.html).\n\n## Author\n- [Olivier Poitrey](https://github.com/rs)\n\n## Collaborators\n- [Konstantinos K.](https://github.com/mythodeia)\n- [Bogdan Poplauschi](https://github.com/bpoplauschi)\n- [Chester Liu](https://github.com/skyline75489)\n- [DreamPiggy](https://github.com/dreampiggy)\n- [Wu Zhong](https://github.com/zhongwuzw)\n\n## Credits\n\nThank you to all the people who have already contributed to SDWebImage.\n\n[![Contributors](https://opencollective.com/SDWebImage/contributors.svg?width=890)](https://github.com/SDWebImage/SDWebImage/graphs/contributors)\n\n## Licenses\n\nAll source code is licensed under the [MIT License](https://github.com/SDWebImage/SDWebImage/blob/master/LICENSE).\n\n## Architecture\n\nTo learn about SDWebImage's architecture design for contribution, read [The Core of SDWebImage v5.6 Architecture](https://github.com/SDWebImage/SDWebImage/wiki/5.6-Code-Architecture-Analysis). Thanks @looseyi for the post and translation.\n\n#### High Level Diagram\n<p align=\"center\" >\n    <img src=\"https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageHighLevelDiagram.jpeg\" title=\"SDWebImage high level diagram\">\n</p>\n\n#### Overall Class Diagram\n<p align=\"center\" >\n    <img src=\"https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageClassDiagram.png\" title=\"SDWebImage overall class diagram\">\n</p>\n\n#### Top Level API Diagram\n<p align=\"center\" >\n    <img src=\"https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageTopLevelClassDiagram.png\" title=\"SDWebImage top level API diagram\">\n</p>\n\n#### Main Sequence Diagram\n<p align=\"center\" >\n    <img src=\"https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageSequenceDiagram.png\" title=\"SDWebImage sequence diagram\">\n</p>\n\n#### More detailed diagrams\n- [Manager API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageManagerClassDiagram.png)\n- [Coders API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageCodersClassDiagram.png)\n- [Loader API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageLoaderClassDiagram.png)\n- [Cache API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageCacheClassDiagram.png)\n\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_MAC\n\n#import \"SDWebImageManager.h\"\n\n/**\n * Integrates SDWebImage async downloading and caching of remote images with NSButton.\n */\n@interface NSButton (WebCache)\n\n#pragma mark - Image\n\n/**\n * Get the current image URL.\n */\n@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentImageURL;\n\n/**\n * Set the button `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url The url for the image.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @see sd_setImageWithURL:placeholderImage:options:\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the button `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n#pragma mark - Alternate Image\n\n/**\n * Get the current alternateImage URL.\n */\n@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentAlternateImageURL;\n\n/**\n * Set the button `alternateImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url The url for the alternateImage.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `alternateImage` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the alternateImage.\n * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.\n * @see sd_setAlternateImageWithURL:placeholderImage:options:\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the alternateImage.\n * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.\n * @param options     The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the alternateImage.\n * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.\n * @param options     The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options\n                            context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the button `alternateImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the alternateImage.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the alternateImage was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original alternateImage url.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                          completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the alternateImage.\n * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the alternateImage was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original alternateImage url.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                          completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the alternateImage.\n * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.\n * @param options        The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the alternateImage was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original alternateImage url.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options\n                          completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the alternateImage.\n * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.\n * @param options        The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while alternateImage is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the alternateImage was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original alternateImage url.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options\n                           progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                          completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `alternateImage` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the alternateImage.\n * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.\n * @param options        The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while alternateImage is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the alternateImage was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original alternateImage url.\n */\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options\n                            context:(nullable SDWebImageContext *)context\n                           progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                          completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n#pragma mark - Cancel\n\n/**\n * Cancel the current image download\n */\n- (void)sd_cancelCurrentImageLoad;\n\n/**\n * Cancel the current alternateImage download\n */\n- (void)sd_cancelCurrentAlternateImageLoad;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"NSButton+WebCache.h\"\n\n#if SD_MAC\n\n#import \"objc/runtime.h\"\n#import \"UIView+WebCacheOperation.h\"\n#import \"UIView+WebCache.h\"\n#import \"SDInternalMacros.h\"\n\nstatic NSString * const SDAlternateImageOperationKey = @\"NSButtonAlternateImageOperation\";\n\n@implementation NSButton (WebCache)\n\n#pragma mark - Image\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock {\n    self.sd_currentImageURL = url;\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:context\n                       setImageBlock:nil\n                            progress:progressBlock\n                           completed:^(NSImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n#pragma mark - Alternate Image\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url {\n    [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url\n                   placeholderImage:(nullable UIImage *)placeholder\n                            options:(SDWebImageOptions)options\n                            context:(nullable SDWebImageContext *)context\n                           progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                          completed:(nullable SDExternalCompletionBlock)completedBlock {\n    self.sd_currentAlternateImageURL = url;\n    \n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    mutableContext[SDWebImageContextSetImageOperationKey] = SDAlternateImageOperationKey;\n    @weakify(self);\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:mutableContext\n                       setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {\n                           @strongify(self);\n                           self.alternateImage = image;\n                       }\n                            progress:progressBlock\n                           completed:^(NSImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n#pragma mark - Cancel\n\n- (void)sd_cancelCurrentImageLoad {\n    [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])];\n}\n\n- (void)sd_cancelCurrentAlternateImageLoad {\n    [self sd_cancelImageLoadOperationWithKey:SDAlternateImageOperationKey];\n}\n\n#pragma mar - Private\n\n- (NSURL *)sd_currentImageURL {\n    return objc_getAssociatedObject(self, @selector(sd_currentImageURL));\n}\n\n- (void)setSd_currentImageURL:(NSURL *)sd_currentImageURL {\n    objc_setAssociatedObject(self, @selector(sd_currentImageURL), sd_currentImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (NSURL *)sd_currentAlternateImageURL {\n    return objc_getAssociatedObject(self, @selector(sd_currentAlternateImageURL));\n}\n\n- (void)setSd_currentAlternateImageURL:(NSURL *)sd_currentAlternateImageURL {\n    objc_setAssociatedObject(self, @selector(sd_currentAlternateImageURL), sd_currentAlternateImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Fabrice Aneche\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/**\n You can use switch case like normal enum. It's also recommended to add a default case. You should not assume anything about the raw value.\n For custom coder plugin, it can also extern the enum for supported format. See `SDImageCoder` for more detailed information.\n */\ntypedef NSInteger SDImageFormat NS_TYPED_EXTENSIBLE_ENUM;\nstatic const SDImageFormat SDImageFormatUndefined = -1;\nstatic const SDImageFormat SDImageFormatJPEG      = 0;\nstatic const SDImageFormat SDImageFormatPNG       = 1;\nstatic const SDImageFormat SDImageFormatGIF       = 2;\nstatic const SDImageFormat SDImageFormatTIFF      = 3;\nstatic const SDImageFormat SDImageFormatWebP      = 4;\nstatic const SDImageFormat SDImageFormatHEIC      = 5;\nstatic const SDImageFormat SDImageFormatHEIF      = 6;\nstatic const SDImageFormat SDImageFormatPDF       = 7;\nstatic const SDImageFormat SDImageFormatSVG       = 8;\n\n/**\n NSData category about the image content type and UTI.\n */\n@interface NSData (ImageContentType)\n\n/**\n *  Return image format\n *\n *  @param data the input image data\n *\n *  @return the image format as `SDImageFormat` (enum)\n */\n+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;\n\n/**\n *  Convert SDImageFormat to UTType\n *\n *  @param format Format as SDImageFormat\n *  @return The UTType as CFStringRef\n *  @note For unknown format, `kUTTypeImage` abstract type will return\n */\n+ (nonnull CFStringRef)sd_UTTypeFromImageFormat:(SDImageFormat)format CF_RETURNS_NOT_RETAINED NS_SWIFT_NAME(sd_UTType(from:));\n\n/**\n *  Convert UTType to SDImageFormat\n *\n *  @param uttype The UTType as CFStringRef\n *  @return The Format as SDImageFormat\n *  @note For unknown type, `SDImageFormatUndefined` will return\n */\n+ (SDImageFormat)sd_imageFormatFromUTType:(nonnull CFStringRef)uttype;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Fabrice Aneche\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"NSData+ImageContentType.h\"\n#if SD_MAC\n#import <CoreServices/CoreServices.h>\n#else\n#import <MobileCoreServices/MobileCoreServices.h>\n#endif\n#import \"SDImageIOAnimatedCoderInternal.h\"\n\n#define kSVGTagEnd @\"</svg>\"\n\n@implementation NSData (ImageContentType)\n\n+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {\n    if (!data) {\n        return SDImageFormatUndefined;\n    }\n    \n    // File signatures table: http://www.garykessler.net/library/file_sigs.html\n    uint8_t c;\n    [data getBytes:&c length:1];\n    switch (c) {\n        case 0xFF:\n            return SDImageFormatJPEG;\n        case 0x89:\n            return SDImageFormatPNG;\n        case 0x47:\n            return SDImageFormatGIF;\n        case 0x49:\n        case 0x4D:\n            return SDImageFormatTIFF;\n        case 0x52: {\n            if (data.length >= 12) {\n                //RIFF....WEBP\n                NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];\n                if ([testString hasPrefix:@\"RIFF\"] && [testString hasSuffix:@\"WEBP\"]) {\n                    return SDImageFormatWebP;\n                }\n            }\n            break;\n        }\n        case 0x00: {\n            if (data.length >= 12) {\n                //....ftypheic ....ftypheix ....ftyphevc ....ftyphevx\n                NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding];\n                if ([testString isEqualToString:@\"ftypheic\"]\n                    || [testString isEqualToString:@\"ftypheix\"]\n                    || [testString isEqualToString:@\"ftyphevc\"]\n                    || [testString isEqualToString:@\"ftyphevx\"]) {\n                    return SDImageFormatHEIC;\n                }\n                //....ftypmif1 ....ftypmsf1\n                if ([testString isEqualToString:@\"ftypmif1\"] || [testString isEqualToString:@\"ftypmsf1\"]) {\n                    return SDImageFormatHEIF;\n                }\n            }\n            break;\n        }\n        case 0x25: {\n            if (data.length >= 4) {\n                //%PDF\n                NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(1, 3)] encoding:NSASCIIStringEncoding];\n                if ([testString isEqualToString:@\"PDF\"]) {\n                    return SDImageFormatPDF;\n                }\n            }\n        }\n        case 0x3C: {\n            // Check end with SVG tag\n            if ([data rangeOfData:[kSVGTagEnd dataUsingEncoding:NSUTF8StringEncoding] options:NSDataSearchBackwards range: NSMakeRange(data.length - MIN(100, data.length), MIN(100, data.length))].location != NSNotFound) {\n                return SDImageFormatSVG;\n            }\n        }\n    }\n    return SDImageFormatUndefined;\n}\n\n+ (nonnull CFStringRef)sd_UTTypeFromImageFormat:(SDImageFormat)format {\n    CFStringRef UTType;\n    switch (format) {\n        case SDImageFormatJPEG:\n            UTType = kUTTypeJPEG;\n            break;\n        case SDImageFormatPNG:\n            UTType = kUTTypePNG;\n            break;\n        case SDImageFormatGIF:\n            UTType = kUTTypeGIF;\n            break;\n        case SDImageFormatTIFF:\n            UTType = kUTTypeTIFF;\n            break;\n        case SDImageFormatWebP:\n            UTType = kSDUTTypeWebP;\n            break;\n        case SDImageFormatHEIC:\n            UTType = kSDUTTypeHEIC;\n            break;\n        case SDImageFormatHEIF:\n            UTType = kSDUTTypeHEIF;\n            break;\n        case SDImageFormatPDF:\n            UTType = kUTTypePDF;\n            break;\n        case SDImageFormatSVG:\n            UTType = kUTTypeScalableVectorGraphics;\n            break;\n        default:\n            // default is kUTTypeImage abstract type\n            UTType = kUTTypeImage;\n            break;\n    }\n    return UTType;\n}\n\n+ (SDImageFormat)sd_imageFormatFromUTType:(CFStringRef)uttype {\n    if (!uttype) {\n        return SDImageFormatUndefined;\n    }\n    SDImageFormat imageFormat;\n    if (CFStringCompare(uttype, kUTTypeJPEG, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatJPEG;\n    } else if (CFStringCompare(uttype, kUTTypePNG, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatPNG;\n    } else if (CFStringCompare(uttype, kUTTypeGIF, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatGIF;\n    } else if (CFStringCompare(uttype, kUTTypeTIFF, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatTIFF;\n    } else if (CFStringCompare(uttype, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatWebP;\n    } else if (CFStringCompare(uttype, kSDUTTypeHEIC, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatHEIC;\n    } else if (CFStringCompare(uttype, kSDUTTypeHEIF, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatHEIF;\n    } else if (CFStringCompare(uttype, kUTTypePDF, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatPDF;\n    } else if (CFStringCompare(uttype, kUTTypeScalableVectorGraphics, 0) == kCFCompareEqualTo) {\n        imageFormat = SDImageFormatSVG;\n    } else {\n        imageFormat = SDImageFormatUndefined;\n    }\n    return imageFormat;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_MAC\n\n/**\n This category is provided to easily write cross-platform(AppKit/UIKit) code. For common usage, see `UIImage+Metadata.h`.\n */\n@interface NSImage (Compatibility)\n\n/**\nThe underlying Core Graphics image object. This will actually use `CGImageForProposedRect` with the image size.\n */\n@property (nonatomic, readonly, nullable) CGImageRef CGImage;\n/**\n The underlying Core Image data. This will actually use `bestRepresentationForRect` with the image size to find the `NSCIImageRep`.\n */\n@property (nonatomic, readonly, nullable) CIImage *CIImage;\n/**\n The scale factor of the image. This wil actually use `bestRepresentationForRect` with image size and pixel size to calculate the scale factor. If failed, use the default value 1.0. Should be greater than or equal to 1.0.\n */\n@property (nonatomic, readonly) CGFloat scale;\n\n// These are convenience methods to make AppKit's `NSImage` match UIKit's `UIImage` behavior. The scale factor should be greater than or equal to 1.0.\n\n/**\n Returns an image object with the scale factor and orientation. The representation is created from the Core Graphics image object.\n @note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will actually create a `NSCGImageSnapshotRep` representation and always use `backingScaleFactor` as scale factor. So we should avoid it and use `NSBitmapImageRep` with `initWithCGImage:` instead.\n @note The difference between this and UIKit's `UIImage` equivalent method is the way to process orientation. If the provided image orientation is not equal to Up orientation, this method will firstly rotate the CGImage to the correct orientation to work compatible with `NSImageView`. However, UIKit will not actually rotate CGImage and just store it as `imageOrientation` property.\n\n @param cgImage A Core Graphics image object\n @param scale The image scale factor\n @param orientation The orientation of the image data\n @return The image object\n */\n- (nonnull instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation;\n\n/**\n Initializes and returns an image object with the specified Core Image object. The representation is `NSCIImageRep`.\n \n @param ciImage A Core Image image object\n @param scale The image scale factor\n @param orientation The orientation of the image data\n @return The image object\n */\n- (nonnull instancetype)initWithCIImage:(nonnull CIImage *)ciImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation;\n\n/**\n Returns an image object with the scale factor. The representation is created from the image data.\n @note The difference between these this and `initWithData:` is that `initWithData:` will always use `backingScaleFactor` as scale factor.\n\n @param data The image data\n @param scale The image scale factor\n @return The image object\n */\n- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"NSImage+Compatibility.h\"\n\n#if SD_MAC\n\n#import \"SDImageCoderHelper.h\"\n\n@implementation NSImage (Compatibility)\n\n- (nullable CGImageRef)CGImage {\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:nil hints:nil];\n    return cgImage;\n}\n\n- (nullable CIImage *)CIImage {\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    if (![imageRep isKindOfClass:NSCIImageRep.class]) {\n        return nil;\n    }\n    return ((NSCIImageRep *)imageRep).CIImage;\n}\n\n- (CGFloat)scale {\n    CGFloat scale = 1;\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    CGFloat width = imageRep.size.width;\n    CGFloat height = imageRep.size.height;\n    NSUInteger pixelWidth = imageRep.pixelsWide;\n    NSUInteger pixelHeight = imageRep.pixelsHigh;\n    if (width > 0 && height > 0) {\n        CGFloat widthScale = pixelWidth / width;\n        CGFloat heightScale = pixelHeight / height;\n        if (widthScale == heightScale && widthScale >= 1) {\n            // Protect because there may be `NSImageRepMatchesDevice` (0)\n            scale = widthScale;\n        }\n    }\n    \n    return scale;\n}\n\n- (instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation {\n    NSBitmapImageRep *imageRep;\n    if (orientation != kCGImagePropertyOrientationUp) {\n        // AppKit design is different from UIKit. Where CGImage based image rep does not respect to any orientation. Only data based image rep which contains the EXIF metadata can automatically detect orientation.\n        // This should be nonnull, until the memory is exhausted cause `CGBitmapContextCreate` failed.\n        CGImageRef rotatedCGImage = [SDImageCoderHelper CGImageCreateDecoded:cgImage orientation:orientation];\n        imageRep = [[NSBitmapImageRep alloc] initWithCGImage:rotatedCGImage];\n        CGImageRelease(rotatedCGImage);\n    } else {\n        imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];\n    }\n    if (scale < 1) {\n        scale = 1;\n    }\n    CGFloat pixelWidth = imageRep.pixelsWide;\n    CGFloat pixelHeight = imageRep.pixelsHigh;\n    NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);\n    self = [self initWithSize:size];\n    if (self) {\n        imageRep.size = size;\n        [self addRepresentation:imageRep];\n    }\n    return self;\n}\n\n- (instancetype)initWithCIImage:(nonnull CIImage *)ciImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation {\n    NSCIImageRep *imageRep;\n    if (orientation != kCGImagePropertyOrientationUp) {\n        CIImage *rotatedCIImage = [ciImage imageByApplyingOrientation:orientation];\n        imageRep = [[NSCIImageRep alloc] initWithCIImage:rotatedCIImage];\n    } else {\n        imageRep = [[NSCIImageRep alloc] initWithCIImage:ciImage];\n    }\n    if (scale < 1) {\n        scale = 1;\n    }\n    CGFloat pixelWidth = imageRep.pixelsWide;\n    CGFloat pixelHeight = imageRep.pixelsHigh;\n    NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);\n    self = [self initWithSize:size];\n    if (self) {\n        imageRep.size = size;\n        [self addRepresentation:imageRep];\n    }\n    return self;\n}\n\n- (instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale {\n    NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:data];\n    if (!imageRep) {\n        return nil;\n    }\n    if (scale < 1) {\n        scale = 1;\n    }\n    CGFloat pixelWidth = imageRep.pixelsWide;\n    CGFloat pixelHeight = imageRep.pixelsHigh;\n    NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);\n    self = [self initWithSize:size];\n    if (self) {\n        imageRep.size = size;\n        [self addRepresentation:imageRep];\n    }\n    return self;\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDImageCoder.h\"\n\n\n/**\n This is the protocol for SDAnimatedImage class only but not for SDAnimatedImageCoder. If you want to provide a custom animated image class with full advanced function, you can conform to this instead of the base protocol.\n */\n@protocol SDAnimatedImage <SDAnimatedImageProvider>\n\n@required\n/**\n Initializes and returns the image object with the specified data, scale factor and possible animation decoding options.\n @note We use this to create animated image instance for normal animation decoding.\n \n @param data The data object containing the image data.\n @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property.\n @param options A dictionary containing any animation decoding options.\n @return An initialized object\n */\n- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale options:(nullable SDImageCoderOptions *)options;\n\n/**\n Initializes the image with an animated coder. You can use the coder to decode the image frame later.\n @note We use this with animated coder which conforms to `SDProgressiveImageCoder` for progressive animation decoding.\n \n @param animatedCoder An animated coder which conform `SDAnimatedImageCoder` protocol\n @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property.\n @return An initialized object\n */\n- (nullable instancetype)initWithAnimatedCoder:(nonnull id<SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale;\n\n@optional\n// These methods are used for optional advanced feature, like image frame preloading.\n/**\n Pre-load all animated image frame into memory. Then later frame image request can directly return the frame for index without decoding.\n This method may be called on background thread.\n \n @note If one image instance is shared by lots of imageViews, the CPU performance for large animated image will drop down because the request frame index will be random (not in order) and the decoder should take extra effort to keep it re-entrant. You can use this to reduce CPU usage if need. Attention this will consume more memory usage.\n */\n- (void)preloadAllFrames;\n\n/**\n Unload all animated image frame from memory if are already pre-loaded. Then later frame image request need decoding. You can use this to free up the memory usage if need.\n */\n- (void)unloadAllFrames;\n\n/**\n Returns a Boolean value indicating whether all animated image frames are already pre-loaded into memory.\n */\n@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded;\n\n/**\n Return the animated image coder if the image is created with `initWithAnimatedCoder:scale:` method.\n @note We use this with animated coder which conforms to `SDProgressiveImageCoder` for progressive animation decoding.\n */\n@property (nonatomic, strong, readonly, nullable) id<SDAnimatedImageCoder> animatedCoder;\n\n@end\n\n/**\n The image class which supports animating on `SDAnimatedImageView`. You can also use it on normal UIImageView/NSImageView.\n */\n@interface SDAnimatedImage : UIImage <SDAnimatedImage>\n\n// This class override these methods from UIImage(NSImage), and it supports NSSecureCoding.\n// You should use these methods to create a new animated image. Use other methods just call super instead.\n// Pay attention, when the animated image frame count <= 1, all the `SDAnimatedImageProvider` protocol methods will return nil or 0 value, you'd better check the frame count before usage and keep fallback.\n+ (nullable instancetype)imageNamed:(nonnull NSString *)name; // Cache in memory, no Asset Catalog support\n#if __has_include(<UIKit/UITraitCollection.h>)\n+ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection; // Cache in memory, no Asset Catalog support\n#else\n+ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle; // Cache in memory, no Asset Catalog support\n#endif\n+ (nullable instancetype)imageWithContentsOfFile:(nonnull NSString *)path;\n+ (nullable instancetype)imageWithData:(nonnull NSData *)data;\n+ (nullable instancetype)imageWithData:(nonnull NSData *)data scale:(CGFloat)scale;\n- (nullable instancetype)initWithContentsOfFile:(nonnull NSString *)path;\n- (nullable instancetype)initWithData:(nonnull NSData *)data;\n- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;\n\n/**\n Current animated image format.\n */\n@property (nonatomic, assign, readonly) SDImageFormat animatedImageFormat;\n\n/**\n Current animated image data, you can use this to grab the compressed format data and create another animated image instance.\n If this image instance is an animated image created by using animated image coder (which means using the API listed above or using `initWithAnimatedCoder:scale:`), this property is non-nil.\n */\n@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;\n\n/**\n The scale factor of the image.\n \n @note For UIKit, this just call super instead.\n @note For AppKit, `NSImage` can contains multiple image representations with different scales. However, this class does not do that from the design. We process the scale like UIKit. This will actually be calculated from image size and pixel size.\n */\n@property (nonatomic, readonly) CGFloat scale;\n\n// By default, animated image frames are returned by decoding just in time without keeping into memory. But you can choose to preload them into memory as well, See the description in `SDAnimatedImage` protocol.\n// After preloaded, there is no huge difference on performance between this and UIImage's `animatedImageWithImages:duration:`. But UIImage's animation have some issues such like blanking and pausing during segue when using in `UIImageView`. It's recommend to use only if need.\n- (void)preloadAllFrames;\n- (void)unloadAllFrames;\n@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAnimatedImage.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDImageCoder.h\"\n#import \"SDImageCodersManager.h\"\n#import \"SDImageFrame.h\"\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"UIImage+Metadata.h\"\n#import \"UIImage+MultiFormat.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDImageAssetManager.h\"\n#import \"objc/runtime.h\"\n\nstatic CGFloat SDImageScaleFromPath(NSString *string) {\n    if (string.length == 0 || [string hasSuffix:@\"/\"]) return 1;\n    NSString *name = string.stringByDeletingPathExtension;\n    __block CGFloat scale = 1;\n    \n    NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@\"@[0-9]+\\\\.?[0-9]*x$\" options:NSRegularExpressionAnchorsMatchLines error:nil];\n    [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {\n        scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue;\n    }];\n    \n    return scale;\n}\n\n@interface SDAnimatedImage ()\n\n@property (nonatomic, strong) id<SDAnimatedImageCoder> animatedCoder;\n@property (nonatomic, assign, readwrite) SDImageFormat animatedImageFormat;\n@property (atomic, copy) NSArray<SDImageFrame *> *loadedAnimatedImageFrames; // Mark as atomic to keep thread-safe\n@property (nonatomic, assign, getter=isAllFramesLoaded) BOOL allFramesLoaded;\n\n@end\n\n@implementation SDAnimatedImage\n@dynamic scale; // call super\n\n#pragma mark - UIImage override method\n+ (instancetype)imageNamed:(NSString *)name {\n#if __has_include(<UIKit/UITraitCollection.h>)\n    return [self imageNamed:name inBundle:nil compatibleWithTraitCollection:nil];\n#else\n    return [self imageNamed:name inBundle:nil];\n#endif\n}\n\n#if __has_include(<UIKit/UITraitCollection.h>)\n+ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection {\n    if (!traitCollection) {\n        traitCollection = UIScreen.mainScreen.traitCollection;\n    }\n    CGFloat scale = traitCollection.displayScale;\n    return [self imageNamed:name inBundle:bundle scale:scale];\n}\n#else\n+ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle {\n    return [self imageNamed:name inBundle:bundle scale:0];\n}\n#endif\n\n// 0 scale means automatically check\n+ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle scale:(CGFloat)scale {\n    if (!name) {\n        return nil;\n    }\n    if (!bundle) {\n        bundle = [NSBundle mainBundle];\n    }\n    SDImageAssetManager *assetManager = [SDImageAssetManager sharedAssetManager];\n    SDAnimatedImage *image = (SDAnimatedImage *)[assetManager imageForName:name];\n    if ([image isKindOfClass:[SDAnimatedImage class]]) {\n        return image;\n    }\n    NSString *path = [assetManager getPathForName:name bundle:bundle preferredScale:&scale];\n    if (!path) {\n        return image;\n    }\n    NSData *data = [NSData dataWithContentsOfFile:path];\n    if (!data) {\n        return image;\n    }\n    image = [[self alloc] initWithData:data scale:scale];\n    if (image) {\n        [assetManager storeImage:image forName:name];\n    }\n    \n    return image;\n}\n\n+ (instancetype)imageWithContentsOfFile:(NSString *)path {\n    return [[self alloc] initWithContentsOfFile:path];\n}\n\n+ (instancetype)imageWithData:(NSData *)data {\n    return [[self alloc] initWithData:data];\n}\n\n+ (instancetype)imageWithData:(NSData *)data scale:(CGFloat)scale {\n    return [[self alloc] initWithData:data scale:scale];\n}\n\n- (instancetype)initWithContentsOfFile:(NSString *)path {\n    NSData *data = [NSData dataWithContentsOfFile:path];\n    return [self initWithData:data scale:SDImageScaleFromPath(path)];\n}\n\n- (instancetype)initWithData:(NSData *)data {\n    return [self initWithData:data scale:1];\n}\n\n- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {\n    return [self initWithData:data scale:scale options:nil];\n}\n\n- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale options:(SDImageCoderOptions *)options {\n    if (!data || data.length == 0) {\n        return nil;\n    }\n    data = [data copy]; // avoid mutable data\n    id<SDAnimatedImageCoder> animatedCoder = nil;\n    for (id<SDImageCoder>coder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) {\n        if ([coder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) {\n            if ([coder canDecodeFromData:data]) {\n                if (!options) {\n                    options = @{SDImageCoderDecodeScaleFactor : @(scale)};\n                }\n                animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:data options:options];\n                break;\n            }\n        }\n    }\n    if (!animatedCoder) {\n        return nil;\n    }\n    return [self initWithAnimatedCoder:animatedCoder scale:scale];\n}\n\n- (instancetype)initWithAnimatedCoder:(id<SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale {\n    if (!animatedCoder) {\n        return nil;\n    }\n    UIImage *image = [animatedCoder animatedImageFrameAtIndex:0];\n    if (!image) {\n        return nil;\n    }\n#if SD_MAC\n    self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:kCGImagePropertyOrientationUp];\n#else\n    self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:image.imageOrientation];\n#endif\n    if (self) {\n        // Only keep the animated coder if frame count > 1, save RAM usage for non-animated image format (APNG/WebP)\n        if (animatedCoder.animatedImageFrameCount > 1) {\n            _animatedCoder = animatedCoder;\n        }\n        NSData *data = [animatedCoder animatedImageData];\n        SDImageFormat format = [NSData sd_imageFormatForImageData:data];\n        _animatedImageFormat = format;\n    }\n    return self;\n}\n\n#pragma mark - Preload\n- (void)preloadAllFrames {\n    if (!_animatedCoder) {\n        return;\n    }\n    if (!self.isAllFramesLoaded) {\n        NSMutableArray<SDImageFrame *> *frames = [NSMutableArray arrayWithCapacity:self.animatedImageFrameCount];\n        for (size_t i = 0; i < self.animatedImageFrameCount; i++) {\n            UIImage *image = [self animatedImageFrameAtIndex:i];\n            NSTimeInterval duration = [self animatedImageDurationAtIndex:i];\n            SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration]; // through the image should be nonnull, used as nullable for `animatedImageFrameAtIndex:`\n            [frames addObject:frame];\n        }\n        self.loadedAnimatedImageFrames = frames;\n        self.allFramesLoaded = YES;\n    }\n}\n\n- (void)unloadAllFrames {\n    if (!_animatedCoder) {\n        return;\n    }\n    if (self.isAllFramesLoaded) {\n        self.loadedAnimatedImageFrames = nil;\n        self.allFramesLoaded = NO;\n    }\n}\n\n#pragma mark - NSSecureCoding\n- (instancetype)initWithCoder:(NSCoder *)aDecoder {\n    self = [super initWithCoder:aDecoder];\n    if (self) {\n        _animatedImageFormat = [aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(animatedImageFormat))];\n        NSData *animatedImageData = [aDecoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(animatedImageData))];\n        if (!animatedImageData) {\n            return self;\n        }\n        CGFloat scale = self.scale;\n        id<SDAnimatedImageCoder> animatedCoder = nil;\n        for (id<SDImageCoder>coder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) {\n            if ([coder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) {\n                if ([coder canDecodeFromData:animatedImageData]) {\n                    animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:animatedImageData options:@{SDImageCoderDecodeScaleFactor : @(scale)}];\n                    break;\n                }\n            }\n        }\n        if (!animatedCoder) {\n            return self;\n        }\n        if (animatedCoder.animatedImageFrameCount > 1) {\n            _animatedCoder = animatedCoder;\n        }\n    }\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)aCoder {\n    [super encodeWithCoder:aCoder];\n    [aCoder encodeInteger:self.animatedImageFormat forKey:NSStringFromSelector(@selector(animatedImageFormat))];\n    NSData *animatedImageData = self.animatedImageData;\n    if (animatedImageData) {\n        [aCoder encodeObject:animatedImageData forKey:NSStringFromSelector(@selector(animatedImageData))];\n    }\n}\n\n+ (BOOL)supportsSecureCoding {\n    return YES;\n}\n\n#pragma mark - SDAnimatedImageProvider\n\n- (NSData *)animatedImageData {\n    return [self.animatedCoder animatedImageData];\n}\n\n- (NSUInteger)animatedImageLoopCount {\n    return [self.animatedCoder animatedImageLoopCount];\n}\n\n- (NSUInteger)animatedImageFrameCount {\n    return [self.animatedCoder animatedImageFrameCount];\n}\n\n- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {\n    if (index >= self.animatedImageFrameCount) {\n        return nil;\n    }\n    if (self.isAllFramesLoaded) {\n        SDImageFrame *frame = [self.loadedAnimatedImageFrames objectAtIndex:index];\n        return frame.image;\n    }\n    return [self.animatedCoder animatedImageFrameAtIndex:index];\n}\n\n- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {\n    if (index >= self.animatedImageFrameCount) {\n        return 0;\n    }\n    if (self.isAllFramesLoaded) {\n        SDImageFrame *frame = [self.loadedAnimatedImageFrames objectAtIndex:index];\n        return frame.duration;\n    }\n    return [self.animatedCoder animatedImageDurationAtIndex:index];\n}\n\n@end\n\n@implementation SDAnimatedImage (MemoryCacheCost)\n\n- (NSUInteger)sd_memoryCost {\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_memoryCost));\n    if (value != nil) {\n        return value.unsignedIntegerValue;\n    }\n    \n    CGImageRef imageRef = self.CGImage;\n    if (!imageRef) {\n        return 0;\n    }\n    NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);\n    NSUInteger frameCount = 1;\n    if (self.isAllFramesLoaded) {\n        frameCount = self.animatedImageFrameCount;\n    }\n    frameCount = frameCount > 0 ? frameCount : 1;\n    NSUInteger cost = bytesPerFrame * frameCount;\n    return cost;\n}\n\n@end\n\n@implementation SDAnimatedImage (Metadata)\n\n- (BOOL)sd_isAnimated {\n    return YES;\n}\n\n- (NSUInteger)sd_imageLoopCount {\n    return self.animatedImageLoopCount;\n}\n\n- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {\n    return;\n}\n\n- (SDImageFormat)sd_imageFormat {\n    return self.animatedImageFormat;\n}\n\n- (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat {\n    return;\n}\n\n- (BOOL)sd_isVector {\n    return NO;\n}\n\n@end\n\n@implementation SDAnimatedImage (MultiFormat)\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {\n    return [self sd_imageWithData:data scale:1];\n}\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale {\n    return [self sd_imageWithData:data scale:scale firstFrameOnly:NO];\n}\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly {\n    if (!data) {\n        return nil;\n    }\n    return [[self alloc] initWithData:data scale:scale options:@{SDImageCoderDecodeFirstFrameOnly : @(firstFrameOnly)}];\n}\n\n- (nullable NSData *)sd_imageData {\n    NSData *imageData = self.animatedImageData;\n    if (imageData) {\n        return imageData;\n    } else {\n        return [self sd_imageDataAsFormat:self.animatedImageFormat];\n    }\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat {\n    return [self sd_imageDataAsFormat:imageFormat compressionQuality:1];\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality {\n    return [self sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:NO];\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly {\n    if (firstFrameOnly) {\n        // First frame, use super implementation\n        return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];\n    }\n    NSUInteger frameCount = self.animatedImageFrameCount;\n    if (frameCount <= 1) {\n        // Static image, use super implementation\n        return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];\n    }\n    // Keep animated image encoding, loop each frame.\n    NSMutableArray<SDImageFrame *> *frames = [NSMutableArray arrayWithCapacity:frameCount];\n    for (size_t i = 0; i < frameCount; i++) {\n        UIImage *image = [self animatedImageFrameAtIndex:i];\n        NSTimeInterval duration = [self animatedImageDurationAtIndex:i];\n        SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration];\n        [frames addObject:frame];\n    }\n    UIImage *animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames];\n    NSData *imageData = [animatedImage sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];\n    return imageData;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDImageCoder.h\"\n\ntypedef NS_ENUM(NSUInteger, SDAnimatedImagePlaybackMode) {\n    /**\n     * From first to last frame and stop or next loop.\n     */\n    SDAnimatedImagePlaybackModeNormal = 0,\n    /**\n     * From last frame to first frame and stop or next loop.\n     */\n    SDAnimatedImagePlaybackModeReverse,\n    /**\n     * From first frame to last frame and reverse again, like reciprocating.\n     */\n    SDAnimatedImagePlaybackModeBounce,\n    /**\n     * From last frame to first frame and reverse again, like reversed reciprocating.\n     */\n    SDAnimatedImagePlaybackModeReversedBounce,\n};\n\n/// A player to control the playback of animated image, which can be used to drive Animated ImageView or any rendering usage, like CALayer/WatchKit/SwiftUI rendering.\n@interface SDAnimatedImagePlayer : NSObject\n\n/// Current playing frame image. This value is KVO Compliance.\n@property (nonatomic, readonly, nullable) UIImage *currentFrame;\n\n/// Current frame index, zero based. This value is KVO Compliance.\n@property (nonatomic, readonly) NSUInteger currentFrameIndex;\n\n/// Current loop count since its latest animating. This value is KVO Compliance.\n@property (nonatomic, readonly) NSUInteger currentLoopCount;\n\n/// Total frame count for animated image rendering. Defaults is animated image's frame count.\n/// @note For progressive animation, you can update this value when your provider receive more frames.\n@property (nonatomic, assign) NSUInteger totalFrameCount;\n\n/// Total loop count for animated image rendering. Default is animated image's loop count.\n@property (nonatomic, assign) NSUInteger totalLoopCount;\n\n/// The animation playback rate. Default is 1.0\n/// `1.0` means the normal speed.\n/// `0.0` means stopping the animation.\n/// `0.0-1.0` means the slow speed.\n/// `> 1.0` means the fast speed.\n/// `< 0.0` is not supported currently and stop animation. (may support reverse playback in the future)\n@property (nonatomic, assign) double playbackRate;\n\n/// Asynchronous setup animation playback mode. Default mode is SDAnimatedImagePlaybackModeNormal.\n@property (nonatomic, assign) SDAnimatedImagePlaybackMode playbackMode;\n\n/// Provide a max buffer size by bytes. This is used to adjust frame buffer count and can be useful when the decoding cost is expensive (such as Animated WebP software decoding). Default is 0.\n/// `0` means automatically adjust by calculating current memory usage.\n/// `1` means without any buffer cache, each of frames will be decoded and then be freed after rendering. (Lowest Memory and Highest CPU)\n/// `NSUIntegerMax` means cache all the buffer. (Lowest CPU and Highest Memory)\n@property (nonatomic, assign) NSUInteger maxBufferSize;\n\n/// You can specify a runloop mode to let it rendering.\n/// Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device\n@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode;\n\n/// Create a player with animated image provider. If the provider's `animatedImageFrameCount` is less than 1, returns nil.\n/// The provider can be any protocol implementation, like `SDAnimatedImage`, `SDImageGIFCoder`, etc.\n/// @note This provider can represent mutable content, like progressive animated loading. But you need to update the frame count by yourself\n/// @param provider The animated provider\n- (nullable instancetype)initWithProvider:(nonnull id<SDAnimatedImageProvider>)provider;\n\n/// Create a player with animated image provider. If the provider's `animatedImageFrameCount` is less than 1, returns nil.\n/// The provider can be any protocol implementation, like `SDAnimatedImage` or `SDImageGIFCoder`, etc.\n/// @note This provider can represent mutable content, like progressive animated loading. But you need to update the frame count by yourself\n/// @param provider The animated provider\n+ (nullable instancetype)playerWithProvider:(nonnull id<SDAnimatedImageProvider>)provider;\n\n/// The handler block when current frame and index changed.\n@property (nonatomic, copy, nullable) void (^animationFrameHandler)(NSUInteger index, UIImage * _Nonnull frame);\n\n/// The handler block when one loop count finished.\n@property (nonatomic, copy, nullable) void (^animationLoopHandler)(NSUInteger loopCount);\n\n/// Return the status whether animation is playing.\n@property (nonatomic, readonly) BOOL isPlaying;\n\n/// Start the animation. Or resume the previously paused animation.\n- (void)startPlaying;\n\n/// Pause the animation. Keep the current frame index and loop count.\n- (void)pausePlaying;\n\n/// Stop the animation. Reset the current frame index and loop count.\n- (void)stopPlaying;\n\n/// Seek to the desired frame index and loop count.\n/// @note This can be used for advanced control like progressive loading, or skipping specify frames.\n/// @param index The frame index\n/// @param loopCount The loop count\n- (void)seekToFrameAtIndex:(NSUInteger)index loopCount:(NSUInteger)loopCount;\n\n/// Clear the frame cache buffer. The frame cache buffer size can be controlled by `maxBufferSize`.\n/// By default, when stop or pause the animation, the frame buffer is still kept to ready for the next restart\n- (void)clearFrameBuffer;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDAnimatedImagePlayer.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDDisplayLink.h\"\n#import \"SDDeviceHelper.h\"\n#import \"SDInternalMacros.h\"\n\n@interface SDAnimatedImagePlayer () {\n    SD_LOCK_DECLARE(_lock);\n    NSRunLoopMode _runLoopMode;\n}\n\n@property (nonatomic, strong, readwrite) UIImage *currentFrame;\n@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex;\n@property (nonatomic, assign, readwrite) NSUInteger currentLoopCount;\n@property (nonatomic, strong) id<SDAnimatedImageProvider> animatedProvider;\n@property (nonatomic, strong) NSMutableDictionary<NSNumber *, UIImage *> *frameBuffer;\n@property (nonatomic, assign) NSTimeInterval currentTime;\n@property (nonatomic, assign) BOOL bufferMiss;\n@property (nonatomic, assign) BOOL needsDisplayWhenImageBecomesAvailable;\n@property (nonatomic, assign) BOOL shouldReverse;\n@property (nonatomic, assign) NSUInteger maxBufferCount;\n@property (nonatomic, strong) NSOperationQueue *fetchQueue;\n@property (nonatomic, strong) SDDisplayLink *displayLink;\n\n@end\n\n@implementation SDAnimatedImagePlayer\n\n- (instancetype)initWithProvider:(id<SDAnimatedImageProvider>)provider {\n    self = [super init];\n    if (self) {\n        NSUInteger animatedImageFrameCount = provider.animatedImageFrameCount;\n        // Check the frame count\n        if (animatedImageFrameCount <= 1) {\n            return nil;\n        }\n        self.totalFrameCount = animatedImageFrameCount;\n        // Get the current frame and loop count.\n        self.totalLoopCount = provider.animatedImageLoopCount;\n        self.animatedProvider = provider;\n        self.playbackRate = 1.0;\n        SD_LOCK_INIT(_lock);\n#if SD_UIKIT\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    }\n    return self;\n}\n\n+ (instancetype)playerWithProvider:(id<SDAnimatedImageProvider>)provider {\n    SDAnimatedImagePlayer *player = [[SDAnimatedImagePlayer alloc] initWithProvider:provider];\n    return player;\n}\n\n#pragma mark - Life Cycle\n\n- (void)dealloc {\n#if SD_UIKIT\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n}\n\n- (void)didReceiveMemoryWarning:(NSNotification *)notification {\n    [_fetchQueue cancelAllOperations];\n    [_fetchQueue addOperationWithBlock:^{\n        NSNumber *currentFrameIndex = @(self.currentFrameIndex);\n        SD_LOCK(self->_lock);\n        NSArray *keys = self.frameBuffer.allKeys;\n        // only keep the next frame for later rendering\n        for (NSNumber * key in keys) {\n            if (![key isEqualToNumber:currentFrameIndex]) {\n                [self.frameBuffer removeObjectForKey:key];\n            }\n        }\n        SD_UNLOCK(self->_lock);\n    }];\n}\n\n#pragma mark - Private\n- (NSOperationQueue *)fetchQueue {\n    if (!_fetchQueue) {\n        _fetchQueue = [[NSOperationQueue alloc] init];\n        _fetchQueue.maxConcurrentOperationCount = 1;\n    }\n    return _fetchQueue;\n}\n\n- (NSMutableDictionary<NSNumber *,UIImage *> *)frameBuffer {\n    if (!_frameBuffer) {\n        _frameBuffer = [NSMutableDictionary dictionary];\n    }\n    return _frameBuffer;\n}\n\n- (SDDisplayLink *)displayLink {\n    if (!_displayLink) {\n        _displayLink = [SDDisplayLink displayLinkWithTarget:self selector:@selector(displayDidRefresh:)];\n        [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.runLoopMode];\n        [_displayLink stop];\n    }\n    return _displayLink;\n}\n\n- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode {\n    if ([_runLoopMode isEqual:runLoopMode]) {\n        return;\n    }\n    if (_displayLink) {\n        if (_runLoopMode) {\n            [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:_runLoopMode];\n        }\n        if (runLoopMode.length > 0) {\n            [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode];\n        }\n    }\n    _runLoopMode = [runLoopMode copy];\n}\n\n- (NSRunLoopMode)runLoopMode {\n    if (!_runLoopMode) {\n        _runLoopMode = [[self class] defaultRunLoopMode];\n    }\n    return _runLoopMode;\n}\n\n#pragma mark - State Control\n\n- (void)setupCurrentFrame {\n    if (self.currentFrameIndex != 0) {\n        return;\n    }\n    if (self.playbackMode == SDAnimatedImagePlaybackModeReverse ||\n               self.playbackMode == SDAnimatedImagePlaybackModeReversedBounce) {\n        self.currentFrameIndex = self.totalFrameCount - 1;\n    }\n    \n    if (!self.currentFrame && [self.animatedProvider isKindOfClass:[UIImage class]]) {\n        UIImage *image = (UIImage *)self.animatedProvider;\n        // Use the poster image if available\n        #if SD_MAC\n        UIImage *posterFrame = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];\n        #else\n        UIImage *posterFrame = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation];\n        #endif\n        if (posterFrame) {\n            self.currentFrame = posterFrame;\n            SD_LOCK(self->_lock);\n            self.frameBuffer[@(self.currentFrameIndex)] = self.currentFrame;\n            SD_UNLOCK(self->_lock);\n            [self handleFrameChange];\n        }\n    }\n    \n}\n\n- (void)resetCurrentFrameStatus {\n    // These should not trigger KVO, user don't need to receive an `index == 0, image == nil` callback.\n    _currentFrame = nil;\n    _currentFrameIndex = 0;\n    _currentLoopCount = 0;\n    _currentTime = 0;\n    _bufferMiss = NO;\n    _needsDisplayWhenImageBecomesAvailable = NO;\n}\n\n- (void)clearFrameBuffer {\n    SD_LOCK(_lock);\n    [_frameBuffer removeAllObjects];\n    SD_UNLOCK(_lock);\n}\n\n#pragma mark - Animation Control\n- (void)startPlaying {\n    [self.displayLink start];\n    // Setup frame\n    [self setupCurrentFrame];\n    // Calculate max buffer size\n    [self calculateMaxBufferCount];\n}\n\n- (void)stopPlaying {\n    [_fetchQueue cancelAllOperations];\n    // Using `_displayLink` here because when UIImageView dealloc, it may trigger `[self stopAnimating]`, we already release the display link in SDAnimatedImageView's dealloc method.\n    [_displayLink stop];\n    // We need to reset the frame status, but not trigger any handle. This can ensure next time's playing status correct.\n    [self resetCurrentFrameStatus];\n}\n\n- (void)pausePlaying {\n    [_fetchQueue cancelAllOperations];\n    [_displayLink stop];\n}\n\n- (BOOL)isPlaying {\n    return _displayLink.isRunning;\n}\n\n- (void)seekToFrameAtIndex:(NSUInteger)index loopCount:(NSUInteger)loopCount {\n    if (index >= self.totalFrameCount) {\n        return;\n    }\n    self.currentFrameIndex = index;\n    self.currentLoopCount = loopCount;\n    self.currentFrame = [self.animatedProvider animatedImageFrameAtIndex:index];\n    [self handleFrameChange];\n}\n\n#pragma mark - Core Render\n- (void)displayDidRefresh:(SDDisplayLink *)displayLink {\n    // If for some reason a wild call makes it through when we shouldn't be animating, bail.\n    // Early return!\n    if (!self.isPlaying) {\n        return;\n    }\n    \n    NSUInteger totalFrameCount = self.totalFrameCount;\n    if (totalFrameCount <= 1) {\n        // Total frame count less than 1, wrong configuration and stop animating\n        [self stopPlaying];\n        return;\n    }\n    \n    NSTimeInterval playbackRate = self.playbackRate;\n    if (playbackRate <= 0) {\n        // Does not support <= 0 play rate\n        [self stopPlaying];\n        return;\n    }\n    \n    // Calculate refresh duration\n    NSTimeInterval duration = self.displayLink.duration;\n    \n    NSUInteger currentFrameIndex = self.currentFrameIndex;\n    NSUInteger nextFrameIndex = (currentFrameIndex + 1) % totalFrameCount;\n    \n    if (self.playbackMode == SDAnimatedImagePlaybackModeReverse) {\n        nextFrameIndex = currentFrameIndex == 0 ? (totalFrameCount - 1) : (currentFrameIndex - 1) % totalFrameCount;\n        \n    } else if (self.playbackMode == SDAnimatedImagePlaybackModeBounce ||\n               self.playbackMode == SDAnimatedImagePlaybackModeReversedBounce) {\n        if (currentFrameIndex == 0) {\n            self.shouldReverse = false;\n        } else if (currentFrameIndex == totalFrameCount - 1) {\n            self.shouldReverse = true;\n        }\n        nextFrameIndex = self.shouldReverse ? (currentFrameIndex - 1) : (currentFrameIndex + 1);\n        nextFrameIndex %= totalFrameCount;\n    }\n    \n    \n    // Check if we need to display new frame firstly\n    BOOL bufferFull = NO;\n    if (self.needsDisplayWhenImageBecomesAvailable) {\n        UIImage *currentFrame;\n        SD_LOCK(_lock);\n        currentFrame = self.frameBuffer[@(currentFrameIndex)];\n        SD_UNLOCK(_lock);\n        \n        // Update the current frame\n        if (currentFrame) {\n            SD_LOCK(_lock);\n            // Remove the frame buffer if need\n            if (self.frameBuffer.count > self.maxBufferCount) {\n                self.frameBuffer[@(currentFrameIndex)] = nil;\n            }\n            // Check whether we can stop fetch\n            if (self.frameBuffer.count == totalFrameCount) {\n                bufferFull = YES;\n            }\n            SD_UNLOCK(_lock);\n            \n            // Update the current frame immediately\n            self.currentFrame = currentFrame;\n            [self handleFrameChange];\n            \n            self.bufferMiss = NO;\n            self.needsDisplayWhenImageBecomesAvailable = NO;\n        }\n        else {\n            self.bufferMiss = YES;\n        }\n    }\n    \n    // Check if we have the frame buffer\n    if (!self.bufferMiss) {\n        // Then check if timestamp is reached\n        self.currentTime += duration;\n        NSTimeInterval currentDuration = [self.animatedProvider animatedImageDurationAtIndex:currentFrameIndex];\n        currentDuration = currentDuration / playbackRate;\n        if (self.currentTime < currentDuration) {\n            // Current frame timestamp not reached, return\n            return;\n        }\n        \n        // Otherwise, we should be ready to display next frame\n        self.needsDisplayWhenImageBecomesAvailable = YES;\n        self.currentFrameIndex = nextFrameIndex;\n        self.currentTime -= currentDuration;\n        NSTimeInterval nextDuration = [self.animatedProvider animatedImageDurationAtIndex:nextFrameIndex];\n        nextDuration = nextDuration / playbackRate;\n        if (self.currentTime > nextDuration) {\n            // Do not skip frame\n            self.currentTime = nextDuration;\n        }\n        \n        // Update the loop count when last frame rendered\n        if (nextFrameIndex == 0) {\n            // Update the loop count\n            self.currentLoopCount++;\n            [self handleLoopChange];\n            \n            // if reached the max loop count, stop animating, 0 means loop indefinitely\n            NSUInteger maxLoopCount = self.totalLoopCount;\n            if (maxLoopCount != 0 && (self.currentLoopCount >= maxLoopCount)) {\n                [self stopPlaying];\n                return;\n            }\n        }\n    }\n    \n    // Since we support handler, check animating state again\n    if (!self.isPlaying) {\n        return;\n    }\n    \n    // Check if we should prefetch next frame or current frame\n    // When buffer miss, means the decode speed is slower than render speed, we fetch current miss frame\n    // Or, most cases, the decode speed is faster than render speed, we fetch next frame\n    NSUInteger fetchFrameIndex = self.bufferMiss? currentFrameIndex : nextFrameIndex;\n    UIImage *fetchFrame;\n    SD_LOCK(_lock);\n    fetchFrame = self.bufferMiss? nil : self.frameBuffer[@(nextFrameIndex)];\n    SD_UNLOCK(_lock);\n    \n    if (!fetchFrame && !bufferFull && self.fetchQueue.operationCount == 0) {\n        // Prefetch next frame in background queue\n        id<SDAnimatedImageProvider> animatedProvider = self.animatedProvider;\n        @weakify(self);\n        NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{\n            @strongify(self);\n            if (!self) {\n                return;\n            }\n            UIImage *frame = [animatedProvider animatedImageFrameAtIndex:fetchFrameIndex];\n\n            BOOL isAnimating = self.displayLink.isRunning;\n            if (isAnimating) {\n                SD_LOCK(self->_lock);\n                self.frameBuffer[@(fetchFrameIndex)] = frame;\n                SD_UNLOCK(self->_lock);\n            }\n        }];\n        [self.fetchQueue addOperation:operation];\n    }\n}\n\n- (void)handleFrameChange {\n    if (self.animationFrameHandler) {\n        self.animationFrameHandler(self.currentFrameIndex, self.currentFrame);\n    }\n}\n\n- (void)handleLoopChange {\n    if (self.animationLoopHandler) {\n        self.animationLoopHandler(self.currentLoopCount);\n    }\n}\n\n#pragma mark - Util\n- (void)calculateMaxBufferCount {\n    NSUInteger bytes = CGImageGetBytesPerRow(self.currentFrame.CGImage) * CGImageGetHeight(self.currentFrame.CGImage);\n    if (bytes == 0) bytes = 1024;\n    \n    NSUInteger max = 0;\n    if (self.maxBufferSize > 0) {\n        max = self.maxBufferSize;\n    } else {\n        // Calculate based on current memory, these factors are by experience\n        NSUInteger total = [SDDeviceHelper totalMemory];\n        NSUInteger free = [SDDeviceHelper freeMemory];\n        max = MIN(total * 0.2, free * 0.6);\n    }\n    \n    NSUInteger maxBufferCount = (double)max / (double)bytes;\n    if (!maxBufferCount) {\n        // At least 1 frame\n        maxBufferCount = 1;\n    }\n    \n    self.maxBufferCount = maxBufferCount;\n}\n\n+ (NSString *)defaultRunLoopMode {\n    // Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations.\n    return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_MAC\n\n/**\n A subclass of `NSBitmapImageRep` to fix that GIF duration issue because `NSBitmapImageRep` will reset `NSImageCurrentFrameDuration` by using `kCGImagePropertyGIFDelayTime` but not `kCGImagePropertyGIFUnclampedDelayTime`.\n This also fix the GIF loop count issue, which will use the Netscape standard (See http://www6.uniovi.es/gifanim/gifabout.htm)  to only place once when the `kCGImagePropertyGIFLoopCount` is nil. This is what modern browser's behavior.\n Built in GIF coder use this instead of `NSBitmapImageRep` for better GIF rendering. If you do not want this, only enable `SDImageIOCoder`, which just call `NSImage` API and actually use `NSBitmapImageRep` for GIF image.\n This also support APNG format using `SDImageAPNGCoder`. Which provide full alpha-channel support and the correct duration match the `kCGImagePropertyAPNGUnclampedDelayTime`.\n */\n@interface SDAnimatedImageRep : NSBitmapImageRep\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAnimatedImageRep.h\"\n\n#if SD_MAC\n\n#import \"SDImageIOAnimatedCoderInternal.h\"\n#import \"SDImageGIFCoder.h\"\n#import \"SDImageAPNGCoder.h\"\n#import \"SDImageHEICCoder.h\"\n#import \"SDImageAWebPCoder.h\"\n\n@implementation SDAnimatedImageRep {\n    CGImageSourceRef _imageSource;\n}\n\n- (void)dealloc {\n    if (_imageSource) {\n        CFRelease(_imageSource);\n        _imageSource = NULL;\n    }\n}\n\n// `NSBitmapImageRep`'s `imageRepWithData:` is not designed initializer\n+ (instancetype)imageRepWithData:(NSData *)data {\n    SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];\n    return imageRep;\n}\n\n// We should override init method for `NSBitmapImageRep` to do initialize about animated image format\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n- (instancetype)initWithData:(NSData *)data {\n    self = [super initWithData:data];\n    if (self) {\n        CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL);\n        if (!imageSource) {\n            return self;\n        }\n        _imageSource = imageSource;\n        NSUInteger frameCount = CGImageSourceGetCount(imageSource);\n        if (frameCount <= 1) {\n            return self;\n        }\n        CFStringRef type = CGImageSourceGetType(imageSource);\n        if (!type) {\n            return self;\n        }\n        if (CFStringCompare(type, kUTTypeGIF, 0) == kCFCompareEqualTo) {\n            // GIF\n            // Fix the `NSBitmapImageRep` GIF loop count calculation issue\n            // Which will use 0 when there are no loop count information metadata in GIF data\n            NSUInteger loopCount = [SDImageGIFCoder imageLoopCountWithSource:imageSource];\n            [self setProperty:NSImageLoopCount withValue:@(loopCount)];\n        } else if (CFStringCompare(type, kUTTypePNG, 0) == kCFCompareEqualTo) {\n            // APNG\n            // Do initialize about frame count, current frame/duration and loop count\n            [self setProperty:NSImageFrameCount withValue:@(frameCount)];\n            [self setProperty:NSImageCurrentFrame withValue:@(0)];\n            NSUInteger loopCount = [SDImageAPNGCoder imageLoopCountWithSource:imageSource];\n            [self setProperty:NSImageLoopCount withValue:@(loopCount)];\n        } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) {\n            // HEIC\n            // Do initialize about frame count, current frame/duration and loop count\n            [self setProperty:NSImageFrameCount withValue:@(frameCount)];\n            [self setProperty:NSImageCurrentFrame withValue:@(0)];\n            NSUInteger loopCount = [SDImageHEICCoder imageLoopCountWithSource:imageSource];\n            [self setProperty:NSImageLoopCount withValue:@(loopCount)];\n        } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {\n            // WebP\n            // Do initialize about frame count, current frame/duration and loop count\n            [self setProperty:NSImageFrameCount withValue:@(frameCount)];\n            [self setProperty:NSImageCurrentFrame withValue:@(0)];\n            NSUInteger loopCount = [SDImageAWebPCoder imageLoopCountWithSource:imageSource];\n            [self setProperty:NSImageLoopCount withValue:@(loopCount)];\n        }\n    }\n    return self;\n}\n\n// `NSBitmapImageRep` will use `kCGImagePropertyGIFDelayTime` whenever you call `setProperty:withValue:` with `NSImageCurrentFrame` to change the current frame. We override it and use the actual `kCGImagePropertyGIFUnclampedDelayTime` if need.\n- (void)setProperty:(NSBitmapImageRepPropertyKey)property withValue:(id)value {\n    [super setProperty:property withValue:value];\n    if ([property isEqualToString:NSImageCurrentFrame]) {\n        // Access the image source\n        CGImageSourceRef imageSource = _imageSource;\n        if (!imageSource) {\n            return;\n        }\n        // Check format type\n        CFStringRef type = CGImageSourceGetType(imageSource);\n        if (!type) {\n            return;\n        }\n        NSUInteger index = [value unsignedIntegerValue];\n        NSTimeInterval frameDuration = 0;\n        if (CFStringCompare(type, kUTTypeGIF, 0) == kCFCompareEqualTo) {\n            // GIF\n            frameDuration = [SDImageGIFCoder frameDurationAtIndex:index source:imageSource];\n        } else if (CFStringCompare(type, kUTTypePNG, 0) == kCFCompareEqualTo) {\n            // APNG\n            frameDuration = [SDImageAPNGCoder frameDurationAtIndex:index source:imageSource];\n        } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) {\n            // HEIC\n            frameDuration = [SDImageHEICCoder frameDurationAtIndex:index source:imageSource];\n        } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {\n            // WebP\n            frameDuration = [SDImageAWebPCoder frameDurationAtIndex:index source:imageSource];\n        }\n        if (!frameDuration) {\n            return;\n        }\n        // Reset super frame duration with the actual frame duration\n        [super setProperty:NSImageCurrentFrameDuration withValue:@(frameDuration)];\n    }\n}\n#pragma clang diagnostic pop\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAnimatedImageView.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#import \"SDWebImageManager.h\"\n\n/**\n Integrates SDWebImage async downloading and caching of remote images with SDAnimatedImageView.\n */\n@interface SDAnimatedImageView (WebCache)\n\n/**\n * Set the imageView `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url The url for the image.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @see sd_setImageWithURL:placeholderImage:options:\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the imageView `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAnimatedImageView+WebCache.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#import \"UIView+WebCache.h\"\n#import \"SDAnimatedImage.h\"\n\n@implementation SDAnimatedImageView (WebCache)\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock {\n    Class animatedImageClass = [SDAnimatedImage class];\n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    mutableContext[SDWebImageContextAnimatedImageClass] = animatedImageClass;\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:mutableContext\n                       setImageBlock:nil\n                            progress:progressBlock\n                           completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#import \"SDAnimatedImage.h\"\n#import \"SDAnimatedImagePlayer.h\"\n\n/**\n A drop-in replacement for UIImageView/NSImageView, you can use this for animated image rendering.\n Call `setImage:` with `UIImage(NSImage)` which conforms to `SDAnimatedImage` protocol will start animated image rendering. Call with normal UIImage(NSImage) will back to normal UIImageView(NSImageView) rendering\n For UIKit: use `-startAnimating`, `-stopAnimating` to control animating. `isAnimating` to check animation state.\n For AppKit: use `-setAnimates:` to control animating, `animates` to check animation state. This view is layer-backed.\n */\n@interface SDAnimatedImageView : UIImageView\n/**\n The internal animation player.\n This property is only used for advanced usage, like inspecting/debugging animation status, control progressive loading, complicated animation frame index control, etc.\n @warning Pay attention if you directly update the player's property like `totalFrameCount`, `totalLoopCount`, the same property on `SDAnimatedImageView` may not get synced.\n */\n@property (nonatomic, strong, readonly, nullable) SDAnimatedImagePlayer *player;\n\n/**\n Current display frame image. This value is KVO Compliance.\n */\n@property (nonatomic, strong, readonly, nullable) UIImage *currentFrame;\n/**\n Current frame index, zero based. This value is KVO Compliance.\n */\n@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex;\n/**\n Current loop count since its latest animating. This value is KVO Compliance.\n */\n@property (nonatomic, assign, readonly) NSUInteger currentLoopCount;\n/**\n YES to choose `animationRepeatCount` property for animation loop count. No to use animated image's `animatedImageLoopCount` instead.\n Default is NO.\n */\n@property (nonatomic, assign) BOOL shouldCustomLoopCount;\n/**\n Total loop count for animated image rendering. Default is animated image's loop count.\n If you need to set custom loop count, set `shouldCustomLoopCount` to YES and change this value.\n This class override UIImageView's `animationRepeatCount` property on iOS, use this property as well.\n */\n@property (nonatomic, assign) NSInteger animationRepeatCount;\n/**\n The animation playback rate. Default is 1.0.\n `1.0` means the normal speed.\n `0.0` means stopping the animation.\n `0.0-1.0` means the slow speed.\n `> 1.0` means the fast speed.\n `< 0.0` is not supported currently and stop animation. (may support reverse playback in the future)\n */\n@property (nonatomic, assign) double playbackRate;\n\n/// Asynchronous setup animation playback mode. Default mode is SDAnimatedImagePlaybackModeNormal.\n@property (nonatomic, assign) SDAnimatedImagePlaybackMode playbackMode;\n\n/**\n Provide a max buffer size by bytes. This is used to adjust frame buffer count and can be useful when the decoding cost is expensive (such as Animated WebP software decoding). Default is 0.\n `0` means automatically adjust by calculating current memory usage.\n `1` means without any buffer cache, each of frames will be decoded and then be freed after rendering. (Lowest Memory and Highest CPU)\n `NSUIntegerMax` means cache all the buffer. (Lowest CPU and Highest Memory)\n */\n@property (nonatomic, assign) NSUInteger maxBufferSize;\n/**\n Whehter or not to enable incremental image load for animated image. This is for the animated image which `sd_isIncremental` is YES (See `UIImage+Metadata.h`). If enable, animated image rendering will stop at the last frame available currently, and continue when another `setImage:` trigger, where the new animated image's `animatedImageData` should be updated from the previous one. If the `sd_isIncremental` is NO. The incremental image load stop.\n @note If you are confused about this description, open Chrome browser to view some large GIF images with low network speed to see the animation behavior.\n @note The best practice to use incremental load is using `initWithAnimatedCoder:scale:` in `SDAnimatedImage` with animated coder which conform to `SDProgressiveImageCoder` as well. Then call incremental update and incremental decode method to produce the image.\n Default is YES. Set to NO to only render the static poster for incremental animated image.\n */\n@property (nonatomic, assign) BOOL shouldIncrementalLoad;\n\n/**\n Whether or not to clear the frame buffer cache when animation stopped. See `maxBufferSize`\n This is useful when you want to limit the memory usage during frequently visibility changes (such as image view inside a list view, then push and pop)\n Default is NO.\n */\n@property (nonatomic, assign) BOOL clearBufferWhenStopped;\n\n/**\n Whether or not to reset the current frame index when animation stopped.\n For some of use case, you may want to reset the frame index to 0 when stop, but some other want to keep the current frame index.\n Default is NO.\n */\n@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped;\n\n/**\n If the image which conforms to `SDAnimatedImage` protocol has more than one frame, set this value to `YES` will automatically\n play/stop the animation when the view become visible/invisible.\n Default is YES.\n */\n@property (nonatomic, assign) BOOL autoPlayAnimatedImage;\n\n/**\n You can specify a runloop mode to let it rendering.\n Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device\n @note This is useful for some cases, for example, always specify NSDefaultRunLoopMode, if you want to pause the animation when user scroll (for Mac user, drag the mouse or touchpad)\n */\n@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode;\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAnimatedImageView.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#import \"UIImage+Metadata.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDInternalMacros.h\"\n#import \"objc/runtime.h\"\n\n@interface UIImageView () <CALayerDelegate>\n@end\n\n@interface SDAnimatedImageView () {\n    BOOL _initFinished; // Extra flag to mark the `commonInit` is called\n    NSRunLoopMode _runLoopMode;\n    NSUInteger _maxBufferSize;\n    double _playbackRate;\n    SDAnimatedImagePlaybackMode _playbackMode;\n}\n\n@property (nonatomic, strong, readwrite) SDAnimatedImagePlayer *player;\n@property (nonatomic, strong, readwrite) UIImage *currentFrame;\n@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex;\n@property (nonatomic, assign, readwrite) NSUInteger currentLoopCount;\n@property (nonatomic, assign) BOOL shouldAnimate;\n@property (nonatomic, assign) BOOL isProgressive;\n@property (nonatomic) CALayer *imageViewLayer; // The actual rendering layer.\n\n@end\n\n@implementation SDAnimatedImageView\n#if SD_UIKIT\n@dynamic animationRepeatCount; // we re-use this property from `UIImageView` super class on iOS.\n#endif\n\n#pragma mark - Initializers\n\n#if SD_MAC\n+ (instancetype)imageViewWithImage:(NSImage *)image\n{\n    NSRect frame = NSMakeRect(0, 0, image.size.width, image.size.height);\n    SDAnimatedImageView *imageView = [[SDAnimatedImageView alloc] initWithFrame:frame];\n    [imageView setImage:image];\n    return imageView;\n}\n#else\n// -initWithImage: isn't documented as a designated initializer of UIImageView, but it actually seems to be.\n// Using -initWithImage: doesn't call any of the other designated initializers.\n- (instancetype)initWithImage:(UIImage *)image\n{\n    self = [super initWithImage:image];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n\n// -initWithImage:highlightedImage: also isn't documented as a designated initializer of UIImageView, but it doesn't call any other designated initializers.\n- (instancetype)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage\n{\n    self = [super initWithImage:image highlightedImage:highlightedImage];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n#endif\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n\n- (instancetype)initWithCoder:(NSCoder *)aDecoder\n{\n    self = [super initWithCoder:aDecoder];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n\n- (void)commonInit\n{\n    // Pay attention that UIKit's `initWithImage:` will trigger a `setImage:` during initialization before this `commonInit`.\n    // So the properties which rely on this order, should using lazy-evaluation or do extra check in `setImage:`.\n    self.autoPlayAnimatedImage = YES;\n    self.shouldCustomLoopCount = NO;\n    self.shouldIncrementalLoad = YES;\n    self.playbackRate = 1.0;\n#if SD_MAC\n    self.wantsLayer = YES;\n#endif\n    // Mark commonInit finished\n    _initFinished = YES;\n}\n\n#pragma mark - Accessors\n#pragma mark Public\n\n- (void)setImage:(UIImage *)image\n{\n    if (self.image == image) {\n        return;\n    }\n    \n    // Check Progressive rendering\n    [self updateIsProgressiveWithImage:image];\n    \n    if (!self.isProgressive) {\n        // Stop animating\n        self.player = nil;\n        self.currentFrame = nil;\n        self.currentFrameIndex = 0;\n        self.currentLoopCount = 0;\n    }\n    \n    // We need call super method to keep function. This will impliedly call `setNeedsDisplay`. But we have no way to avoid this when using animated image. So we call `setNeedsDisplay` again at the end.\n    super.image = image;\n    if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {\n        if (!self.player) {\n            id<SDAnimatedImageProvider> provider;\n            // Check progressive loading\n            if (self.isProgressive) {\n                provider = [self progressiveAnimatedCoderForImage:image];\n            } else {\n                provider = (id<SDAnimatedImage>)image;\n            }\n            // Create animated player\n            self.player = [SDAnimatedImagePlayer playerWithProvider:provider];\n        } else {\n            // Update Frame Count\n            self.player.totalFrameCount = [(id<SDAnimatedImage>)image animatedImageFrameCount];\n        }\n        \n        if (!self.player) {\n            // animated player nil means the image format is not supported, or frame count <= 1\n            return;\n        }\n        \n        // Custom Loop Count\n        if (self.shouldCustomLoopCount) {\n            self.player.totalLoopCount = self.animationRepeatCount;\n        }\n        \n        // RunLoop Mode\n        self.player.runLoopMode = self.runLoopMode;\n        \n        // Max Buffer Size\n        self.player.maxBufferSize = self.maxBufferSize;\n        \n        // Play Rate\n        self.player.playbackRate = self.playbackRate;\n        \n        // Play Mode\n        self.player.playbackMode = self.playbackMode;\n\n        // Setup handler\n        @weakify(self);\n        self.player.animationFrameHandler = ^(NSUInteger index, UIImage * frame) {\n            @strongify(self);\n            self.currentFrameIndex = index;\n            self.currentFrame = frame;\n            [self.imageViewLayer setNeedsDisplay];\n        };\n        self.player.animationLoopHandler = ^(NSUInteger loopCount) {\n            @strongify(self);\n            // Progressive image reach the current last frame index. Keep the state and pause animating. Wait for later restart\n            if (self.isProgressive) {\n                NSUInteger lastFrameIndex = self.player.totalFrameCount - 1;\n                [self.player seekToFrameAtIndex:lastFrameIndex loopCount:0];\n                [self.player pausePlaying];\n            } else {\n                self.currentLoopCount = loopCount;\n            }\n        };\n        \n        // Ensure disabled highlighting; it's not supported (see `-setHighlighted:`).\n        super.highlighted = NO;\n        \n        [self stopAnimating];\n        [self checkPlay];\n\n        [self.imageViewLayer setNeedsDisplay];\n    }\n}\n\n#pragma mark - Configuration\n\n- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode\n{\n    _runLoopMode = [runLoopMode copy];\n    self.player.runLoopMode = runLoopMode;\n}\n\n- (NSRunLoopMode)runLoopMode\n{\n    if (!_runLoopMode) {\n        _runLoopMode = [[self class] defaultRunLoopMode];\n    }\n    return _runLoopMode;\n}\n\n+ (NSString *)defaultRunLoopMode {\n    // Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations.\n    return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;\n}\n\n- (void)setMaxBufferSize:(NSUInteger)maxBufferSize\n{\n    _maxBufferSize = maxBufferSize;\n    self.player.maxBufferSize = maxBufferSize;\n}\n\n- (NSUInteger)maxBufferSize {\n    return _maxBufferSize; // Defaults to 0\n}\n\n- (void)setPlaybackRate:(double)playbackRate\n{\n    _playbackRate = playbackRate;\n    self.player.playbackRate = playbackRate;\n}\n\n- (double)playbackRate\n{\n    if (!_initFinished) {\n        return 1.0; // Defaults to 1.0\n    }\n    return _playbackRate;\n}\n\n- (void)setPlaybackMode:(SDAnimatedImagePlaybackMode)playbackMode {\n    _playbackMode = playbackMode;\n    self.player.playbackMode = playbackMode;\n}\n\n- (SDAnimatedImagePlaybackMode)playbackMode {\n    if (!_initFinished) {\n        return SDAnimatedImagePlaybackModeNormal; // Default mode is normal\n    }\n    return _playbackMode;\n}\n\n\n- (BOOL)shouldIncrementalLoad\n{\n    if (!_initFinished) {\n        return YES; // Defaults to YES\n    }\n    return _initFinished;\n}\n\n#pragma mark - UIView Method Overrides\n#pragma mark Observing View-Related Changes\n\n#if SD_MAC\n- (void)viewDidMoveToSuperview\n#else\n- (void)didMoveToSuperview\n#endif\n{\n#if SD_MAC\n    [super viewDidMoveToSuperview];\n#else\n    [super didMoveToSuperview];\n#endif\n    \n    [self checkPlay];\n}\n\n#if SD_MAC\n- (void)viewDidMoveToWindow\n#else\n- (void)didMoveToWindow\n#endif\n{\n#if SD_MAC\n    [super viewDidMoveToWindow];\n#else\n    [super didMoveToWindow];\n#endif\n    \n    [self checkPlay];\n}\n\n#if SD_MAC\n- (void)setAlphaValue:(CGFloat)alphaValue\n#else\n- (void)setAlpha:(CGFloat)alpha\n#endif\n{\n#if SD_MAC\n    [super setAlphaValue:alphaValue];\n#else\n    [super setAlpha:alpha];\n#endif\n    \n    [self checkPlay];\n}\n\n- (void)setHidden:(BOOL)hidden\n{\n    [super setHidden:hidden];\n    \n    [self checkPlay];\n}\n\n#pragma mark - UIImageView Method Overrides\n#pragma mark Image Data\n\n- (void)setAnimationRepeatCount:(NSInteger)animationRepeatCount\n{\n#if SD_UIKIT\n    [super setAnimationRepeatCount:animationRepeatCount];\n#else\n    _animationRepeatCount = animationRepeatCount;\n#endif\n    \n    if (self.shouldCustomLoopCount) {\n        self.player.totalLoopCount = animationRepeatCount;\n    }\n}\n\n- (void)startAnimating\n{\n    if (self.player) {\n        [self updateShouldAnimate];\n        if (self.shouldAnimate) {\n            [self.player startPlaying];\n        }\n    } else {\n#if SD_UIKIT\n        [super startAnimating];\n#else\n        [super setAnimates:YES];\n#endif\n    }\n}\n\n- (void)stopAnimating\n{\n    if (self.player) {\n        if (self.resetFrameIndexWhenStopped) {\n            [self.player stopPlaying];\n        } else {\n            [self.player pausePlaying];\n        }\n        if (self.clearBufferWhenStopped) {\n            [self.player clearFrameBuffer];\n        }\n    } else {\n#if SD_UIKIT\n        [super stopAnimating];\n#else\n        [super setAnimates:NO];\n#endif\n    }\n}\n\n#if SD_UIKIT\n- (BOOL)isAnimating\n{\n    if (self.player) {\n        return self.player.isPlaying;\n    } else {\n        return [super isAnimating];\n    }\n}\n#endif\n\n#if SD_MAC\n- (BOOL)animates\n{\n    if (self.player) {\n        return self.player.isPlaying;\n    } else {\n        return [super animates];\n    }\n}\n\n- (void)setAnimates:(BOOL)animates\n{\n    if (animates) {\n        [self startAnimating];\n    } else {\n        [self stopAnimating];\n    }\n}\n#endif\n\n#pragma mark Highlighted Image Unsupport\n\n- (void)setHighlighted:(BOOL)highlighted\n{\n    // Highlighted image is unsupported for animated images, but implementing it breaks the image view when embedded in a UICollectionViewCell.\n    if (!self.player) {\n        [super setHighlighted:highlighted];\n    }\n}\n\n\n#pragma mark - Private Methods\n#pragma mark Animation\n\n/// Check if it should be played\n- (void)checkPlay\n{\n    // Only handle for SDAnimatedImage, leave UIAnimatedImage or animationImages for super implementation control\n    if (self.player && self.autoPlayAnimatedImage) {\n        [self updateShouldAnimate];\n        if (self.shouldAnimate) {\n            [self startAnimating];\n        } else {\n            [self stopAnimating];\n        }\n    }\n}\n\n// Don't repeatedly check our window & superview in `-displayDidRefresh:` for performance reasons.\n// Just update our cached value whenever the animated image or visibility (window, superview, hidden, alpha) is changed.\n- (void)updateShouldAnimate\n{\n#if SD_MAC\n    BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alphaValue > 0.0;\n#else\n    BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alpha > 0.0;\n#endif\n    self.shouldAnimate = self.player && isVisible;\n}\n\n// Update progressive status only after `setImage:` call.\n- (void)updateIsProgressiveWithImage:(UIImage *)image\n{\n    self.isProgressive = NO;\n    if (!self.shouldIncrementalLoad) {\n        // Early return\n        return;\n    }\n    // We must use `image.class conformsToProtocol:` instead of `image conformsToProtocol:` here\n    // Because UIKit on macOS, using internal hard-coded override method, which returns NO\n    id<SDAnimatedImageCoder> currentAnimatedCoder = [self progressiveAnimatedCoderForImage:image];\n    if (currentAnimatedCoder) {\n        UIImage *previousImage = self.image;\n        if (!previousImage) {\n            // If current animated coder supports progressive, and no previous image to check, start progressive loading\n            self.isProgressive = YES;\n        } else {\n            id<SDAnimatedImageCoder> previousAnimatedCoder = [self progressiveAnimatedCoderForImage:previousImage];\n            if (previousAnimatedCoder == currentAnimatedCoder) {\n                // If current animated coder is the same as previous, start progressive loading\n                self.isProgressive = YES;\n            }\n        }\n    }\n}\n\n// Check if image can represent a `Progressive Animated Image` during loading\n- (id<SDAnimatedImageCoder, SDProgressiveImageCoder>)progressiveAnimatedCoderForImage:(UIImage *)image\n{\n    if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)] && image.sd_isIncremental && [image respondsToSelector:@selector(animatedCoder)]) {\n        id<SDAnimatedImageCoder> animatedCoder = [(id<SDAnimatedImage>)image animatedCoder];\n        if ([animatedCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) {\n            return (id<SDAnimatedImageCoder, SDProgressiveImageCoder>)animatedCoder;\n        }\n    }\n    return nil;\n}\n\n\n#pragma mark Providing the Layer's Content\n#pragma mark - CALayerDelegate\n\n- (void)displayLayer:(CALayer *)layer\n{\n    UIImage *currentFrame = self.currentFrame;\n    if (currentFrame) {\n        layer.contentsScale = currentFrame.scale;\n        layer.contents = (__bridge id)currentFrame.CGImage;\n    } else {\n        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.\n        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {\n            [super displayLayer:layer];\n        }\n    }\n}\n\n#if SD_MAC\n// NSImageView use a subview. We need this subview's layer for actual rendering.\n// Why using this design may because of properties like `imageAlignment` and `imageScaling`, which it's not available for UIImageView.contentMode (it's impossible to align left and keep aspect ratio at the same time)\n- (NSView *)imageView {\n    NSImageView *imageView = objc_getAssociatedObject(self, SD_SEL_SPI(imageView));\n    if (!imageView) {\n        // macOS 10.14\n        imageView = objc_getAssociatedObject(self, SD_SEL_SPI(imageSubview));\n    }\n    return imageView;\n}\n\n// on macOS, it's the imageView subview's layer (we use layer-hosting view to let CALayerDelegate works)\n- (CALayer *)imageViewLayer {\n    NSView *imageView = self.imageView;\n    if (!imageView) {\n        return nil;\n    }\n    if (!_imageViewLayer) {\n        _imageViewLayer = [CALayer new];\n        _imageViewLayer.delegate = self;\n        imageView.layer = _imageViewLayer;\n        imageView.wantsLayer = YES;\n    }\n    return _imageViewLayer;\n}\n#else\n// on iOS, it's the imageView itself's layer\n- (CALayer *)imageViewLayer {\n    return self.layer;\n}\n\n#endif\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDDiskCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n@class SDImageCacheConfig;\n/**\n A protocol to allow custom disk cache used in SDImageCache.\n */\n@protocol SDDiskCache <NSObject>\n\n// All of these method are called from the same global queue to avoid blocking on main queue and thread-safe problem. But it's also recommend to ensure thread-safe yourself using lock or other ways.\n@required\n/**\n Create a new disk cache based on the specified path. You can check `maxDiskSize` and `maxDiskAge` used for disk cache.\n \n @param cachePath Full path of a directory in which the cache will write data.\n Once initialized you should not read and write to this directory.\n @param config The cache config to be used to create the cache.\n \n @return A new cache object, or nil if an error occurs.\n */\n- (nullable instancetype)initWithCachePath:(nonnull NSString *)cachePath config:(nonnull SDImageCacheConfig *)config;\n\n/**\n Returns a boolean value that indicates whether a given key is in cache.\n This method may blocks the calling thread until file read finished.\n \n @param key A string identifying the data. If nil, just return NO.\n @return Whether the key is in cache.\n */\n- (BOOL)containsDataForKey:(nonnull NSString *)key;\n\n/**\n Returns the data associated with a given key.\n This method may blocks the calling thread until file read finished.\n \n @param key A string identifying the data. If nil, just return nil.\n @return The value associated with key, or nil if no value is associated with key.\n */\n- (nullable NSData *)dataForKey:(nonnull NSString *)key;\n\n/**\n Sets the value of the specified key in the cache.\n This method may blocks the calling thread until file write finished.\n \n @param data The data to be stored in the cache.\n @param key    The key with which to associate the value. If nil, this method has no effect.\n */\n- (void)setData:(nullable NSData *)data forKey:(nonnull NSString *)key;\n\n/**\n Returns the extended data associated with a given key.\n This method may blocks the calling thread until file read finished.\n \n @param key A string identifying the data. If nil, just return nil.\n @return The value associated with key, or nil if no value is associated with key.\n */\n- (nullable NSData *)extendedDataForKey:(nonnull NSString *)key;\n\n/**\n Set extended data with a given key.\n \n @discussion You can set any extended data to exist cache key. Without override the exist disk file data.\n on UNIX, the common way for this is to use the Extended file attributes (xattr)\n \n @param extendedData The extended data (pass nil to remove).\n @param key The key with which to associate the value. If nil, this method has no effect.\n*/\n- (void)setExtendedData:(nullable NSData *)extendedData forKey:(nonnull NSString *)key;\n\n/**\n Removes the value of the specified key in the cache.\n This method may blocks the calling thread until file delete finished.\n \n @param key The key identifying the value to be removed. If nil, this method has no effect.\n */\n- (void)removeDataForKey:(nonnull NSString *)key;\n\n/**\n Empties the cache.\n This method may blocks the calling thread until file delete finished.\n */\n- (void)removeAllData;\n\n/**\n Removes the expired data from the cache. You can choose the data to remove base on `ageLimit`, `countLimit` and `sizeLimit` options.\n */\n- (void)removeExpiredData;\n\n/**\n The cache path for key\n\n @param key A string identifying the value\n @return The cache path for key. Or nil if the key can not associate to a path\n */\n- (nullable NSString *)cachePathForKey:(nonnull NSString *)key;\n\n/**\n Returns the number of data in this cache.\n This method may blocks the calling thread until file read finished.\n \n @return The total data count.\n */\n- (NSUInteger)totalCount;\n\n/**\n Returns the total size (in bytes) of data in this cache.\n This method may blocks the calling thread until file read finished.\n \n @return The total data size in bytes.\n */\n- (NSUInteger)totalSize;\n\n@end\n\n/**\n The built-in disk cache.\n */\n@interface SDDiskCache : NSObject <SDDiskCache>\n/**\n Cache Config object - storing all kind of settings.\n */\n@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n\n/**\n Move the cache directory from old location to new location, the old location will be removed after finish.\n If the old location does not exist, does nothing.\n If the new location does not exist, only do a movement of directory.\n If the new location does exist, will move and merge the files from old location.\n If the new location does exist, but is not a directory, will remove it and do a movement of directory.\n\n @param srcPath old location of cache directory\n @param dstPath new location of cache directory\n */\n- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDDiskCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDDiskCache.h\"\n#import \"SDImageCacheConfig.h\"\n#import \"SDFileAttributeHelper.h\"\n#import <CommonCrypto/CommonDigest.h>\n\nstatic NSString * const SDDiskCacheExtendedAttributeName = @\"com.hackemist.SDDiskCache\";\n\n@interface SDDiskCache ()\n\n@property (nonatomic, copy) NSString *diskCachePath;\n@property (nonatomic, strong, nonnull) NSFileManager *fileManager;\n\n@end\n\n@implementation SDDiskCache\n\n- (instancetype)init {\n    NSAssert(NO, @\"Use `initWithCachePath:` with the disk cache path\");\n    return nil;\n}\n\n#pragma mark - SDcachePathForKeyDiskCache Protocol\n- (instancetype)initWithCachePath:(NSString *)cachePath config:(nonnull SDImageCacheConfig *)config {\n    if (self = [super init]) {\n        _diskCachePath = cachePath;\n        _config = config;\n        [self commonInit];\n    }\n    return self;\n}\n\n- (void)commonInit {\n    if (self.config.fileManager) {\n        self.fileManager = self.config.fileManager;\n    } else {\n        self.fileManager = [NSFileManager new];\n    }\n}\n\n- (BOOL)containsDataForKey:(NSString *)key {\n    NSParameterAssert(key);\n    NSString *filePath = [self cachePathForKey:key];\n    BOOL exists = [self.fileManager fileExistsAtPath:filePath];\n    \n    // fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name\n    // checking the key with and without the extension\n    if (!exists) {\n        exists = [self.fileManager fileExistsAtPath:filePath.stringByDeletingPathExtension];\n    }\n    \n    return exists;\n}\n\n- (NSData *)dataForKey:(NSString *)key {\n    NSParameterAssert(key);\n    NSString *filePath = [self cachePathForKey:key];\n    NSData *data = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil];\n    if (data) {\n        return data;\n    }\n    \n    // fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name\n    // checking the key with and without the extension\n    data = [NSData dataWithContentsOfFile:filePath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];\n    if (data) {\n        return data;\n    }\n    \n    return nil;\n}\n\n- (void)setData:(NSData *)data forKey:(NSString *)key {\n    NSParameterAssert(data);\n    NSParameterAssert(key);\n    if (![self.fileManager fileExistsAtPath:self.diskCachePath]) {\n        [self.fileManager createDirectoryAtPath:self.diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];\n    }\n    \n    // get cache Path for image key\n    NSString *cachePathForKey = [self cachePathForKey:key];\n    // transform to NSURL\n    NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey];\n    \n    [data writeToURL:fileURL options:self.config.diskCacheWritingOptions error:nil];\n    \n    // disable iCloud backup\n    if (self.config.shouldDisableiCloud) {\n        // ignore iCloud backup resource value error\n        [fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];\n    }\n}\n\n- (NSData *)extendedDataForKey:(NSString *)key {\n    NSParameterAssert(key);\n    \n    // get cache Path for image key\n    NSString *cachePathForKey = [self cachePathForKey:key];\n    \n    NSData *extendedData = [SDFileAttributeHelper extendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil];\n    \n    return extendedData;\n}\n\n- (void)setExtendedData:(NSData *)extendedData forKey:(NSString *)key {\n    NSParameterAssert(key);\n    // get cache Path for image key\n    NSString *cachePathForKey = [self cachePathForKey:key];\n    \n    if (!extendedData) {\n        // Remove\n        [SDFileAttributeHelper removeExtendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil];\n    } else {\n        // Override\n        [SDFileAttributeHelper setExtendedAttribute:SDDiskCacheExtendedAttributeName value:extendedData atPath:cachePathForKey traverseLink:NO overwrite:YES error:nil];\n    }\n}\n\n- (void)removeDataForKey:(NSString *)key {\n    NSParameterAssert(key);\n    NSString *filePath = [self cachePathForKey:key];\n    [self.fileManager removeItemAtPath:filePath error:nil];\n}\n\n- (void)removeAllData {\n    [self.fileManager removeItemAtPath:self.diskCachePath error:nil];\n    [self.fileManager createDirectoryAtPath:self.diskCachePath\n            withIntermediateDirectories:YES\n                             attributes:nil\n                                  error:NULL];\n}\n\n- (void)removeExpiredData {\n    NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];\n    \n    // Compute content date key to be used for tests\n    NSURLResourceKey cacheContentDateKey = NSURLContentModificationDateKey;\n    switch (self.config.diskCacheExpireType) {\n        case SDImageCacheConfigExpireTypeAccessDate:\n            cacheContentDateKey = NSURLContentAccessDateKey;\n            break;\n        case SDImageCacheConfigExpireTypeModificationDate:\n            cacheContentDateKey = NSURLContentModificationDateKey;\n            break;\n        case SDImageCacheConfigExpireTypeCreationDate:\n            cacheContentDateKey = NSURLCreationDateKey;\n            break;\n        case SDImageCacheConfigExpireTypeChangeDate:\n            cacheContentDateKey = NSURLAttributeModificationDateKey;\n            break;\n        default:\n            break;\n    }\n    \n    NSArray<NSString *> *resourceKeys = @[NSURLIsDirectoryKey, cacheContentDateKey, NSURLTotalFileAllocatedSizeKey];\n    \n    // This enumerator prefetches useful properties for our cache files.\n    NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtURL:diskCacheURL\n                                               includingPropertiesForKeys:resourceKeys\n                                                                  options:NSDirectoryEnumerationSkipsHiddenFiles\n                                                             errorHandler:NULL];\n    \n    NSDate *expirationDate = (self.config.maxDiskAge < 0) ? nil: [NSDate dateWithTimeIntervalSinceNow:-self.config.maxDiskAge];\n    NSMutableDictionary<NSURL *, NSDictionary<NSString *, id> *> *cacheFiles = [NSMutableDictionary dictionary];\n    NSUInteger currentCacheSize = 0;\n    \n    // Enumerate all of the files in the cache directory.  This loop has two purposes:\n    //\n    //  1. Removing files that are older than the expiration date.\n    //  2. Storing file attributes for the size-based cleanup pass.\n    NSMutableArray<NSURL *> *urlsToDelete = [[NSMutableArray alloc] init];\n    for (NSURL *fileURL in fileEnumerator) {\n        NSError *error;\n        NSDictionary<NSString *, id> *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:&error];\n        \n        // Skip directories and errors.\n        if (error || !resourceValues || [resourceValues[NSURLIsDirectoryKey] boolValue]) {\n            continue;\n        }\n        \n        // Remove files that are older than the expiration date;\n        NSDate *modifiedDate = resourceValues[cacheContentDateKey];\n        if (expirationDate && [[modifiedDate laterDate:expirationDate] isEqualToDate:expirationDate]) {\n            [urlsToDelete addObject:fileURL];\n            continue;\n        }\n        \n        // Store a reference to this file and account for its total size.\n        NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];\n        currentCacheSize += totalAllocatedSize.unsignedIntegerValue;\n        cacheFiles[fileURL] = resourceValues;\n    }\n    \n    for (NSURL *fileURL in urlsToDelete) {\n        [self.fileManager removeItemAtURL:fileURL error:nil];\n    }\n    \n    // If our remaining disk cache exceeds a configured maximum size, perform a second\n    // size-based cleanup pass.  We delete the oldest files first.\n    NSUInteger maxDiskSize = self.config.maxDiskSize;\n    if (maxDiskSize > 0 && currentCacheSize > maxDiskSize) {\n        // Target half of our maximum cache size for this cleanup pass.\n        const NSUInteger desiredCacheSize = maxDiskSize / 2;\n        \n        // Sort the remaining cache files by their last modification time or last access time (oldest first).\n        NSArray<NSURL *> *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent\n                                                                 usingComparator:^NSComparisonResult(id obj1, id obj2) {\n                                                                     return [obj1[cacheContentDateKey] compare:obj2[cacheContentDateKey]];\n                                                                 }];\n        \n        // Delete files until we fall below our desired cache size.\n        for (NSURL *fileURL in sortedFiles) {\n            if ([self.fileManager removeItemAtURL:fileURL error:nil]) {\n                NSDictionary<NSString *, id> *resourceValues = cacheFiles[fileURL];\n                NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];\n                currentCacheSize -= totalAllocatedSize.unsignedIntegerValue;\n                \n                if (currentCacheSize < desiredCacheSize) {\n                    break;\n                }\n            }\n        }\n    }\n}\n\n- (nullable NSString *)cachePathForKey:(NSString *)key {\n    NSParameterAssert(key);\n    return [self cachePathForKey:key inPath:self.diskCachePath];\n}\n\n- (NSUInteger)totalSize {\n    NSUInteger size = 0;\n    NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtPath:self.diskCachePath];\n    for (NSString *fileName in fileEnumerator) {\n        NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];\n        NSDictionary<NSString *, id> *attrs = [self.fileManager attributesOfItemAtPath:filePath error:nil];\n        size += [attrs fileSize];\n    }\n    return size;\n}\n\n- (NSUInteger)totalCount {\n    NSUInteger count = 0;\n    NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtPath:self.diskCachePath];\n    count = fileEnumerator.allObjects.count;\n    return count;\n}\n\n#pragma mark - Cache paths\n\n- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path {\n    NSString *filename = SDDiskCacheFileNameForKey(key);\n    return [path stringByAppendingPathComponent:filename];\n}\n\n- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath {\n    NSParameterAssert(srcPath);\n    NSParameterAssert(dstPath);\n    // Check if old path is equal to new path\n    if ([srcPath isEqualToString:dstPath]) {\n        return;\n    }\n    BOOL isDirectory;\n    // Check if old path is directory\n    if (![self.fileManager fileExistsAtPath:srcPath isDirectory:&isDirectory] || !isDirectory) {\n        return;\n    }\n    // Check if new path is directory\n    if (![self.fileManager fileExistsAtPath:dstPath isDirectory:&isDirectory] || !isDirectory) {\n        if (!isDirectory) {\n            // New path is not directory, remove file\n            [self.fileManager removeItemAtPath:dstPath error:nil];\n        }\n        NSString *dstParentPath = [dstPath stringByDeletingLastPathComponent];\n        // Creates any non-existent parent directories as part of creating the directory in path\n        if (![self.fileManager fileExistsAtPath:dstParentPath]) {\n            [self.fileManager createDirectoryAtPath:dstParentPath withIntermediateDirectories:YES attributes:nil error:NULL];\n        }\n        // New directory does not exist, rename directory\n        [self.fileManager moveItemAtPath:srcPath toPath:dstPath error:nil];\n    } else {\n        // New directory exist, merge the files\n        NSDirectoryEnumerator *dirEnumerator = [self.fileManager enumeratorAtPath:srcPath];\n        NSString *file;\n        while ((file = [dirEnumerator nextObject])) {\n            [self.fileManager moveItemAtPath:[srcPath stringByAppendingPathComponent:file] toPath:[dstPath stringByAppendingPathComponent:file] error:nil];\n        }\n        // Remove the old path\n        [self.fileManager removeItemAtPath:srcPath error:nil];\n    }\n}\n\n#pragma mark - Hash\n\n#define SD_MAX_FILE_EXTENSION_LENGTH (NAME_MAX - CC_MD5_DIGEST_LENGTH * 2 - 1)\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\nstatic inline NSString * _Nonnull SDDiskCacheFileNameForKey(NSString * _Nullable key) {\n    const char *str = key.UTF8String;\n    if (str == NULL) {\n        str = \"\";\n    }\n    unsigned char r[CC_MD5_DIGEST_LENGTH];\n    CC_MD5(str, (CC_LONG)strlen(str), r);\n    NSURL *keyURL = [NSURL URLWithString:key];\n    NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension;\n    // File system has file name length limit, we need to check if ext is too long, we don't add it to the filename\n    if (ext.length > SD_MAX_FILE_EXTENSION_LENGTH) {\n        ext = nil;\n    }\n    NSString *filename = [NSString stringWithFormat:@\"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@\",\n                          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],\n                          r[11], r[12], r[13], r[14], r[15], ext.length == 0 ? @\"\" : [NSString stringWithFormat:@\".%@\", ext]];\n    return filename;\n}\n#pragma clang diagnostic pop\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDWebImageCompat.h\"\n\n/**\n These following class are provided to use `UIGraphicsImageRenderer` with polyfill, which allows write cross-platform(AppKit/UIKit) code and avoid runtime version check.\n Compared to `UIGraphicsBeginImageContext`, `UIGraphicsImageRenderer` use dynamic bitmap from your draw code to generate CGContext, not always use ARGB8888, which is more performant on RAM usage.\n Which means, if you draw CGImage/CIImage which contains grayscale only, the underlaying bitmap context use grayscale, it's managed by system and not a fixed type. (actually, the `kCGContextTypeAutomatic`)\n For usage, See more in Apple's documentation: https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer\n For UIKit on iOS/tvOS 10+, these method just use the same `UIGraphicsImageRenderer` API.\n For others (macOS/watchOS or iOS/tvOS 10-), these method use the `SDImageGraphics.h` to implements the same behavior (but without dynamic bitmap support)\n*/\n\ntypedef void (^SDGraphicsImageDrawingActions)(CGContextRef _Nonnull context);\ntypedef NS_ENUM(NSInteger, SDGraphicsImageRendererFormatRange) {\n    SDGraphicsImageRendererFormatRangeUnspecified = -1,\n    SDGraphicsImageRendererFormatRangeAutomatic = 0,\n    SDGraphicsImageRendererFormatRangeExtended,\n    SDGraphicsImageRendererFormatRangeStandard\n};\n\n/// A set of drawing attributes that represent the configuration of an image renderer context.\n@interface SDGraphicsImageRendererFormat : NSObject\n\n/// The display scale of the image renderer context.\n/// The default value is equal to the scale of the main screen.\n@property (nonatomic) CGFloat scale;\n\n/// A Boolean value indicating whether the underlying Core Graphics context has an alpha channel.\n/// The default value is NO.\n@property (nonatomic) BOOL opaque;\n\n/// Specifying whether the bitmap context should use extended color.\n/// For iOS 12+, the value is from system `preferredRange` property\n/// For iOS 10-11, the value is from system `prefersExtendedRange` property\n/// For iOS 9-, the value is `.standard`\n@property (nonatomic) SDGraphicsImageRendererFormatRange preferredRange;\n\n/// Init the default format. See each properties's default value.\n- (nonnull instancetype)init;\n\n/// Returns a new format best suited for the main screen’s current configuration.\n+ (nonnull instancetype)preferredFormat;\n\n@end\n\n/// A graphics renderer for creating Core Graphics-backed images.\n@interface SDGraphicsImageRenderer : NSObject\n\n/// Creates an image renderer for drawing images of a given size.\n/// @param size The size of images output from the renderer, specified in points.\n/// @return An initialized image renderer.\n- (nonnull instancetype)initWithSize:(CGSize)size;\n\n/// Creates a new image renderer with a given size and format.\n/// @param size The size of images output from the renderer, specified in points.\n/// @param format A SDGraphicsImageRendererFormat object that encapsulates the format used to create the renderer context.\n/// @return An initialized image renderer.\n- (nonnull instancetype)initWithSize:(CGSize)size format:(nonnull SDGraphicsImageRendererFormat *)format;\n\n/// Creates an image by following a set of drawing instructions.\n/// @param actions A SDGraphicsImageDrawingActions block that, when invoked by the renderer, executes a set of drawing instructions to create the output image.\n/// @note You should not retain or use the context outside the block, it's non-escaping.\n/// @return A UIImage object created by the supplied drawing actions.\n- (nonnull UIImage *)imageWithActions:(nonnull NS_NOESCAPE SDGraphicsImageDrawingActions)actions;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDGraphicsImageRenderer.h\"\n#import \"SDImageGraphics.h\"\n\n@interface SDGraphicsImageRendererFormat ()\n#if SD_UIKIT\n@property (nonatomic, strong) UIGraphicsImageRendererFormat *uiformat API_AVAILABLE(ios(10.0), tvos(10.0));\n#endif\n@end\n\n@implementation SDGraphicsImageRendererFormat\n@synthesize scale = _scale;\n@synthesize opaque = _opaque;\n@synthesize preferredRange = _preferredRange;\n\n#pragma mark - Property\n- (CGFloat)scale {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        return self.uiformat.scale;\n    } else {\n        return _scale;\n    }\n#else\n    return _scale;\n#endif\n}\n\n- (void)setScale:(CGFloat)scale {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        self.uiformat.scale = scale;\n    } else {\n        _scale = scale;\n    }\n#else\n    _scale = scale;\n#endif\n}\n\n- (BOOL)opaque {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        return self.uiformat.opaque;\n    } else {\n        return _opaque;\n    }\n#else\n    return _opaque;\n#endif\n}\n\n- (void)setOpaque:(BOOL)opaque {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        self.uiformat.opaque = opaque;\n    } else {\n        _opaque = opaque;\n    }\n#else\n    _opaque = opaque;\n#endif\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n- (SDGraphicsImageRendererFormatRange)preferredRange {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        if (@available(iOS 12.0, tvOS 12.0, *)) {\n            return (SDGraphicsImageRendererFormatRange)self.uiformat.preferredRange;\n        } else {\n            BOOL prefersExtendedRange = self.uiformat.prefersExtendedRange;\n            if (prefersExtendedRange) {\n                return SDGraphicsImageRendererFormatRangeExtended;\n            } else {\n                return SDGraphicsImageRendererFormatRangeStandard;\n            }\n        }\n    } else {\n        return _preferredRange;\n    }\n#else\n    return _preferredRange;\n#endif\n}\n\n- (void)setPreferredRange:(SDGraphicsImageRendererFormatRange)preferredRange {\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.10, *)) {\n        if (@available(iOS 12.0, tvOS 12.0, *)) {\n            self.uiformat.preferredRange = (UIGraphicsImageRendererFormatRange)preferredRange;\n        } else {\n            switch (preferredRange) {\n                case SDGraphicsImageRendererFormatRangeExtended:\n                    self.uiformat.prefersExtendedRange = YES;\n                    break;\n                case SDGraphicsImageRendererFormatRangeStandard:\n                    self.uiformat.prefersExtendedRange = NO;\n                default:\n                    // Automatic means default\n                    break;\n            }\n        }\n    } else {\n        _preferredRange = preferredRange;\n    }\n#else\n    _preferredRange = preferredRange;\n#endif\n}\n#pragma clang diagnostic pop\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n#if SD_UIKIT\n        if (@available(iOS 10.0, tvOS 10.10, *)) {\n            UIGraphicsImageRendererFormat *uiformat = [[UIGraphicsImageRendererFormat alloc] init];\n            self.uiformat = uiformat;\n        } else {\n#endif\n#if SD_WATCH\n            CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale;\n#elif SD_UIKIT\n            CGFloat screenScale = [UIScreen mainScreen].scale;\n#elif SD_MAC\n            CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor;\n#endif\n            self.scale = screenScale;\n            self.opaque = NO;\n            self.preferredRange = SDGraphicsImageRendererFormatRangeStandard;\n#if SD_UIKIT\n        }\n#endif\n    }\n    return self;\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n- (instancetype)initForMainScreen {\n    self = [super init];\n    if (self) {\n#if SD_UIKIT\n        if (@available(iOS 10.0, tvOS 10.0, *)) {\n            UIGraphicsImageRendererFormat *uiformat;\n            // iOS 11.0.0 GM does have `preferredFormat`, but iOS 11 betas did not (argh!)\n            if ([UIGraphicsImageRenderer respondsToSelector:@selector(preferredFormat)]) {\n                uiformat = [UIGraphicsImageRendererFormat preferredFormat];\n            } else {\n                uiformat = [UIGraphicsImageRendererFormat defaultFormat];\n            }\n            self.uiformat = uiformat;\n        } else {\n#endif\n#if SD_WATCH\n            CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale;\n#elif SD_UIKIT\n            CGFloat screenScale = [UIScreen mainScreen].scale;\n#elif SD_MAC\n            CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor;\n#endif\n            self.scale = screenScale;\n            self.opaque = NO;\n            self.preferredRange = SDGraphicsImageRendererFormatRangeStandard;\n#if SD_UIKIT\n        }\n#endif\n    }\n    return self;\n}\n#pragma clang diagnostic pop\n\n+ (instancetype)preferredFormat {\n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] initForMainScreen];\n    return format;\n}\n\n@end\n\n@interface SDGraphicsImageRenderer ()\n@property (nonatomic, assign) CGSize size;\n@property (nonatomic, strong) SDGraphicsImageRendererFormat *format;\n#if SD_UIKIT\n@property (nonatomic, strong) UIGraphicsImageRenderer *uirenderer API_AVAILABLE(ios(10.0), tvos(10.0));\n#endif\n@end\n\n@implementation SDGraphicsImageRenderer\n\n- (instancetype)initWithSize:(CGSize)size {\n    return [self initWithSize:size format:SDGraphicsImageRendererFormat.preferredFormat];\n}\n\n- (instancetype)initWithSize:(CGSize)size format:(SDGraphicsImageRendererFormat *)format {\n    NSParameterAssert(format);\n    self = [super init];\n    if (self) {\n        self.size = size;\n        self.format = format;\n#if SD_UIKIT\n        if (@available(iOS 10.0, tvOS 10.0, *)) {\n            UIGraphicsImageRendererFormat *uiformat = format.uiformat;\n            self.uirenderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:uiformat];\n        }\n#endif\n    }\n    return self;\n}\n\n- (UIImage *)imageWithActions:(NS_NOESCAPE SDGraphicsImageDrawingActions)actions {\n    NSParameterAssert(actions);\n#if SD_UIKIT\n    if (@available(iOS 10.0, tvOS 10.0, *)) {\n        UIGraphicsImageDrawingActions uiactions = ^(UIGraphicsImageRendererContext *rendererContext) {\n            if (actions) {\n                actions(rendererContext.CGContext);\n            }\n        };\n        return [self.uirenderer imageWithActions:uiactions];\n    } else {\n#endif\n        SDGraphicsBeginImageContextWithOptions(self.size, self.format.opaque, self.format.scale);\n        CGContextRef context = SDGraphicsGetCurrentContext();\n        if (actions) {\n            actions(context);\n        }\n        UIImage *image = SDGraphicsGetImageFromCurrentImageContext();\n        SDGraphicsEndImageContext();\n        return image;\n#if SD_UIKIT\n    }\n#endif\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageIOAnimatedCoder.h\"\n\n/**\n Built in coder using ImageIO that supports APNG encoding/decoding\n */\n@interface SDImageAPNGCoder : SDImageIOAnimatedCoder <SDProgressiveImageCoder, SDAnimatedImageCoder>\n\n@property (nonatomic, class, readonly, nonnull) SDImageAPNGCoder *sharedCoder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageAPNGCoder.h\"\n#if SD_MAC\n#import <CoreServices/CoreServices.h>\n#else\n#import <MobileCoreServices/MobileCoreServices.h>\n#endif\n\n@implementation SDImageAPNGCoder\n\n+ (instancetype)sharedCoder {\n    static SDImageAPNGCoder *coder;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        coder = [[SDImageAPNGCoder alloc] init];\n    });\n    return coder;\n}\n\n#pragma mark - Subclass Override\n\n+ (SDImageFormat)imageFormat {\n    return SDImageFormatPNG;\n}\n\n+ (NSString *)imageUTType {\n    return (__bridge NSString *)kUTTypePNG;\n}\n\n+ (NSString *)dictionaryProperty {\n    return (__bridge NSString *)kCGImagePropertyPNGDictionary;\n}\n\n+ (NSString *)unclampedDelayTimeProperty {\n    return (__bridge NSString *)kCGImagePropertyAPNGUnclampedDelayTime;\n}\n\n+ (NSString *)delayTimeProperty {\n    return (__bridge NSString *)kCGImagePropertyAPNGDelayTime;\n}\n\n+ (NSString *)loopCountProperty {\n    return (__bridge NSString *)kCGImagePropertyAPNGLoopCount;\n}\n\n+ (NSUInteger)defaultLoopCount {\n    return 0;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageIOAnimatedCoder.h\"\n\n/**\n This coder is used for Google WebP and Animated WebP(AWebP) image format.\n Image/IO provide the WebP decoding support in iOS 14/macOS 11/tvOS 14/watchOS 7+.\n @note Currently Image/IO seems does not supports WebP encoding, if you need WebP encoding, use the custom codec below.\n @note If you need to support lower firmware version for WebP, you can have a try at https://github.com/SDWebImage/SDWebImageWebPCoder\n */\nAPI_AVAILABLE(ios(14.0), tvos(14.0), macos(11.0), watchos(7.0))\n@interface SDImageAWebPCoder : SDImageIOAnimatedCoder <SDProgressiveImageCoder, SDAnimatedImageCoder>\n\n@property (nonatomic, class, readonly, nonnull) SDImageAWebPCoder *sharedCoder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDImageAWebPCoder.h\"\n#import \"SDImageIOAnimatedCoderInternal.h\"\n\n// These constants are available from iOS 14+ and Xcode 12. This raw value is used for toolchain and firmware compatibility\nstatic NSString * kSDCGImagePropertyWebPDictionary = @\"{WebP}\";\nstatic NSString * kSDCGImagePropertyWebPLoopCount = @\"LoopCount\";\nstatic NSString * kSDCGImagePropertyWebPDelayTime = @\"DelayTime\";\nstatic NSString * kSDCGImagePropertyWebPUnclampedDelayTime = @\"UnclampedDelayTime\";\n\n@implementation SDImageAWebPCoder\n\n+ (void)initialize {\n#if __IPHONE_14_0 || __TVOS_14_0 || __MAC_11_0 || __WATCHOS_7_0\n    // Xcode 12\n    if (@available(iOS 14, tvOS 14, macOS 11, watchOS 7, *)) {\n        // Use SDK instead of raw value\n        kSDCGImagePropertyWebPDictionary = (__bridge NSString *)kCGImagePropertyWebPDictionary;\n        kSDCGImagePropertyWebPLoopCount = (__bridge NSString *)kCGImagePropertyWebPLoopCount;\n        kSDCGImagePropertyWebPDelayTime = (__bridge NSString *)kCGImagePropertyWebPDelayTime;\n        kSDCGImagePropertyWebPUnclampedDelayTime = (__bridge NSString *)kCGImagePropertyWebPUnclampedDelayTime;\n    }\n#endif\n}\n\n+ (instancetype)sharedCoder {\n    static SDImageAWebPCoder *coder;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        coder = [[SDImageAWebPCoder alloc] init];\n    });\n    return coder;\n}\n\n#pragma mark - SDImageCoder\n\n- (BOOL)canDecodeFromData:(nullable NSData *)data {\n    switch ([NSData sd_imageFormatForImageData:data]) {\n        case SDImageFormatWebP:\n            // Check WebP decoding compatibility\n            return [self.class canDecodeFromFormat:SDImageFormatWebP];\n        default:\n            return NO;\n    }\n}\n\n- (BOOL)canIncrementalDecodeFromData:(NSData *)data {\n    return [self canDecodeFromData:data];\n}\n\n- (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    switch (format) {\n        case SDImageFormatWebP:\n            // Check WebP encoding compatibility\n            return [self.class canEncodeToFormat:SDImageFormatWebP];\n        default:\n            return NO;\n    }\n}\n\n#pragma mark - Subclass Override\n\n+ (SDImageFormat)imageFormat {\n    return SDImageFormatWebP;\n}\n\n+ (NSString *)imageUTType {\n    return (__bridge NSString *)kSDUTTypeWebP;\n}\n\n+ (NSString *)dictionaryProperty {\n    return kSDCGImagePropertyWebPDictionary;\n}\n\n+ (NSString *)unclampedDelayTimeProperty {\n    return kSDCGImagePropertyWebPUnclampedDelayTime;\n}\n\n+ (NSString *)delayTimeProperty {\n    return kSDCGImagePropertyWebPDelayTime;\n}\n\n+ (NSString *)loopCountProperty {\n    return kSDCGImagePropertyWebPLoopCount;\n}\n\n+ (NSUInteger)defaultLoopCount {\n    return 0;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n#import \"SDImageCacheConfig.h\"\n#import \"SDImageCacheDefine.h\"\n#import \"SDMemoryCache.h\"\n#import \"SDDiskCache.h\"\n\n/// Image Cache Options\ntypedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {\n    /**\n     * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDImageCacheQueryMemoryDataSync`\n     */\n    SDImageCacheQueryMemoryData = 1 << 0,\n    /**\n     * By default, when you only specify `SDImageCacheQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously.\n     */\n    SDImageCacheQueryMemoryDataSync = 1 << 1,\n    /**\n     * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously.\n     @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page.\n     */\n    SDImageCacheQueryDiskDataSync = 1 << 2,\n    /**\n     * By default, images are decoded respecting their original size. On iOS, this flag will scale down the\n     * images to a size compatible with the constrained memory of devices.\n     */\n    SDImageCacheScaleDownLargeImages = 1 << 3,\n    /**\n     * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.\n     * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.\n     */\n    SDImageCacheAvoidDecodeImage = 1 << 4,\n    /**\n     * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image.\n     */\n    SDImageCacheDecodeFirstFrameOnly = 1 << 5,\n    /**\n     * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from disk cache\n     */\n    SDImageCachePreloadAllFrames = 1 << 6,\n    /**\n     * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution.\n     * Using this option, can ensure we always produce image with your provided class. If failed, an error with code `SDWebImageErrorBadImageData` will be used.\n     * Note this options is not compatible with `SDImageCacheDecodeFirstFrameOnly`, which always produce a UIImage/NSImage.\n     */\n    SDImageCacheMatchAnimatedImageClass = 1 << 7,\n};\n\n/**\n * SDImageCache maintains a memory cache and a disk cache. Disk cache write operations are performed\n * asynchronous so it doesn’t add unnecessary latency to the UI.\n */\n@interface SDImageCache : NSObject\n\n#pragma mark - Properties\n\n/**\n *  Cache Config object - storing all kind of settings.\n *  The property is copy so change of current config will not accidentally affect other cache's config.\n */\n@property (nonatomic, copy, nonnull, readonly) SDImageCacheConfig *config;\n\n/**\n * The memory cache implementation object used for current image cache.\n * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method.\n * @note To customize this class, check `SDImageCacheConfig.memoryCacheClass` property.\n */\n@property (nonatomic, strong, readonly, nonnull) id<SDMemoryCache> memoryCache;\n\n/**\n * The disk cache implementation object used for current image cache.\n * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method.\n * @note To customize this class, check `SDImageCacheConfig.diskCacheClass` property.\n * @warning When calling method about read/write in disk cache, be sure to either make your disk cache implementation IO-safe or using the same access queue to avoid issues.\n */\n@property (nonatomic, strong, readonly, nonnull) id<SDDiskCache> diskCache;\n\n/**\n *  The disk cache's root path\n */\n@property (nonatomic, copy, nonnull, readonly) NSString *diskCachePath;\n\n/**\n *  The additional disk cache path to check if the query from disk cache not exist;\n *  The `key` param is the image cache key. The returned file path will be used to load the disk cache. If return nil, ignore it.\n *  Useful if you want to bundle pre-loaded images with your app\n */\n@property (nonatomic, copy, nullable) SDImageCacheAdditionalCachePathBlock additionalCachePathBlock;\n\n#pragma mark - Singleton and initialization\n\n/**\n * Returns global shared cache instance\n */\n@property (nonatomic, class, readonly, nonnull) SDImageCache *sharedImageCache;\n\n/**\n * Control the default disk cache directory. This will effect all the SDImageCache instance created after modification, even for shared image cache.\n * This can be used to share the same disk cache with the App and App Extension (Today/Notification Widget) using `- [NSFileManager.containerURLForSecurityApplicationGroupIdentifier:]`.\n * @note If you pass nil, the value will be reset to `~/Library/Caches/com.hackemist.SDImageCache`.\n * @note We still preserve the `namespace` arg, which means, if you change this property into `/path/to/use`,  the `SDImageCache.sharedImageCache.diskCachePath` should be `/path/to/use/default` because shared image cache use `default` as namespace.\n * Defaults to nil.\n */\n@property (nonatomic, class, readwrite, null_resettable) NSString *defaultDiskCacheDirectory;\n\n/**\n * Init a new cache store with a specific namespace\n * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)\n *\n * @param ns The namespace to use for this cache store\n */\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns;\n\n/**\n * Init a new cache store with a specific namespace and directory.\n * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)\n *\n * @param ns        The namespace to use for this cache store\n * @param directory Directory to cache disk images in\n */\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns\n                       diskCacheDirectory:(nullable NSString *)directory;\n\n/**\n * Init a new cache store with a specific namespace, directory and config.\n * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)\n *\n * @param ns          The namespace to use for this cache store\n * @param directory   Directory to cache disk images in\n * @param config      The cache config to be used to create the cache. You can provide custom memory cache or disk cache class in the cache config\n */\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns\n                       diskCacheDirectory:(nullable NSString *)directory\n                                   config:(nullable SDImageCacheConfig *)config NS_DESIGNATED_INITIALIZER;\n\n#pragma mark - Cache paths\n\n/**\n Get the cache path for a certain key\n \n @param key The unique image cache key\n @return The cache path. You can check `lastPathComponent` to grab the file name.\n */\n- (nullable NSString *)cachePathForKey:(nullable NSString *)key;\n\n#pragma mark - Store Ops\n\n/**\n * Asynchronously store an image into memory and disk cache at the given key.\n *\n * @param image           The image to store\n * @param key             The unique image cache key, usually it's image absolute URL\n * @param completionBlock A block executed after the operation is finished\n */\n- (void)storeImage:(nullable UIImage *)image\n            forKey:(nullable NSString *)key\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n/**\n * Asynchronously store an image into memory and disk cache at the given key.\n *\n * @param image           The image to store\n * @param key             The unique image cache key, usually it's image absolute URL\n * @param toDisk          Store the image to disk cache if YES. If NO, the completion block is called synchronously\n * @param completionBlock A block executed after the operation is finished\n * @note If no image data is provided and encode to disk, we will try to detect the image format (using either `sd_imageFormat` or `SDAnimatedImage` protocol method) and animation status, to choose the best matched format, including GIF, JPEG or PNG.\n */\n- (void)storeImage:(nullable UIImage *)image\n            forKey:(nullable NSString *)key\n            toDisk:(BOOL)toDisk\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n/**\n * Asynchronously store an image into memory and disk cache at the given key.\n *\n * @param image           The image to store\n * @param imageData       The image data as returned by the server, this representation will be used for disk storage\n *                        instead of converting the given image object into a storable/compressed image format in order\n *                        to save quality and CPU\n * @param key             The unique image cache key, usually it's image absolute URL\n * @param toDisk          Store the image to disk cache if YES. If NO, the completion block is called synchronously\n * @param completionBlock A block executed after the operation is finished\n * @note If no image data is provided and encode to disk, we will try to detect the image format (using either `sd_imageFormat` or `SDAnimatedImage` protocol method) and animation status, to choose the best matched format, including GIF, JPEG or PNG.\n */\n- (void)storeImage:(nullable UIImage *)image\n         imageData:(nullable NSData *)imageData\n            forKey:(nullable NSString *)key\n            toDisk:(BOOL)toDisk\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n/**\n * Synchronously store image into memory cache at the given key.\n *\n * @param image  The image to store\n * @param key    The unique image cache key, usually it's image absolute URL\n */\n- (void)storeImageToMemory:(nullable UIImage*)image\n                    forKey:(nullable NSString *)key;\n\n/**\n * Synchronously store image data into disk cache at the given key.\n *\n * @param imageData  The image data to store\n * @param key        The unique image cache key, usually it's image absolute URL\n */\n- (void)storeImageDataToDisk:(nullable NSData *)imageData\n                      forKey:(nullable NSString *)key;\n\n\n#pragma mark - Contains and Check Ops\n\n/**\n *  Asynchronously check if image exists in disk cache already (does not load the image)\n *\n *  @param key             the key describing the url\n *  @param completionBlock the block to be executed when the check is done.\n *  @note the completion block will be always executed on the main queue\n */\n- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDImageCacheCheckCompletionBlock)completionBlock;\n\n/**\n *  Synchronously check if image data exists in disk cache already (does not load the image)\n *\n *  @param key             the key describing the url\n */\n- (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key;\n\n#pragma mark - Query and Retrieve Ops\n\n/**\n * Synchronously query the image data for the given key in disk cache. You can decode the image data to image after loaded.\n *\n *  @param key The unique key used to store the wanted image\n *  @return The image data for the given key, or nil if not found.\n */\n- (nullable NSData *)diskImageDataForKey:(nullable NSString *)key;\n\n/**\n * Asynchronously query the image data for the given key in disk cache. You can decode the image data to image after loaded.\n *\n *  @param key The unique key used to store the wanted image\n *  @param completionBlock the block to be executed when the query is done.\n *  @note the completion block will be always executed on the main queue\n */\n- (void)diskImageDataQueryForKey:(nullable NSString *)key completion:(nullable SDImageCacheQueryDataCompletionBlock)completionBlock;\n\n/**\n * Asynchronously queries the cache with operation and call the completion when done.\n *\n * @param key       The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`.\n * @param doneBlock The completion block. Will not get called if the operation is cancelled\n *\n * @return a NSOperation instance containing the cache op\n */\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;\n\n/**\n * Asynchronously queries the cache with operation and call the completion when done.\n *\n * @param key       The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`.\n * @param options   A mask to specify options to use for this cache query\n * @param doneBlock The completion block. Will not get called if the operation is cancelled\n *\n * @return a NSOperation instance containing the cache op\n */\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;\n\n/**\n * Asynchronously queries the cache with operation and call the completion when done.\n *\n * @param key       The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`.\n * @param options   A mask to specify options to use for this cache query\n * @param context   A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param doneBlock The completion block. Will not get called if the operation is cancelled\n *\n * @return a NSOperation instance containing the cache op\n */\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;\n\n/**\n * Asynchronously queries the cache with operation and call the completion when done.\n *\n * @param key       The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`.\n * @param options   A mask to specify options to use for this cache query\n * @param context   A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param queryCacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediately.\n * @param doneBlock The completion block. Will not get called if the operation is cancelled\n *\n * @return a NSOperation instance containing the cache op\n */\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;\n\n/**\n * Synchronously query the memory cache.\n *\n * @param key The unique key used to store the image\n * @return The image for the given key, or nil if not found.\n */\n- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key;\n\n/**\n * Synchronously query the disk cache.\n *\n * @param key The unique key used to store the image\n * @return The image for the given key, or nil if not found.\n */\n- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key;\n\n/**\n * Synchronously query the disk cache. With the options and context which may effect the image generation. (Such as transformer, animated image, thumbnail, etc)\n *\n * @param key The unique key used to store the image\n * @param options   A mask to specify options to use for this cache query\n * @param context   A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @return The image for the given key, or nil if not found.\n */\n- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context;\n\n/**\n * Synchronously query the cache (memory and or disk) after checking the memory cache.\n *\n * @param key The unique key used to store the image\n * @return The image for the given key, or nil if not found.\n */\n- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key;\n\n/**\n * Synchronously query the cache (memory and or disk) after checking the memory cache. With the options and context which may effect the image generation. (Such as transformer, animated image, thumbnail, etc)\n *\n * @param key The unique key used to store the image\n * @param options   A mask to specify options to use for this cache query\n * @param context   A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @return The image for the given key, or nil if not found.\n */\n- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context;\n\n#pragma mark - Remove Ops\n\n/**\n * Asynchronously remove the image from memory and disk cache\n *\n * @param key             The unique image cache key\n * @param completion      A block that should be executed after the image has been removed (optional)\n */\n- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion;\n\n/**\n * Asynchronously remove the image from memory and optionally disk cache\n *\n * @param key             The unique image cache key\n * @param fromDisk        Also remove cache entry from disk if YES. If NO, the completion block is called synchronously\n * @param completion      A block that should be executed after the image has been removed (optional)\n */\n- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion;\n\n/**\n Synchronously remove the image from memory cache.\n \n @param key The unique image cache key\n */\n- (void)removeImageFromMemoryForKey:(nullable NSString *)key;\n\n/**\n Synchronously remove the image from disk cache.\n \n @param key The unique image cache key\n */\n- (void)removeImageFromDiskForKey:(nullable NSString *)key;\n\n#pragma mark - Cache clean Ops\n\n/**\n * Synchronously Clear all memory cached images\n */\n- (void)clearMemory;\n\n/**\n * Asynchronously clear all disk cached images. Non-blocking method - returns immediately.\n * @param completion    A block that should be executed after cache expiration completes (optional)\n */\n- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion;\n\n/**\n * Asynchronously remove all expired cached image from disk. Non-blocking method - returns immediately.\n * @param completionBlock A block that should be executed after cache expiration completes (optional)\n */\n- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n#pragma mark - Cache Info\n\n/**\n * Get the total bytes size of images in the disk cache\n */\n- (NSUInteger)totalDiskSize;\n\n/**\n * Get the number of images in the disk cache\n */\n- (NSUInteger)totalDiskCount;\n\n/**\n * Asynchronously calculate the disk cache's size.\n */\n- (void)calculateSizeWithCompletionBlock:(nullable SDImageCacheCalculateSizeBlock)completionBlock;\n\n@end\n\n/**\n * SDImageCache is the built-in image cache implementation for web image manager. It adopts `SDImageCache` protocol to provide the function for web image manager to use for image loading process.\n */\n@interface SDImageCache (SDImageCache) <SDImageCache>\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCache.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDImageCodersManager.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDAnimatedImage.h\"\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"UIImage+Metadata.h\"\n#import \"UIImage+ExtendedCacheData.h\"\n\nstatic NSString * _defaultDiskCacheDirectory;\n\n@interface SDImageCache ()\n\n#pragma mark - Properties\n@property (nonatomic, strong, readwrite, nonnull) id<SDMemoryCache> memoryCache;\n@property (nonatomic, strong, readwrite, nonnull) id<SDDiskCache> diskCache;\n@property (nonatomic, copy, readwrite, nonnull) SDImageCacheConfig *config;\n@property (nonatomic, copy, readwrite, nonnull) NSString *diskCachePath;\n@property (nonatomic, strong, nullable) dispatch_queue_t ioQueue;\n\n@end\n\n\n@implementation SDImageCache\n\n#pragma mark - Singleton, init, dealloc\n\n+ (nonnull instancetype)sharedImageCache {\n    static dispatch_once_t once;\n    static id instance;\n    dispatch_once(&once, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n+ (NSString *)defaultDiskCacheDirectory {\n    if (!_defaultDiskCacheDirectory) {\n        _defaultDiskCacheDirectory = [[self userCacheDirectory] stringByAppendingPathComponent:@\"com.hackemist.SDImageCache\"];\n    }\n    return _defaultDiskCacheDirectory;\n}\n\n+ (void)setDefaultDiskCacheDirectory:(NSString *)defaultDiskCacheDirectory {\n    _defaultDiskCacheDirectory = [defaultDiskCacheDirectory copy];\n}\n\n- (instancetype)init {\n    return [self initWithNamespace:@\"default\"];\n}\n\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns {\n    return [self initWithNamespace:ns diskCacheDirectory:nil];\n}\n\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns\n                       diskCacheDirectory:(nullable NSString *)directory {\n    return [self initWithNamespace:ns diskCacheDirectory:directory config:SDImageCacheConfig.defaultCacheConfig];\n}\n\n- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns\n                       diskCacheDirectory:(nullable NSString *)directory\n                                   config:(nullable SDImageCacheConfig *)config {\n    if ((self = [super init])) {\n        NSAssert(ns, @\"Cache namespace should not be nil\");\n        \n        // Create IO serial queue\n        _ioQueue = dispatch_queue_create(\"com.hackemist.SDImageCache\", DISPATCH_QUEUE_SERIAL);\n        \n        if (!config) {\n            config = SDImageCacheConfig.defaultCacheConfig;\n        }\n        _config = [config copy];\n        \n        // Init the memory cache\n        NSAssert([config.memoryCacheClass conformsToProtocol:@protocol(SDMemoryCache)], @\"Custom memory cache class must conform to `SDMemoryCache` protocol\");\n        _memoryCache = [[config.memoryCacheClass alloc] initWithConfig:_config];\n        \n        // Init the disk cache\n        if (!directory) {\n            // Use default disk cache directory\n            directory = [self.class defaultDiskCacheDirectory];\n        }\n        _diskCachePath = [directory stringByAppendingPathComponent:ns];\n        \n        NSAssert([config.diskCacheClass conformsToProtocol:@protocol(SDDiskCache)], @\"Custom disk cache class must conform to `SDDiskCache` protocol\");\n        _diskCache = [[config.diskCacheClass alloc] initWithCachePath:_diskCachePath config:_config];\n        \n        // Check and migrate disk cache directory if need\n        [self migrateDiskCacheDirectory];\n\n#if SD_UIKIT\n        // Subscribe to app events\n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(applicationWillTerminate:)\n                                                     name:UIApplicationWillTerminateNotification\n                                                   object:nil];\n\n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(applicationDidEnterBackground:)\n                                                     name:UIApplicationDidEnterBackgroundNotification\n                                                   object:nil];\n#endif\n#if SD_MAC\n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(applicationWillTerminate:)\n                                                     name:NSApplicationWillTerminateNotification\n                                                   object:nil];\n#endif\n    }\n\n    return self;\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n#pragma mark - Cache paths\n\n- (nullable NSString *)cachePathForKey:(nullable NSString *)key {\n    if (!key) {\n        return nil;\n    }\n    return [self.diskCache cachePathForKey:key];\n}\n\n+ (nullable NSString *)userCacheDirectory {\n    NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);\n    return paths.firstObject;\n}\n\n- (void)migrateDiskCacheDirectory {\n    if ([self.diskCache isKindOfClass:[SDDiskCache class]]) {\n        static dispatch_once_t onceToken;\n        dispatch_once(&onceToken, ^{\n            // ~/Library/Caches/com.hackemist.SDImageCache/default/\n            NSString *newDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@\"com.hackemist.SDImageCache\"] stringByAppendingPathComponent:@\"default\"];\n            // ~/Library/Caches/default/com.hackemist.SDWebImageCache.default/\n            NSString *oldDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@\"default\"] stringByAppendingPathComponent:@\"com.hackemist.SDWebImageCache.default\"];\n            dispatch_async(self.ioQueue, ^{\n                [((SDDiskCache *)self.diskCache) moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];\n            });\n        });\n    }\n}\n\n#pragma mark - Store Ops\n\n- (void)storeImage:(nullable UIImage *)image\n            forKey:(nullable NSString *)key\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    [self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock];\n}\n\n- (void)storeImage:(nullable UIImage *)image\n            forKey:(nullable NSString *)key\n            toDisk:(BOOL)toDisk\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    [self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];\n}\n\n- (void)storeImage:(nullable UIImage *)image\n         imageData:(nullable NSData *)imageData\n            forKey:(nullable NSString *)key\n            toDisk:(BOOL)toDisk\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    return [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:toDisk completion:completionBlock];\n}\n\n- (void)storeImage:(nullable UIImage *)image\n         imageData:(nullable NSData *)imageData\n            forKey:(nullable NSString *)key\n          toMemory:(BOOL)toMemory\n            toDisk:(BOOL)toDisk\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    if (!image || !key) {\n        if (completionBlock) {\n            completionBlock();\n        }\n        return;\n    }\n    // if memory cache is enabled\n    if (toMemory && self.config.shouldCacheImagesInMemory) {\n        NSUInteger cost = image.sd_memoryCost;\n        [self.memoryCache setObject:image forKey:key cost:cost];\n    }\n    \n    if (!toDisk) {\n        if (completionBlock) {\n            completionBlock();\n        }\n        return;\n    }\n    dispatch_async(self.ioQueue, ^{\n        @autoreleasepool {\n            NSData *data = imageData;\n            if (!data && [image conformsToProtocol:@protocol(SDAnimatedImage)]) {\n                // If image is custom animated image class, prefer its original animated data\n                data = [((id<SDAnimatedImage>)image) animatedImageData];\n            }\n            if (!data && image) {\n                // Check image's associated image format, may return .undefined\n                SDImageFormat format = image.sd_imageFormat;\n                if (format == SDImageFormatUndefined) {\n                    // If image is animated, use GIF (APNG may be better, but has bugs before macOS 10.14)\n                    if (image.sd_isAnimated) {\n                        format = SDImageFormatGIF;\n                    } else {\n                        // If we do not have any data to detect image format, check whether it contains alpha channel to use PNG or JPEG format\n                        format = [SDImageCoderHelper CGImageContainsAlpha:image.CGImage] ? SDImageFormatPNG : SDImageFormatJPEG;\n                    }\n                }\n                data = [[SDImageCodersManager sharedManager] encodedDataWithImage:image format:format options:nil];\n            }\n            [self _storeImageDataToDisk:data forKey:key];\n            [self _archivedDataWithImage:image forKey:key];\n        }\n        \n        if (completionBlock) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completionBlock();\n            });\n        }\n    });\n}\n\n- (void)_archivedDataWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return;\n    }\n    // Check extended data\n    id extendedObject = image.sd_extendedObject;\n    if (![extendedObject conformsToProtocol:@protocol(NSCoding)]) {\n        return;\n    }\n    NSData *extendedData;\n    if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) {\n        NSError *error;\n        extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject requiringSecureCoding:NO error:&error];\n        if (error) {\n            NSLog(@\"NSKeyedArchiver archive failed with error: %@\", error);\n        }\n    } else {\n        @try {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n            extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject];\n#pragma clang diagnostic pop\n        } @catch (NSException *exception) {\n            NSLog(@\"NSKeyedArchiver archive failed with exception: %@\", exception);\n        }\n    }\n    if (extendedData) {\n        [self.diskCache setExtendedData:extendedData forKey:key];\n    }\n}\n\n- (void)storeImageToMemory:(UIImage *)image forKey:(NSString *)key {\n    if (!image || !key) {\n        return;\n    }\n    NSUInteger cost = image.sd_memoryCost;\n    [self.memoryCache setObject:image forKey:key cost:cost];\n}\n\n- (void)storeImageDataToDisk:(nullable NSData *)imageData\n                      forKey:(nullable NSString *)key {\n    if (!imageData || !key) {\n        return;\n    }\n    \n    dispatch_sync(self.ioQueue, ^{\n        [self _storeImageDataToDisk:imageData forKey:key];\n    });\n}\n\n// Make sure to call from io queue by caller\n- (void)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {\n    if (!imageData || !key) {\n        return;\n    }\n    \n    [self.diskCache setData:imageData forKey:key];\n}\n\n#pragma mark - Query and Retrieve Ops\n\n- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDImageCacheCheckCompletionBlock)completionBlock {\n    dispatch_async(self.ioQueue, ^{\n        BOOL exists = [self _diskImageDataExistsWithKey:key];\n        if (completionBlock) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completionBlock(exists);\n            });\n        }\n    });\n}\n\n- (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key {\n    if (!key) {\n        return NO;\n    }\n    \n    __block BOOL exists = NO;\n    dispatch_sync(self.ioQueue, ^{\n        exists = [self _diskImageDataExistsWithKey:key];\n    });\n    \n    return exists;\n}\n\n// Make sure to call from io queue by caller\n- (BOOL)_diskImageDataExistsWithKey:(nullable NSString *)key {\n    if (!key) {\n        return NO;\n    }\n    \n    return [self.diskCache containsDataForKey:key];\n}\n\n- (void)diskImageDataQueryForKey:(NSString *)key completion:(SDImageCacheQueryDataCompletionBlock)completionBlock {\n    dispatch_async(self.ioQueue, ^{\n        NSData *imageData = [self diskImageDataBySearchingAllPathsForKey:key];\n        if (completionBlock) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completionBlock(imageData);\n            });\n        }\n    });\n}\n\n- (nullable NSData *)diskImageDataForKey:(nullable NSString *)key {\n    if (!key) {\n        return nil;\n    }\n    __block NSData *imageData = nil;\n    dispatch_sync(self.ioQueue, ^{\n        imageData = [self diskImageDataBySearchingAllPathsForKey:key];\n    });\n    \n    return imageData;\n}\n\n- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key {\n    return [self.memoryCache objectForKey:key];\n}\n\n- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key {\n    return [self imageFromDiskCacheForKey:key options:0 context:nil];\n}\n\n- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context {\n    NSData *data = [self diskImageDataForKey:key];\n    UIImage *diskImage = [self diskImageForKey:key data:data options:options context:context];\n    \n    BOOL shouldCacheToMomery = YES;\n    if (context[SDWebImageContextStoreCacheType]) {\n        SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue];\n        shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);\n    }\n    if (diskImage && self.config.shouldCacheImagesInMemory && shouldCacheToMomery) {\n        NSUInteger cost = diskImage.sd_memoryCost;\n        [self.memoryCache setObject:diskImage forKey:key cost:cost];\n    }\n\n    return diskImage;\n}\n\n- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key {\n    return [self imageFromCacheForKey:key options:0 context:nil];\n}\n\n- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context {\n    // First check the in-memory cache...\n    UIImage *image = [self imageFromMemoryCacheForKey:key];\n    if (image) {\n        return image;\n    }\n    \n    // Second check the disk cache...\n    image = [self imageFromDiskCacheForKey:key options:options context:context];\n    return image;\n}\n\n- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key {\n    if (!key) {\n        return nil;\n    }\n    \n    NSData *data = [self.diskCache dataForKey:key];\n    if (data) {\n        return data;\n    }\n    \n    // Addtional cache path for custom pre-load cache\n    if (self.additionalCachePathBlock) {\n        NSString *filePath = self.additionalCachePathBlock(key);\n        if (filePath) {\n            data = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil];\n        }\n    }\n\n    return data;\n}\n\n- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {\n    NSData *data = [self diskImageDataForKey:key];\n    return [self diskImageForKey:key data:data];\n}\n\n- (nullable UIImage *)diskImageForKey:(nullable NSString *)key data:(nullable NSData *)data {\n    return [self diskImageForKey:key data:data options:0 context:nil];\n}\n\n- (nullable UIImage *)diskImageForKey:(nullable NSString *)key data:(nullable NSData *)data options:(SDImageCacheOptions)options context:(SDWebImageContext *)context {\n    if (!data) {\n        return nil;\n    }\n    UIImage *image = SDImageCacheDecodeImageData(data, key, [[self class] imageOptionsFromCacheOptions:options], context);\n    [self _unarchiveObjectWithImage:image forKey:key];\n    return image;\n}\n\n- (void)_unarchiveObjectWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return;\n    }\n    // Check extended data\n    NSData *extendedData = [self.diskCache extendedDataForKey:key];\n    if (!extendedData) {\n        return;\n    }\n    id extendedObject;\n    if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) {\n        NSError *error;\n        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:extendedData error:&error];\n        unarchiver.requiresSecureCoding = NO;\n        extendedObject = [unarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:&error];\n        if (error) {\n            NSLog(@\"NSKeyedUnarchiver unarchive failed with error: %@\", error);\n        }\n    } else {\n        @try {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n            extendedObject = [NSKeyedUnarchiver unarchiveObjectWithData:extendedData];\n#pragma clang diagnostic pop\n        } @catch (NSException *exception) {\n            NSLog(@\"NSKeyedUnarchiver unarchive failed with exception: %@\", exception);\n        }\n    }\n    image.sd_extendedObject = extendedObject;\n}\n\n- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDImageCacheQueryCompletionBlock)doneBlock {\n    return [self queryCacheOperationForKey:key options:0 done:doneBlock];\n}\n\n- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key options:(SDImageCacheOptions)options done:(SDImageCacheQueryCompletionBlock)doneBlock {\n    return [self queryCacheOperationForKey:key options:options context:nil done:doneBlock];\n}\n\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock {\n    return [self queryCacheOperationForKey:key options:options context:context cacheType:SDImageCacheTypeAll done:doneBlock];\n}\n\n- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock {\n    if (!key) {\n        if (doneBlock) {\n            doneBlock(nil, nil, SDImageCacheTypeNone);\n        }\n        return nil;\n    }\n    // Invalid cache type\n    if (queryCacheType == SDImageCacheTypeNone) {\n        if (doneBlock) {\n            doneBlock(nil, nil, SDImageCacheTypeNone);\n        }\n        return nil;\n    }\n    \n    // First check the in-memory cache...\n    UIImage *image;\n    if (queryCacheType != SDImageCacheTypeDisk) {\n        image = [self imageFromMemoryCacheForKey:key];\n    }\n    \n    if (image) {\n        if (options & SDImageCacheDecodeFirstFrameOnly) {\n            // Ensure static image\n            Class animatedImageClass = image.class;\n            if (image.sd_isAnimated || ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)])) {\n#if SD_MAC\n                image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];\n#else\n                image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation];\n#endif\n            }\n        } else if (options & SDImageCacheMatchAnimatedImageClass) {\n            // Check image class matching\n            Class animatedImageClass = image.class;\n            Class desiredImageClass = context[SDWebImageContextAnimatedImageClass];\n            if (desiredImageClass && ![animatedImageClass isSubclassOfClass:desiredImageClass]) {\n                image = nil;\n            }\n        }\n    }\n\n    BOOL shouldQueryMemoryOnly = (queryCacheType == SDImageCacheTypeMemory) || (image && !(options & SDImageCacheQueryMemoryData));\n    if (shouldQueryMemoryOnly) {\n        if (doneBlock) {\n            doneBlock(image, nil, SDImageCacheTypeMemory);\n        }\n        return nil;\n    }\n    \n    // Second check the disk cache...\n    NSOperation *operation = [NSOperation new];\n    // Check whether we need to synchronously query disk\n    // 1. in-memory cache hit & memoryDataSync\n    // 2. in-memory cache miss & diskDataSync\n    BOOL shouldQueryDiskSync = ((image && options & SDImageCacheQueryMemoryDataSync) ||\n                                (!image && options & SDImageCacheQueryDiskDataSync));\n    void(^queryDiskBlock)(void) =  ^{\n        if (operation.isCancelled) {\n            if (doneBlock) {\n                doneBlock(nil, nil, SDImageCacheTypeNone);\n            }\n            return;\n        }\n        \n        @autoreleasepool {\n            NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];\n            UIImage *diskImage;\n            if (image) {\n                // the image is from in-memory cache, but need image data\n                diskImage = image;\n            } else if (diskData) {\n                BOOL shouldCacheToMomery = YES;\n                if (context[SDWebImageContextStoreCacheType]) {\n                    SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue];\n                    shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);\n                }\n                // decode image data only if in-memory cache missed\n                diskImage = [self diskImageForKey:key data:diskData options:options context:context];\n                if (shouldCacheToMomery && diskImage && self.config.shouldCacheImagesInMemory) {\n                    NSUInteger cost = diskImage.sd_memoryCost;\n                    [self.memoryCache setObject:diskImage forKey:key cost:cost];\n                }\n            }\n            \n            if (doneBlock) {\n                if (shouldQueryDiskSync) {\n                    doneBlock(diskImage, diskData, SDImageCacheTypeDisk);\n                } else {\n                    dispatch_async(dispatch_get_main_queue(), ^{\n                        doneBlock(diskImage, diskData, SDImageCacheTypeDisk);\n                    });\n                }\n            }\n        }\n    };\n    \n    // Query in ioQueue to keep IO-safe\n    if (shouldQueryDiskSync) {\n        dispatch_sync(self.ioQueue, queryDiskBlock);\n    } else {\n        dispatch_async(self.ioQueue, queryDiskBlock);\n    }\n    \n    return operation;\n}\n\n#pragma mark - Remove Ops\n\n- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion {\n    [self removeImageForKey:key fromDisk:YES withCompletion:completion];\n}\n\n- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion {\n    [self removeImageForKey:key fromMemory:YES fromDisk:fromDisk withCompletion:completion];\n}\n\n- (void)removeImageForKey:(nullable NSString *)key fromMemory:(BOOL)fromMemory fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion {\n    if (key == nil) {\n        return;\n    }\n\n    if (fromMemory && self.config.shouldCacheImagesInMemory) {\n        [self.memoryCache removeObjectForKey:key];\n    }\n\n    if (fromDisk) {\n        dispatch_async(self.ioQueue, ^{\n            [self.diskCache removeDataForKey:key];\n            \n            if (completion) {\n                dispatch_async(dispatch_get_main_queue(), ^{\n                    completion();\n                });\n            }\n        });\n    } else if (completion) {\n        completion();\n    }\n}\n\n- (void)removeImageFromMemoryForKey:(NSString *)key {\n    if (!key) {\n        return;\n    }\n    \n    [self.memoryCache removeObjectForKey:key];\n}\n\n- (void)removeImageFromDiskForKey:(NSString *)key {\n    if (!key) {\n        return;\n    }\n    dispatch_sync(self.ioQueue, ^{\n        [self _removeImageFromDiskForKey:key];\n    });\n}\n\n// Make sure to call from io queue by caller\n- (void)_removeImageFromDiskForKey:(NSString *)key {\n    if (!key) {\n        return;\n    }\n    \n    [self.diskCache removeDataForKey:key];\n}\n\n#pragma mark - Cache clean Ops\n\n- (void)clearMemory {\n    [self.memoryCache removeAllObjects];\n}\n\n- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion {\n    dispatch_async(self.ioQueue, ^{\n        [self.diskCache removeAllData];\n        if (completion) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completion();\n            });\n        }\n    });\n}\n\n- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock {\n    dispatch_async(self.ioQueue, ^{\n        [self.diskCache removeExpiredData];\n        if (completionBlock) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completionBlock();\n            });\n        }\n    });\n}\n\n#pragma mark - UIApplicationWillTerminateNotification\n\n#if SD_UIKIT || SD_MAC\n- (void)applicationWillTerminate:(NSNotification *)notification {\n    // On iOS/macOS, the async opeartion to remove exipred data will be terminated quickly\n    // Try using the sync operation to ensure we reomve the exipred data\n    if (!self.config.shouldRemoveExpiredDataWhenTerminate) {\n        return;\n    }\n    dispatch_sync(self.ioQueue, ^{\n        [self.diskCache removeExpiredData];\n    });\n}\n#endif\n\n#pragma mark - UIApplicationDidEnterBackgroundNotification\n\n#if SD_UIKIT\n- (void)applicationDidEnterBackground:(NSNotification *)notification {\n    if (!self.config.shouldRemoveExpiredDataWhenEnterBackground) {\n        return;\n    }\n    Class UIApplicationClass = NSClassFromString(@\"UIApplication\");\n    if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) {\n        return;\n    }\n    UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];\n    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{\n        // Clean up any unfinished task business by marking where you\n        // stopped or ending the task outright.\n        [application endBackgroundTask:bgTask];\n        bgTask = UIBackgroundTaskInvalid;\n    }];\n\n    // Start the long-running task and return immediately.\n    [self deleteOldFilesWithCompletionBlock:^{\n        [application endBackgroundTask:bgTask];\n        bgTask = UIBackgroundTaskInvalid;\n    }];\n}\n#endif\n\n#pragma mark - Cache Info\n\n- (NSUInteger)totalDiskSize {\n    __block NSUInteger size = 0;\n    dispatch_sync(self.ioQueue, ^{\n        size = [self.diskCache totalSize];\n    });\n    return size;\n}\n\n- (NSUInteger)totalDiskCount {\n    __block NSUInteger count = 0;\n    dispatch_sync(self.ioQueue, ^{\n        count = [self.diskCache totalCount];\n    });\n    return count;\n}\n\n- (void)calculateSizeWithCompletionBlock:(nullable SDImageCacheCalculateSizeBlock)completionBlock {\n    dispatch_async(self.ioQueue, ^{\n        NSUInteger fileCount = [self.diskCache totalCount];\n        NSUInteger totalSize = [self.diskCache totalSize];\n        if (completionBlock) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                completionBlock(fileCount, totalSize);\n            });\n        }\n    });\n}\n\n#pragma mark - Helper\n+ (SDWebImageOptions)imageOptionsFromCacheOptions:(SDImageCacheOptions)cacheOptions {\n    SDWebImageOptions options = 0;\n    if (cacheOptions & SDImageCacheScaleDownLargeImages) options |= SDWebImageScaleDownLargeImages;\n    if (cacheOptions & SDImageCacheDecodeFirstFrameOnly) options |= SDWebImageDecodeFirstFrameOnly;\n    if (cacheOptions & SDImageCachePreloadAllFrames) options |= SDWebImagePreloadAllFrames;\n    if (cacheOptions & SDImageCacheAvoidDecodeImage) options |= SDWebImageAvoidDecodeImage;\n    if (cacheOptions & SDImageCacheMatchAnimatedImageClass) options |= SDWebImageMatchAnimatedImageClass;\n    \n    return options;\n}\n\n@end\n\n@implementation SDImageCache (SDImageCache)\n\n#pragma mark - SDImageCache\n\n- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock {\n    return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:completionBlock];\n}\n\n- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock {\n    SDImageCacheOptions cacheOptions = 0;\n    if (options & SDWebImageQueryMemoryData) cacheOptions |= SDImageCacheQueryMemoryData;\n    if (options & SDWebImageQueryMemoryDataSync) cacheOptions |= SDImageCacheQueryMemoryDataSync;\n    if (options & SDWebImageQueryDiskDataSync) cacheOptions |= SDImageCacheQueryDiskDataSync;\n    if (options & SDWebImageScaleDownLargeImages) cacheOptions |= SDImageCacheScaleDownLargeImages;\n    if (options & SDWebImageAvoidDecodeImage) cacheOptions |= SDImageCacheAvoidDecodeImage;\n    if (options & SDWebImageDecodeFirstFrameOnly) cacheOptions |= SDImageCacheDecodeFirstFrameOnly;\n    if (options & SDWebImagePreloadAllFrames) cacheOptions |= SDImageCachePreloadAllFrames;\n    if (options & SDWebImageMatchAnimatedImageClass) cacheOptions |= SDImageCacheMatchAnimatedImageClass;\n    \n    return [self queryCacheOperationForKey:key options:cacheOptions context:context cacheType:cacheType done:completionBlock];\n}\n\n- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(nullable NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    switch (cacheType) {\n        case SDImageCacheTypeNone: {\n            [self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:NO completion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeMemory: {\n            [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:NO completion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeDisk: {\n            [self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:YES completion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeAll: {\n            [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:YES completion:completionBlock];\n        }\n            break;\n        default: {\n            if (completionBlock) {\n                completionBlock();\n            }\n        }\n            break;\n    }\n}\n\n- (void)removeImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock {\n    switch (cacheType) {\n        case SDImageCacheTypeNone: {\n            [self removeImageForKey:key fromMemory:NO fromDisk:NO withCompletion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeMemory: {\n            [self removeImageForKey:key fromMemory:YES fromDisk:NO withCompletion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeDisk: {\n            [self removeImageForKey:key fromMemory:NO fromDisk:YES withCompletion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeAll: {\n            [self removeImageForKey:key fromMemory:YES fromDisk:YES withCompletion:completionBlock];\n        }\n            break;\n        default: {\n            if (completionBlock) {\n                completionBlock();\n            }\n        }\n            break;\n    }\n}\n\n- (void)containsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDImageCacheContainsCompletionBlock)completionBlock {\n    switch (cacheType) {\n        case SDImageCacheTypeNone: {\n            if (completionBlock) {\n                completionBlock(SDImageCacheTypeNone);\n            }\n        }\n            break;\n        case SDImageCacheTypeMemory: {\n            BOOL isInMemoryCache = ([self imageFromMemoryCacheForKey:key] != nil);\n            if (completionBlock) {\n                completionBlock(isInMemoryCache ? SDImageCacheTypeMemory : SDImageCacheTypeNone);\n            }\n        }\n            break;\n        case SDImageCacheTypeDisk: {\n            [self diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) {\n                if (completionBlock) {\n                    completionBlock(isInDiskCache ? SDImageCacheTypeDisk : SDImageCacheTypeNone);\n                }\n            }];\n        }\n            break;\n        case SDImageCacheTypeAll: {\n            BOOL isInMemoryCache = ([self imageFromMemoryCacheForKey:key] != nil);\n            if (isInMemoryCache) {\n                if (completionBlock) {\n                    completionBlock(SDImageCacheTypeMemory);\n                }\n                return;\n            }\n            [self diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) {\n                if (completionBlock) {\n                    completionBlock(isInDiskCache ? SDImageCacheTypeDisk : SDImageCacheTypeNone);\n                }\n            }];\n        }\n            break;\n        default:\n            if (completionBlock) {\n                completionBlock(SDImageCacheTypeNone);\n            }\n            break;\n    }\n}\n\n- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {\n    switch (cacheType) {\n        case SDImageCacheTypeNone: {\n            if (completionBlock) {\n                completionBlock();\n            }\n        }\n            break;\n        case SDImageCacheTypeMemory: {\n            [self clearMemory];\n            if (completionBlock) {\n                completionBlock();\n            }\n        }\n            break;\n        case SDImageCacheTypeDisk: {\n            [self clearDiskOnCompletion:completionBlock];\n        }\n            break;\n        case SDImageCacheTypeAll: {\n            [self clearMemory];\n            [self clearDiskOnCompletion:completionBlock];\n        }\n            break;\n        default: {\n            if (completionBlock) {\n                completionBlock();\n            }\n        }\n            break;\n    }\n}\n\n@end\n\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// Image Cache Expire Type\ntypedef NS_ENUM(NSUInteger, SDImageCacheConfigExpireType) {\n    /**\n     * When the image cache is accessed it will update this value\n     */\n    SDImageCacheConfigExpireTypeAccessDate,\n    /**\n     * When the image cache is created or modified it will update this value (Default)\n     */\n    SDImageCacheConfigExpireTypeModificationDate,\n    /**\n     * When the image cache is created it will update this value\n     */\n    SDImageCacheConfigExpireTypeCreationDate,\n    /**\n     * When the image cache is created, modified, renamed, file attribute updated (like permission, xattr)  it will update this value\n     */\n    SDImageCacheConfigExpireTypeChangeDate,\n};\n\n/**\n The class contains all the config for image cache\n @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well.\n */\n@interface SDImageCacheConfig : NSObject <NSCopying>\n\n/**\n Gets the default cache config used for shared instance or initialization when it does not provide any cache config. Such as `SDImageCache.sharedImageCache`.\n @note You can modify the property on default cache config, which can be used for later created cache instance. The already created cache instance does not get affected.\n */\n@property (nonatomic, class, readonly, nonnull) SDImageCacheConfig *defaultCacheConfig;\n\n/**\n * Whether or not to disable iCloud backup\n * Defaults to YES.\n */\n@property (assign, nonatomic) BOOL shouldDisableiCloud;\n\n/**\n * Whether or not to use memory cache\n * @note When the memory cache is disabled, the weak memory cache will also be disabled.\n * Defaults to YES.\n */\n@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;\n\n/*\n * The option to control weak memory cache for images. When enable, `SDImageCache`'s memory cache will use a weak maptable to store the image at the same time when it stored to memory, and get removed at the same time.\n * However when memory warning is triggered, since the weak maptable does not hold a strong reference to image instance, even when the memory cache itself is purged, some images which are held strongly by UIImageViews or other live instances can be recovered again, to avoid later re-query from disk cache or network. This may be helpful for the case, for example, when app enter background and memory is purged, cause cell flashing after re-enter foreground.\n * Defaults to YES. You can change this option dynamically.\n */\n@property (assign, nonatomic) BOOL shouldUseWeakMemoryCache;\n\n/**\n * Whether or not to remove the expired disk data when application entering the background. (Not works for macOS)\n * Defaults to YES.\n */\n@property (assign, nonatomic) BOOL shouldRemoveExpiredDataWhenEnterBackground;\n\n/**\n * Whether or not to remove the expired disk data when application been terminated. This operation is processed in sync to ensure clean up.\n * Defaults to YES.\n */\n@property (assign, nonatomic) BOOL shouldRemoveExpiredDataWhenTerminate;\n\n/**\n * The reading options while reading cache from disk.\n * Defaults to 0. You can set this to `NSDataReadingMappedIfSafe` to improve performance.\n */\n@property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions;\n\n/**\n * The writing options while writing cache to disk.\n * Defaults to `NSDataWritingAtomic`. You can set this to `NSDataWritingWithoutOverwriting` to prevent overwriting an existing file.\n */\n@property (assign, nonatomic) NSDataWritingOptions diskCacheWritingOptions;\n\n/**\n * The maximum length of time to keep an image in the disk cache, in seconds.\n * Setting this to a negative value means no expiring.\n * Setting this to zero means that all cached files would be removed when do expiration check.\n * Defaults to 1 week.\n */\n@property (assign, nonatomic) NSTimeInterval maxDiskAge;\n\n/**\n * The maximum size of the disk cache, in bytes.\n * Defaults to 0. Which means there is no cache size limit.\n */\n@property (assign, nonatomic) NSUInteger maxDiskSize;\n\n/**\n * The maximum \"total cost\" of the in-memory image cache. The cost function is the bytes size held in memory.\n * @note The memory cost is bytes size in memory, but not simple pixels count. For common ARGB8888 image, one pixel is 4 bytes (32 bits).\n * Defaults to 0. Which means there is no memory cost limit.\n */\n@property (assign, nonatomic) NSUInteger maxMemoryCost;\n\n/**\n * The maximum number of objects in-memory image cache should hold.\n * Defaults to 0. Which means there is no memory count limit.\n */\n@property (assign, nonatomic) NSUInteger maxMemoryCount;\n\n/*\n * The attribute which the clear cache will be checked against when clearing the disk cache\n * Default is Modified Date\n */\n@property (assign, nonatomic) SDImageCacheConfigExpireType diskCacheExpireType;\n\n/**\n * The custom file manager for disk cache. Pass nil to let disk cache choose the proper file manager.\n * Defaults to nil.\n * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect.\n * @note Since `NSFileManager` does not support `NSCopying`. We just pass this by reference during copying. So it's not recommend to set this value on `defaultCacheConfig`.\n */\n@property (strong, nonatomic, nullable) NSFileManager *fileManager;\n\n/**\n * The custom memory cache class. Provided class instance must conform to `SDMemoryCache` protocol to allow usage.\n * Defaults to built-in `SDMemoryCache` class.\n * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect.\n */\n@property (assign, nonatomic, nonnull) Class memoryCacheClass;\n\n/**\n * The custom disk cache class. Provided class instance must conform to `SDDiskCache` protocol to allow usage.\n * Defaults to built-in `SDDiskCache` class.\n * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect.\n */\n@property (assign ,nonatomic, nonnull) Class diskCacheClass;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCacheConfig.h\"\n#import \"SDMemoryCache.h\"\n#import \"SDDiskCache.h\"\n\nstatic SDImageCacheConfig *_defaultCacheConfig;\nstatic const NSInteger kDefaultCacheMaxDiskAge = 60 * 60 * 24 * 7; // 1 week\n\n@implementation SDImageCacheConfig\n\n+ (SDImageCacheConfig *)defaultCacheConfig {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _defaultCacheConfig = [SDImageCacheConfig new];\n    });\n    return _defaultCacheConfig;\n}\n\n- (instancetype)init {\n    if (self = [super init]) {\n        _shouldDisableiCloud = YES;\n        _shouldCacheImagesInMemory = YES;\n        _shouldUseWeakMemoryCache = YES;\n        _shouldRemoveExpiredDataWhenEnterBackground = YES;\n        _shouldRemoveExpiredDataWhenTerminate = YES;\n        _diskCacheReadingOptions = 0;\n        _diskCacheWritingOptions = NSDataWritingAtomic;\n        _maxDiskAge = kDefaultCacheMaxDiskAge;\n        _maxDiskSize = 0;\n        _diskCacheExpireType = SDImageCacheConfigExpireTypeModificationDate;\n        _memoryCacheClass = [SDMemoryCache class];\n        _diskCacheClass = [SDDiskCache class];\n    }\n    return self;\n}\n\n- (id)copyWithZone:(NSZone *)zone {\n    SDImageCacheConfig *config = [[[self class] allocWithZone:zone] init];\n    config.shouldDisableiCloud = self.shouldDisableiCloud;\n    config.shouldCacheImagesInMemory = self.shouldCacheImagesInMemory;\n    config.shouldUseWeakMemoryCache = self.shouldUseWeakMemoryCache;\n    config.shouldRemoveExpiredDataWhenEnterBackground = self.shouldRemoveExpiredDataWhenEnterBackground;\n    config.shouldRemoveExpiredDataWhenTerminate = self.shouldRemoveExpiredDataWhenTerminate;\n    config.diskCacheReadingOptions = self.diskCacheReadingOptions;\n    config.diskCacheWritingOptions = self.diskCacheWritingOptions;\n    config.maxDiskAge = self.maxDiskAge;\n    config.maxDiskSize = self.maxDiskSize;\n    config.maxMemoryCost = self.maxMemoryCost;\n    config.maxMemoryCount = self.maxMemoryCount;\n    config.diskCacheExpireType = self.diskCacheExpireType;\n    config.fileManager = self.fileManager; // NSFileManager does not conform to NSCopying, just pass the reference\n    config.memoryCacheClass = self.memoryCacheClass;\n    config.diskCacheClass = self.diskCacheClass;\n    \n    return config;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageOperation.h\"\n#import \"SDWebImageDefine.h\"\n\n/// Image Cache Type\ntypedef NS_ENUM(NSInteger, SDImageCacheType) {\n    /**\n     * For query and contains op in response, means the image isn't available in the image cache\n     * For op in request, this type is not available and take no effect.\n     */\n    SDImageCacheTypeNone,\n    /**\n     * For query and contains op in response, means the image was obtained from the disk cache.\n     * For op in request, means process only disk cache.\n     */\n    SDImageCacheTypeDisk,\n    /**\n     * For query and contains op in response, means the image was obtained from the memory cache.\n     * For op in request, means process only memory cache.\n     */\n    SDImageCacheTypeMemory,\n    /**\n     * For query and contains op in response, this type is not available and take no effect.\n     * For op in request, means process both memory cache and disk cache.\n     */\n    SDImageCacheTypeAll\n};\n\ntypedef void(^SDImageCacheCheckCompletionBlock)(BOOL isInCache);\ntypedef void(^SDImageCacheQueryDataCompletionBlock)(NSData * _Nullable data);\ntypedef void(^SDImageCacheCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);\ntypedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString * _Nonnull key);\ntypedef void(^SDImageCacheQueryCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType);\ntypedef void(^SDImageCacheContainsCompletionBlock)(SDImageCacheType containsCacheType);\n\n/**\n This is the built-in decoding process for image query from cache.\n @note If you want to implement your custom loader with `queryImageForKey:options:context:completion:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image.\n \n @param imageData The image data from the cache. Should not be nil\n @param cacheKey The image cache key from the input. Should not be nil\n @param options The options arg from the input\n @param context The context arg from the input\n @return The decoded image for current image data query from cache\n */\nFOUNDATION_EXPORT UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context);\n\n/**\n This is the image cache protocol to provide custom image cache for `SDWebImageManager`.\n Though the best practice to custom image cache, is to write your own class which conform `SDMemoryCache` or `SDDiskCache` protocol for `SDImageCache` class (See more on `SDImageCacheConfig.memoryCacheClass & SDImageCacheConfig.diskCacheClass`).\n However, if your own cache implementation contains more advanced feature beyond `SDImageCache` itself, you can consider to provide this instead. For example, you can even use a cache manager like `SDImageCachesManager` to register multiple caches.\n */\n@protocol SDImageCache <NSObject>\n\n@required\n/**\n Query the cached image from image cache for given key. The operation can be used to cancel the query.\n If image is cached in memory, completion is called synchronously, else asynchronously and depends on the options arg (See `SDWebImageQueryDiskSync`)\n\n @param key The image cache key\n @param options A mask to specify options to use for this query\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @param completionBlock The completion block. Will not get called if the operation is cancelled\n @return The operation for this query\n */\n- (nullable id<SDWebImageOperation>)queryImageForKey:(nullable NSString *)key\n                                             options:(SDWebImageOptions)options\n                                             context:(nullable SDWebImageContext *)context\n                                          completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock;\n\n/**\n Query the cached image from image cache for given key. The operation can be used to cancel the query.\n If image is cached in memory, completion is called synchronously, else asynchronously and depends on the options arg (See `SDWebImageQueryDiskSync`)\n\n @param key The image cache key\n @param options A mask to specify options to use for this query\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @param cacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediately.\n @param completionBlock The completion block. Will not get called if the operation is cancelled\n @return The operation for this query\n */\n- (nullable id<SDWebImageOperation>)queryImageForKey:(nullable NSString *)key\n                                             options:(SDWebImageOptions)options\n                                             context:(nullable SDWebImageContext *)context\n                                           cacheType:(SDImageCacheType)cacheType\n                                          completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock;\n\n/**\n Store the image into image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously.\n\n @param image The image to store\n @param imageData The image data to be used for disk storage\n @param key The image cache key\n @param cacheType The image store op cache type\n @param completionBlock A block executed after the operation is finished\n */\n- (void)storeImage:(nullable UIImage *)image\n         imageData:(nullable NSData *)imageData\n            forKey:(nullable NSString *)key\n         cacheType:(SDImageCacheType)cacheType\n        completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n/**\n Remove the image from image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously.\n\n @param key The image cache key\n @param cacheType The image remove op cache type\n @param completionBlock A block executed after the operation is finished\n */\n- (void)removeImageForKey:(nullable NSString *)key\n                cacheType:(SDImageCacheType)cacheType\n               completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n/**\n Check if image cache contains the image for the given key (does not load the image). If image is cached in memory, completion is called synchronously, else asynchronously.\n\n @param key The image cache key\n @param cacheType The image contains op cache type\n @param completionBlock A block executed after the operation is finished.\n */\n- (void)containsImageForKey:(nullable NSString *)key\n                  cacheType:(SDImageCacheType)cacheType\n                 completion:(nullable SDImageCacheContainsCompletionBlock)completionBlock;\n\n/**\n Clear all the cached images for image cache. If cache type is memory only, completion is called synchronously, else asynchronously.\n\n @param cacheType The image clear op cache type\n @param completionBlock A block executed after the operation is finished\n */\n- (void)clearWithCacheType:(SDImageCacheType)cacheType\n                completion:(nullable SDWebImageNoParamsBlock)completionBlock;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCacheDefine.h\"\n#import \"SDImageCodersManager.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDAnimatedImage.h\"\n#import \"UIImage+Metadata.h\"\n#import \"SDInternalMacros.h\"\n\nUIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context) {\n    UIImage *image;\n    BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);\n    NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];\n    CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey);\n    NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio];\n    NSValue *thumbnailSizeValue;\n    BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages);\n    if (shouldScaleDown) {\n        CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4;\n        CGFloat dimension = ceil(sqrt(thumbnailPixels));\n        thumbnailSizeValue = @(CGSizeMake(dimension, dimension));\n    }\n    if (context[SDWebImageContextImageThumbnailPixelSize]) {\n        thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];\n    }\n    \n    SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2];\n    mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame);\n    mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);\n    mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue;\n    mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue;\n    mutableCoderOptions[SDImageCoderWebImageContext] = context;\n    SDImageCoderOptions *coderOptions = [mutableCoderOptions copy];\n    \n    // Grab the image coder\n    id<SDImageCoder> imageCoder;\n    if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) {\n        imageCoder = context[SDWebImageContextImageCoder];\n    } else {\n        imageCoder = [SDImageCodersManager sharedManager];\n    }\n    \n    if (!decodeFirstFrame) {\n        Class animatedImageClass = context[SDWebImageContextAnimatedImageClass];\n        // check whether we should use `SDAnimatedImage`\n        if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) {\n            image = [[animatedImageClass alloc] initWithData:imageData scale:scale options:coderOptions];\n            if (image) {\n                // Preload frames if supported\n                if (options & SDWebImagePreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) {\n                    [((id<SDAnimatedImage>)image) preloadAllFrames];\n                }\n            } else {\n                // Check image class matching\n                if (options & SDWebImageMatchAnimatedImageClass) {\n                    return nil;\n                }\n            }\n        }\n    }\n    if (!image) {\n        image = [imageCoder decodedImageWithData:imageData options:coderOptions];\n    }\n    if (image) {\n        BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage);\n        if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {\n            // `SDAnimatedImage` do not decode\n            shouldDecode = NO;\n        } else if (image.sd_isAnimated) {\n            // animated image do not decode\n            shouldDecode = NO;\n        }\n        if (shouldDecode) {\n            image = [SDImageCoderHelper decodedImageWithImage:image];\n        }\n    }\n    \n    return image;\n}\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageCacheDefine.h\"\n\n/// Policy for cache operation\ntypedef NS_ENUM(NSUInteger, SDImageCachesManagerOperationPolicy) {\n    SDImageCachesManagerOperationPolicySerial, // process all caches serially (from the highest priority to the lowest priority cache by order)\n    SDImageCachesManagerOperationPolicyConcurrent, // process all caches concurrently\n    SDImageCachesManagerOperationPolicyHighestOnly, // process the highest priority cache only\n    SDImageCachesManagerOperationPolicyLowestOnly // process the lowest priority cache only\n};\n\n/**\n A caches manager to manage multiple caches.\n */\n@interface SDImageCachesManager : NSObject <SDImageCache>\n\n/**\n Returns the global shared caches manager instance. By default we will set [`SDImageCache.sharedImageCache`] into the caches array.\n */\n@property (nonatomic, class, readonly, nonnull) SDImageCachesManager *sharedManager;\n\n// These are op policy for cache manager.\n\n/**\n Operation policy for query op.\n Defaults to `Serial`, means query all caches serially (one completion called then next begin) until one cache query success (`image` != nil).\n */\n@property (nonatomic, assign) SDImageCachesManagerOperationPolicy queryOperationPolicy;\n\n/**\n Operation policy for store op.\n Defaults to `HighestOnly`, means store to the highest priority cache only.\n */\n@property (nonatomic, assign) SDImageCachesManagerOperationPolicy storeOperationPolicy;\n\n/**\n Operation policy for remove op.\n Defaults to `Concurrent`, means remove all caches concurrently.\n */\n@property (nonatomic, assign) SDImageCachesManagerOperationPolicy removeOperationPolicy;\n\n/**\n Operation policy for contains op.\n Defaults to `Serial`, means check all caches serially (one completion called then next begin) until one cache check success (`containsCacheType` != None).\n */\n@property (nonatomic, assign) SDImageCachesManagerOperationPolicy containsOperationPolicy;\n\n/**\n Operation policy for clear op.\n Defaults to `Concurrent`, means clear all caches concurrently.\n */\n@property (nonatomic, assign) SDImageCachesManagerOperationPolicy clearOperationPolicy;\n\n/**\n All caches in caches manager. The caches array is a priority queue, which means the later added cache will have the highest priority\n */\n@property (nonatomic, copy, nullable) NSArray<id<SDImageCache>> *caches;\n\n/**\n Add a new cache to the end of caches array. Which has the highest priority.\n \n @param cache cache\n */\n- (void)addCache:(nonnull id<SDImageCache>)cache;\n\n/**\n Remove a cache in the caches array.\n \n @param cache cache\n */\n- (void)removeCache:(nonnull id<SDImageCache>)cache;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCachesManager.h\"\n#import \"SDImageCachesManagerOperation.h\"\n#import \"SDImageCache.h\"\n#import \"SDInternalMacros.h\"\n\n@interface SDImageCachesManager ()\n\n@property (nonatomic, strong, nonnull) NSMutableArray<id<SDImageCache>> *imageCaches;\n\n@end\n\n@implementation SDImageCachesManager {\n    SD_LOCK_DECLARE(_cachesLock);\n}\n\n+ (SDImageCachesManager *)sharedManager {\n    static dispatch_once_t onceToken;\n    static SDImageCachesManager *manager;\n    dispatch_once(&onceToken, ^{\n        manager = [[SDImageCachesManager alloc] init];\n    });\n    return manager;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        self.queryOperationPolicy = SDImageCachesManagerOperationPolicySerial;\n        self.storeOperationPolicy = SDImageCachesManagerOperationPolicyHighestOnly;\n        self.removeOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;\n        self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial;\n        self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;\n        // initialize with default image caches\n        _imageCaches = [NSMutableArray arrayWithObject:[SDImageCache sharedImageCache]];\n        SD_LOCK_INIT(_cachesLock);\n    }\n    return self;\n}\n\n- (NSArray<id<SDImageCache>> *)caches {\n    SD_LOCK(_cachesLock);\n    NSArray<id<SDImageCache>> *caches = [_imageCaches copy];\n    SD_UNLOCK(_cachesLock);\n    return caches;\n}\n\n- (void)setCaches:(NSArray<id<SDImageCache>> *)caches {\n    SD_LOCK(_cachesLock);\n    [_imageCaches removeAllObjects];\n    if (caches.count) {\n        [_imageCaches addObjectsFromArray:caches];\n    }\n    SD_UNLOCK(_cachesLock);\n}\n\n#pragma mark - Cache IO operations\n\n- (void)addCache:(id<SDImageCache>)cache {\n    if (![cache conformsToProtocol:@protocol(SDImageCache)]) {\n        return;\n    }\n    SD_LOCK(_cachesLock);\n    [_imageCaches addObject:cache];\n    SD_UNLOCK(_cachesLock);\n}\n\n- (void)removeCache:(id<SDImageCache>)cache {\n    if (![cache conformsToProtocol:@protocol(SDImageCache)]) {\n        return;\n    }\n    SD_LOCK(_cachesLock);\n    [_imageCaches removeObject:cache];\n    SD_UNLOCK(_cachesLock);\n}\n\n#pragma mark - SDImageCache\n\n- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)completionBlock {\n    return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:completionBlock];\n}\n\n- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock {\n    if (!key) {\n        return nil;\n    }\n    NSArray<id<SDImageCache>> *caches = self.caches;\n    NSUInteger count = caches.count;\n    if (count == 0) {\n        return nil;\n    } else if (count == 1) {\n        return [caches.firstObject queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];\n    }\n    switch (self.queryOperationPolicy) {\n        case SDImageCachesManagerOperationPolicyHighestOnly: {\n            id<SDImageCache> cache = caches.lastObject;\n            return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyLowestOnly: {\n            id<SDImageCache> cache = caches.firstObject;\n            return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyConcurrent: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self concurrentQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n            return operation;\n        }\n            break;\n        case SDImageCachesManagerOperationPolicySerial: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self serialQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n            return operation;\n        }\n            break;\n        default:\n            return nil;\n            break;\n    }\n}\n\n- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {\n    if (!key) {\n        return;\n    }\n    NSArray<id<SDImageCache>> *caches = self.caches;\n    NSUInteger count = caches.count;\n    if (count == 0) {\n        return;\n    } else if (count == 1) {\n        [caches.firstObject storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock];\n        return;\n    }\n    switch (self.storeOperationPolicy) {\n        case SDImageCachesManagerOperationPolicyHighestOnly: {\n            id<SDImageCache> cache = caches.lastObject;\n            [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyLowestOnly: {\n            id<SDImageCache> cache = caches.firstObject;\n            [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyConcurrent: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self concurrentStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicySerial: {\n            [self serialStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator];\n        }\n            break;\n        default:\n            break;\n    }\n}\n\n- (void)removeImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {\n    if (!key) {\n        return;\n    }\n    NSArray<id<SDImageCache>> *caches = self.caches;\n    NSUInteger count = caches.count;\n    if (count == 0) {\n        return;\n    } else if (count == 1) {\n        [caches.firstObject removeImageForKey:key cacheType:cacheType completion:completionBlock];\n        return;\n    }\n    switch (self.removeOperationPolicy) {\n        case SDImageCachesManagerOperationPolicyHighestOnly: {\n            id<SDImageCache> cache = caches.lastObject;\n            [cache removeImageForKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyLowestOnly: {\n            id<SDImageCache> cache = caches.firstObject;\n            [cache removeImageForKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyConcurrent: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self concurrentRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicySerial: {\n            [self serialRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator];\n        }\n            break;\n        default:\n            break;\n    }\n}\n\n- (void)containsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock {\n    if (!key) {\n        return;\n    }\n    NSArray<id<SDImageCache>> *caches = self.caches;\n    NSUInteger count = caches.count;\n    if (count == 0) {\n        return;\n    } else if (count == 1) {\n        [caches.firstObject containsImageForKey:key cacheType:cacheType completion:completionBlock];\n        return;\n    }\n    switch (self.clearOperationPolicy) {\n        case SDImageCachesManagerOperationPolicyHighestOnly: {\n            id<SDImageCache> cache = caches.lastObject;\n            [cache containsImageForKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyLowestOnly: {\n            id<SDImageCache> cache = caches.firstObject;\n            [cache containsImageForKey:key cacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyConcurrent: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self concurrentContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicySerial: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self serialContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n        }\n            break;\n        default:\n            break;\n    }\n}\n\n- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {\n    NSArray<id<SDImageCache>> *caches = self.caches;\n    NSUInteger count = caches.count;\n    if (count == 0) {\n        return;\n    } else if (count == 1) {\n        [caches.firstObject clearWithCacheType:cacheType completion:completionBlock];\n        return;\n    }\n    switch (self.clearOperationPolicy) {\n        case SDImageCachesManagerOperationPolicyHighestOnly: {\n            id<SDImageCache> cache = caches.lastObject;\n            [cache clearWithCacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyLowestOnly: {\n            id<SDImageCache> cache = caches.firstObject;\n            [cache clearWithCacheType:cacheType completion:completionBlock];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicyConcurrent: {\n            SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];\n            [operation beginWithTotalCount:caches.count];\n            [self concurrentClearWithCacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];\n        }\n            break;\n        case SDImageCachesManagerOperationPolicySerial: {\n            [self serialClearWithCacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator];\n        }\n            break;\n        default:\n            break;\n    }\n}\n\n#pragma mark - Concurrent Operation\n\n- (void)concurrentQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    for (id<SDImageCache> cache in enumerator) {\n        [cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {\n            if (operation.isCancelled) {\n                // Cancelled\n                return;\n            }\n            if (operation.isFinished) {\n                // Finished\n                return;\n            }\n            [operation completeOne];\n            if (image) {\n                // Success\n                [operation done];\n                if (completionBlock) {\n                    completionBlock(image, data, cacheType);\n                }\n                return;\n            }\n            if (operation.pendingCount == 0) {\n                // Complete\n                [operation done];\n                if (completionBlock) {\n                    completionBlock(nil, nil, SDImageCacheTypeNone);\n                }\n            }\n        }];\n    }\n}\n\n- (void)concurrentStoreImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    for (id<SDImageCache> cache in enumerator) {\n        [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:^{\n            if (operation.isCancelled) {\n                // Cancelled\n                return;\n            }\n            if (operation.isFinished) {\n                // Finished\n                return;\n            }\n            [operation completeOne];\n            if (operation.pendingCount == 0) {\n                // Complete\n                [operation done];\n                if (completionBlock) {\n                    completionBlock();\n                }\n            }\n        }];\n    }\n}\n\n- (void)concurrentRemoveImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    for (id<SDImageCache> cache in enumerator) {\n        [cache removeImageForKey:key cacheType:cacheType completion:^{\n            if (operation.isCancelled) {\n                // Cancelled\n                return;\n            }\n            if (operation.isFinished) {\n                // Finished\n                return;\n            }\n            [operation completeOne];\n            if (operation.pendingCount == 0) {\n                // Complete\n                [operation done];\n                if (completionBlock) {\n                    completionBlock();\n                }\n            }\n        }];\n    }\n}\n\n- (void)concurrentContainsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    for (id<SDImageCache> cache in enumerator) {\n        [cache containsImageForKey:key cacheType:cacheType completion:^(SDImageCacheType containsCacheType) {\n            if (operation.isCancelled) {\n                // Cancelled\n                return;\n            }\n            if (operation.isFinished) {\n                // Finished\n                return;\n            }\n            [operation completeOne];\n            if (containsCacheType != SDImageCacheTypeNone) {\n                // Success\n                [operation done];\n                if (completionBlock) {\n                    completionBlock(containsCacheType);\n                }\n                return;\n            }\n            if (operation.pendingCount == 0) {\n                // Complete\n                [operation done];\n                if (completionBlock) {\n                    completionBlock(SDImageCacheTypeNone);\n                }\n            }\n        }];\n    }\n}\n\n- (void)concurrentClearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    for (id<SDImageCache> cache in enumerator) {\n        [cache clearWithCacheType:cacheType completion:^{\n            if (operation.isCancelled) {\n                // Cancelled\n                return;\n            }\n            if (operation.isFinished) {\n                // Finished\n                return;\n            }\n            [operation completeOne];\n            if (operation.pendingCount == 0) {\n                // Complete\n                [operation done];\n                if (completionBlock) {\n                    completionBlock();\n                }\n            }\n        }];\n    }\n}\n\n#pragma mark - Serial Operation\n\n- (void)serialQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    id<SDImageCache> cache = enumerator.nextObject;\n    if (!cache) {\n        // Complete\n        [operation done];\n        if (completionBlock) {\n            completionBlock(nil, nil, SDImageCacheTypeNone);\n        }\n        return;\n    }\n    @weakify(self);\n    [cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {\n        @strongify(self);\n        if (operation.isCancelled) {\n            // Cancelled\n            return;\n        }\n        if (operation.isFinished) {\n            // Finished\n            return;\n        }\n        [operation completeOne];\n        if (image) {\n            // Success\n            [operation done];\n            if (completionBlock) {\n                completionBlock(image, data, cacheType);\n            }\n            return;\n        }\n        // Next\n        [self serialQueryImageForKey:key options:options context:context cacheType:queryCacheType completion:completionBlock enumerator:enumerator operation:operation];\n    }];\n}\n\n- (void)serialStoreImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator {\n    NSParameterAssert(enumerator);\n    id<SDImageCache> cache = enumerator.nextObject;\n    if (!cache) {\n        // Complete\n        if (completionBlock) {\n            completionBlock();\n        }\n        return;\n    }\n    @weakify(self);\n    [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:^{\n        @strongify(self);\n        // Next\n        [self serialStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator];\n    }];\n}\n\n- (void)serialRemoveImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator {\n    NSParameterAssert(enumerator);\n    id<SDImageCache> cache = enumerator.nextObject;\n    if (!cache) {\n        // Complete\n        if (completionBlock) {\n            completionBlock();\n        }\n        return;\n    }\n    @weakify(self);\n    [cache removeImageForKey:key cacheType:cacheType completion:^{\n        @strongify(self);\n        // Next\n        [self serialRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator];\n    }];\n}\n\n- (void)serialContainsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {\n    NSParameterAssert(enumerator);\n    NSParameterAssert(operation);\n    id<SDImageCache> cache = enumerator.nextObject;\n    if (!cache) {\n        // Complete\n        [operation done];\n        if (completionBlock) {\n            completionBlock(SDImageCacheTypeNone);\n        }\n        return;\n    }\n    @weakify(self);\n    [cache containsImageForKey:key cacheType:cacheType completion:^(SDImageCacheType containsCacheType) {\n        @strongify(self);\n        if (operation.isCancelled) {\n            // Cancelled\n            return;\n        }\n        if (operation.isFinished) {\n            // Finished\n            return;\n        }\n        [operation completeOne];\n        if (containsCacheType != SDImageCacheTypeNone) {\n            // Success\n            [operation done];\n            if (completionBlock) {\n                completionBlock(containsCacheType);\n            }\n            return;\n        }\n        // Next\n        [self serialContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator operation:operation];\n    }];\n}\n\n- (void)serialClearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator {\n    NSParameterAssert(enumerator);\n    id<SDImageCache> cache = enumerator.nextObject;\n    if (!cache) {\n        // Complete\n        if (completionBlock) {\n            completionBlock();\n        }\n        return;\n    }\n    @weakify(self);\n    [cache clearWithCacheType:cacheType completion:^{\n        @strongify(self);\n        // Next\n        [self serialClearWithCacheType:cacheType completion:completionBlock enumerator:enumerator];\n    }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCoder.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"NSData+ImageContentType.h\"\n\ntypedef NSString * SDImageCoderOption NS_STRING_ENUM;\ntypedef NSDictionary<SDImageCoderOption, id> SDImageCoderOptions;\ntypedef NSMutableDictionary<SDImageCoderOption, id> SDImageCoderMutableOptions;\n\n#pragma mark - Coder Options\n// These options are for image decoding\n/**\n A Boolean value indicating whether to decode the first frame only for animated image during decoding. (NSNumber). If not provide, decode animated image if need.\n @note works for `SDImageCoder`.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeFirstFrameOnly;\n\n/**\n A CGFloat value which is greater than or equal to 1.0. This value specify the image scale factor for decoding. If not provide, use 1.0. (NSNumber)\n @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeScaleFactor;\n\n/**\n A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format).\n Defaults to YES.\n @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodePreserveAspectRatio;\n\n/**\n A CGSize value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.preserveAspectRatio`) the value size.\n Defaults to CGSizeZero, which means no thumbnail generation at all.\n @note Supports for animated image as well.\n @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.\n @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeThumbnailPixelSize;\n\n\n// These options are for image encoding\n/**\n A Boolean value indicating whether to encode the first frame only for animated image during encoding. (NSNumber). If not provide, encode animated image if need.\n @note works for `SDImageCoder`.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeFirstFrameOnly;\n/**\n A double value between 0.0-1.0 indicating the encode compression quality to produce the image data. 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. If not provide, use 1.0. (NSNumber)\n @note works for `SDImageCoder`\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeCompressionQuality;\n\n/**\n A UIColor(NSColor) value to used for non-alpha image encoding when the input image has alpha channel, the background color will be used to compose the alpha one. If not provide, use white color.\n @note works for `SDImageCoder`\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeBackgroundColor;\n\n/**\n A CGSize value indicating the max image resolution in pixels during encoding. For vector image, this also effect the output vector data information about width and height. The encoder will not generate the encoded image larger than this limit. Note it always use the aspect ratio of input image..\n Defaults to CGSizeZero, which means no max size limit at all.\n @note Supports for animated image as well.\n @note The output image's width is limited to pixel size's width, the output image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.\n @note works for `SDImageCoder`\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeMaxPixelSize;\n\n/**\n A NSUInteger value specify the max output data bytes size after encoding. Some lossy format like JPEG/HEIF supports the hint for codec to automatically reduce the quality and match the file size you want. Note this option will override the `SDImageCoderEncodeCompressionQuality`, because now the quality is decided by the encoder. (NSNumber)\n @note This is a hint, no guarantee for output size because of compression algorithm limit. And this options does not works for vector images.\n @note works for `SDImageCoder`\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeMaxFileSize;\n\n/**\n A Boolean value indicating the encoding format should contains a thumbnail image into the output data. Only some of image format (like JPEG/HEIF/AVIF) support this behavior. The embed thumbnail will be used during next time thumbnail decoding (provided `.thumbnailPixelSize`), which is faster than full image thumbnail decoding. (NSNumber)\n Defaults to NO, which does not embed any thumbnail.\n @note The thumbnail image's pixel size is not defined, the encoder can choose the proper pixel size which is suitable for encoding quality.\n @note works for `SDImageCoder`\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeEmbedThumbnail;\n\n/**\n A SDWebImageContext object which hold the original context options from top-level API. (SDWebImageContext)\n This option is ignored for all built-in coders and take no effect.\n But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data information only.\n See `SDWebImageContext` for more detailed information.\n */\nFOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderWebImageContext API_DEPRECATED(\"The coder component will be seperated from Core subspec in the future. Update your code to not rely on this context option.\", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));\n\n#pragma mark - Coder\n/**\n This is the image coder protocol to provide custom image decoding/encoding.\n These methods are all required to implement.\n @note Pay attention that these methods are not called from main queue.\n */\n@protocol SDImageCoder <NSObject>\n\n@required\n#pragma mark - Decoding\n/**\n Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder.\n \n @param data The image data so we can look at it\n @return YES if this coder can decode the data, NO otherwise\n */\n- (BOOL)canDecodeFromData:(nullable NSData *)data;\n\n/**\n Decode the image data to image.\n @note This protocol may supports decode animated image frames. You can use `+[SDImageCoderHelper animatedImageWithFrames:]` to produce an animated image with frames.\n\n @param data The image data to be decoded\n @param options A dictionary containing any decoding options. Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for image. Pass @{SDImageCoderDecodeFirstFrameOnly: @(YES)} to decode the first frame only.\n @return The decoded image from data\n */\n- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data\n                                   options:(nullable SDImageCoderOptions *)options;\n\n#pragma mark - Encoding\n\n/**\n Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder.\n For custom coder which introduce new image format, you'd better define a new `SDImageFormat` using like this. If you're creating public coder plugin for new image format, also update `https://github.com/rs/SDWebImage/wiki/Coder-Plugin-List` to avoid same value been defined twice.\n * @code\n static const SDImageFormat SDImageFormatHEIF = 10;\n * @endcode\n \n @param format The image format\n @return YES if this coder can encode the image, NO otherwise\n */\n- (BOOL)canEncodeToFormat:(SDImageFormat)format NS_SWIFT_NAME(canEncode(to:));\n\n/**\n Encode the image to image data.\n @note This protocol may supports encode animated image frames. You can use `+[SDImageCoderHelper framesFromAnimatedImage:]` to assemble an animated image with frames.\n\n @param image The image to be encoded\n @param format The image format to encode, you should note `SDImageFormatUndefined` format is also  possible\n @param options A dictionary containing any encoding options. Pass @{SDImageCoderEncodeCompressionQuality: @(1)} to specify compression quality.\n @return The encoded image data\n */\n- (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image\n                                   format:(SDImageFormat)format\n                                  options:(nullable SDImageCoderOptions *)options;\n\n@end\n\n#pragma mark - Progressive Coder\n/**\n This is the image coder protocol to provide custom progressive image decoding.\n These methods are all required to implement.\n @note Pay attention that these methods are not called from main queue.\n */\n@protocol SDProgressiveImageCoder <SDImageCoder>\n\n@required\n/**\n Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder.\n \n @param data The image data so we can look at it\n @return YES if this coder can decode the data, NO otherwise\n */\n- (BOOL)canIncrementalDecodeFromData:(nullable NSData *)data;\n\n/**\n Because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts\n This init method should not return nil\n\n @param options A dictionary containing any progressive decoding options (instance-level). Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive animated image (each frames should use the same scale).\n @return A new instance to do incremental decoding for the specify image format\n */\n- (nonnull instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options;\n\n/**\n Update the incremental decoding when new image data available\n\n @param data The image data has been downloaded so far\n @param finished Whether the download has finished\n */\n- (void)updateIncrementalData:(nullable NSData *)data finished:(BOOL)finished;\n\n/**\n Incremental decode the current image data to image.\n @note Due to the performance issue for progressive decoding and the integration for image view. This method may only return the first frame image even if the image data is animated image. If you want progressive animated image decoding, conform to `SDAnimatedImageCoder` protocol as well and use `animatedImageFrameAtIndex:` instead.\n\n @param options A dictionary containing any progressive decoding options. Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive image\n @return The decoded image from current data\n */\n- (nullable UIImage *)incrementalDecodedImageWithOptions:(nullable SDImageCoderOptions *)options;\n\n@end\n\n#pragma mark - Animated Image Provider\n/**\n This is the animated image protocol to provide the basic function for animated image rendering. It's adopted by `SDAnimatedImage` and `SDAnimatedImageCoder`\n */\n@protocol SDAnimatedImageProvider <NSObject>\n\n@required\n/**\n The original animated image data for current image. If current image is not an animated format, return nil.\n We may use this method to grab back the original image data if need, such as NSCoding or compare.\n \n @return The animated image data\n */\n@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;\n\n/**\n Total animated frame count.\n If the frame count is less than 1, then the methods below will be ignored.\n \n @return Total animated frame count.\n */\n@property (nonatomic, assign, readonly) NSUInteger animatedImageFrameCount;\n/**\n Animation loop count, 0 means infinite looping.\n \n @return Animation loop count\n */\n@property (nonatomic, assign, readonly) NSUInteger animatedImageLoopCount;\n/**\n Returns the frame image from a specified index.\n @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's not recommend to store the images into array because it's memory consuming)\n \n @param index Frame index (zero based).\n @return Frame's image\n */\n- (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index;\n/**\n Returns the frames's duration from a specified index.\n @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's recommend to store the durations into array because it's not memory-consuming)\n \n @param index Frame index (zero based).\n @return Frame's duration\n */\n- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index;\n\n@end\n\n#pragma mark - Animated Coder\n/**\n This is the animated image coder protocol for custom animated image class like  `SDAnimatedImage`. Through it inherit from `SDImageCoder`. We currentlly only use the method `canDecodeFromData:` to detect the proper coder for specify animated image format.\n */\n@protocol SDAnimatedImageCoder <SDImageCoder, SDAnimatedImageProvider>\n\n@required\n/**\n Because animated image coder should keep the original data, we will alloc a new instance with the same class for the specify animated image data\n The init method should return nil if it can't decode the specify animated image data to produce any frame.\n After the instance created, we may call methods in `SDAnimatedImageProvider` to produce animated image frame.\n\n @param data The animated image data to be decode\n @param options A dictionary containing any animated decoding options (instance-level). Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for animated image (each frames should use the same scale).\n @return A new instance to do animated decoding for specify image data\n */\n- (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCoder.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCoder.h\"\n\nSDImageCoderOption const SDImageCoderDecodeFirstFrameOnly = @\"decodeFirstFrameOnly\";\nSDImageCoderOption const SDImageCoderDecodeScaleFactor = @\"decodeScaleFactor\";\nSDImageCoderOption const SDImageCoderDecodePreserveAspectRatio = @\"decodePreserveAspectRatio\";\nSDImageCoderOption const SDImageCoderDecodeThumbnailPixelSize = @\"decodeThumbnailPixelSize\";\n\nSDImageCoderOption const SDImageCoderEncodeFirstFrameOnly = @\"encodeFirstFrameOnly\";\nSDImageCoderOption const SDImageCoderEncodeCompressionQuality = @\"encodeCompressionQuality\";\nSDImageCoderOption const SDImageCoderEncodeBackgroundColor = @\"encodeBackgroundColor\";\nSDImageCoderOption const SDImageCoderEncodeMaxPixelSize = @\"encodeMaxPixelSize\";\nSDImageCoderOption const SDImageCoderEncodeMaxFileSize = @\"encodeMaxFileSize\";\nSDImageCoderOption const SDImageCoderEncodeEmbedThumbnail = @\"encodeEmbedThumbnail\";\n\nSDImageCoderOption const SDImageCoderWebImageContext = @\"webImageContext\";\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <ImageIO/ImageIO.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDImageFrame.h\"\n\n/**\n Provide some common helper methods for building the image decoder/encoder.\n */\n@interface SDImageCoderHelper : NSObject\n\n/**\n Return an animated image with frames array.\n For UIKit, this will apply the patch and then create animated UIImage. The patch is because that `+[UIImage animatedImageWithImages:duration:]` just use the average of duration for each image. So it will not work if different frame has different duration. Therefore we repeat the specify frame for specify times to let it work.\n For AppKit, NSImage does not support animates other than GIF. This will try to encode the frames to GIF format and then create an animated NSImage for rendering. Attention the animated image may loss some detail if the input frames contain full alpha channel because GIF only supports 1 bit alpha channel. (For 1 pixel, either transparent or not)\n\n @param frames The frames array. If no frames or frames is empty, return nil\n @return A animated image for rendering on UIImageView(UIKit) or NSImageView(AppKit)\n */\n+ (UIImage * _Nullable)animatedImageWithFrames:(NSArray<SDImageFrame *> * _Nullable)frames;\n\n/**\n Return frames array from an animated image.\n For UIKit, this will unapply the patch for the description above and then create frames array. This will also work for normal animated UIImage.\n For AppKit, NSImage does not support animates other than GIF. This will try to decode the GIF imageRep and then create frames array.\n\n @param animatedImage A animated image. If it's not animated, return nil\n @return The frames array\n */\n+ (NSArray<SDImageFrame *> * _Nullable)framesFromAnimatedImage:(UIImage * _Nullable)animatedImage NS_SWIFT_NAME(frames(from:));\n\n/**\n Return the shared device-dependent RGB color space. This follows The Get Rule.\n On iOS, it's created with deviceRGB (if available, use sRGB).\n On macOS, it's from the screen colorspace (if failed, use deviceRGB)\n Because it's shared, you should not retain or release this object.\n \n @return The device-dependent RGB color space\n */\n+ (CGColorSpaceRef _Nonnull)colorSpaceGetDeviceRGB CF_RETURNS_NOT_RETAINED;\n\n/**\n Check whether CGImage contains alpha channel.\n \n @param cgImage The CGImage\n @return Return YES if CGImage contains alpha channel, otherwise return NO\n */\n+ (BOOL)CGImageContainsAlpha:(_Nonnull CGImageRef)cgImage;\n\n/**\n Create a decoded CGImage by the provided CGImage. This follows The Create Rule and you are response to call release after usage.\n It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView.\n @note This actually call `CGImageCreateDecoded:orientation:` with the Up orientation.\n\n @param cgImage The CGImage\n @return A new created decoded image\n */\n+ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage CF_RETURNS_RETAINED;\n\n/**\n Create a decoded CGImage by the provided CGImage and orientation. This follows The Create Rule and you are response to call release after usage.\n It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView.\n \n @param cgImage The CGImage\n @param orientation The EXIF image orientation.\n @return A new created decoded image\n */\n+ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage orientation:(CGImagePropertyOrientation)orientation CF_RETURNS_RETAINED;\n\n/**\n Create a scaled CGImage by the provided CGImage and size. This follows The Create Rule and you are response to call release after usage.\n It will detect whether the image size matching the scale size, if not, stretch the image to the target size.\n \n @param cgImage The CGImage\n @param size The scale size in pixel.\n @return A new created scaled image\n */\n+ (CGImageRef _Nullable)CGImageCreateScaled:(_Nonnull CGImageRef)cgImage size:(CGSize)size CF_RETURNS_RETAINED;\n\n/**\n Return the decoded image by the provided image. This one unlike `CGImageCreateDecoded:`, will not decode the image which contains alpha channel or animated image\n @param image The image to be decoded\n @return The decoded image\n */\n+ (UIImage * _Nullable)decodedImageWithImage:(UIImage * _Nullable)image;\n\n/**\n Return the decoded and probably scaled down image by the provided image. If the image pixels bytes size large than the limit bytes, will try to scale down. Or just works as `decodedImageWithImage:`, never scale up.\n @warning You should not pass too small bytes, the suggestion value should be larger than 1MB. Even we use Tile Decoding to avoid OOM, however, small bytes will consume much more CPU time because we need to iterate more times to draw each tile.\n\n @param image The image to be decoded and scaled down\n @param bytes The limit bytes size. Provide 0 to use the build-in limit.\n @return The decoded and probably scaled down image\n */\n+ (UIImage * _Nullable)decodedAndScaledDownImageWithImage:(UIImage * _Nullable)image limitBytes:(NSUInteger)bytes;\n\n/**\n Control the default limit bytes to scale down largest images.\n This value must be larger than 4 Bytes (at least 1x1 pixel). Defaults to 60MB on iOS/tvOS, 90MB on macOS, 30MB on watchOS.\n */\n@property (class, readwrite) NSUInteger defaultScaleDownLimitBytes;\n\n#if SD_UIKIT || SD_WATCH\n/**\n Convert an EXIF image orientation to an iOS one.\n\n @param exifOrientation EXIF orientation\n @return iOS orientation\n */\n+ (UIImageOrientation)imageOrientationFromEXIFOrientation:(CGImagePropertyOrientation)exifOrientation NS_SWIFT_NAME(imageOrientation(from:));\n\n/**\n Convert an iOS orientation to an EXIF image orientation.\n\n @param imageOrientation iOS orientation\n @return EXIF orientation\n */\n+ (CGImagePropertyOrientation)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation;\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCoderHelper.h\"\n#import \"SDImageFrame.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"NSData+ImageContentType.h\"\n#import \"SDAnimatedImageRep.h\"\n#import \"UIImage+ForceDecode.h\"\n#import \"SDAssociatedObject.h\"\n#import \"UIImage+Metadata.h\"\n#import \"SDInternalMacros.h\"\n#import <Accelerate/Accelerate.h>\n\nstatic inline size_t SDByteAlign(size_t size, size_t alignment) {\n    return ((size + (alignment - 1)) / alignment) * alignment;\n}\n\nstatic const size_t kBytesPerPixel = 4;\nstatic const size_t kBitsPerComponent = 8;\n\nstatic const CGFloat kBytesPerMB = 1024.0f * 1024.0f;\n/*\n * Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set\n * Suggested value for iPad1 and iPhone 3GS: 60.\n * Suggested value for iPad2 and iPhone 4: 120.\n * Suggested value for iPhone 3G and iPod 2 and earlier devices: 30.\n */\n#if SD_MAC\nstatic CGFloat kDestImageLimitBytes = 90.f * kBytesPerMB;\n#elif SD_UIKIT\nstatic CGFloat kDestImageLimitBytes = 60.f * kBytesPerMB;\n#elif SD_WATCH\nstatic CGFloat kDestImageLimitBytes = 30.f * kBytesPerMB;\n#endif\n\nstatic const CGFloat kDestSeemOverlap = 2.0f;   // the numbers of pixels to overlap the seems where tiles meet.\n\n@implementation SDImageCoderHelper\n\n+ (UIImage *)animatedImageWithFrames:(NSArray<SDImageFrame *> *)frames {\n    NSUInteger frameCount = frames.count;\n    if (frameCount == 0) {\n        return nil;\n    }\n    \n    UIImage *animatedImage;\n    \n#if SD_UIKIT || SD_WATCH\n    NSUInteger durations[frameCount];\n    for (size_t i = 0; i < frameCount; i++) {\n        durations[i] = frames[i].duration * 1000;\n    }\n    NSUInteger const gcd = gcdArray(frameCount, durations);\n    __block NSUInteger totalDuration = 0;\n    NSMutableArray<UIImage *> *animatedImages = [NSMutableArray arrayWithCapacity:frameCount];\n    [frames enumerateObjectsUsingBlock:^(SDImageFrame * _Nonnull frame, NSUInteger idx, BOOL * _Nonnull stop) {\n        UIImage *image = frame.image;\n        NSUInteger duration = frame.duration * 1000;\n        totalDuration += duration;\n        NSUInteger repeatCount;\n        if (gcd) {\n            repeatCount = duration / gcd;\n        } else {\n            repeatCount = 1;\n        }\n        for (size_t i = 0; i < repeatCount; ++i) {\n            [animatedImages addObject:image];\n        }\n    }];\n    \n    animatedImage = [UIImage animatedImageWithImages:animatedImages duration:totalDuration / 1000.f];\n    \n#else\n    \n    NSMutableData *imageData = [NSMutableData data];\n    CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:SDImageFormatGIF];\n    // Create an image destination. GIF does not support EXIF image orientation\n    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL);\n    if (!imageDestination) {\n        // Handle failure.\n        return nil;\n    }\n    \n    for (size_t i = 0; i < frameCount; i++) {\n        @autoreleasepool {\n            SDImageFrame *frame = frames[i];\n            NSTimeInterval frameDuration = frame.duration;\n            CGImageRef frameImageRef = frame.image.CGImage;\n            NSDictionary *frameProperties = @{(__bridge NSString *)kCGImagePropertyGIFDictionary : @{(__bridge NSString *)kCGImagePropertyGIFDelayTime : @(frameDuration)}};\n            CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties);\n        }\n    }\n    // Finalize the destination.\n    if (CGImageDestinationFinalize(imageDestination) == NO) {\n        // Handle failure.\n        CFRelease(imageDestination);\n        return nil;\n    }\n    CFRelease(imageDestination);\n    CGFloat scale = MAX(frames.firstObject.image.scale, 1);\n    \n    SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:imageData];\n    NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);\n    imageRep.size = size;\n    animatedImage = [[NSImage alloc] initWithSize:size];\n    [animatedImage addRepresentation:imageRep];\n#endif\n    \n    return animatedImage;\n}\n\n+ (NSArray<SDImageFrame *> *)framesFromAnimatedImage:(UIImage *)animatedImage {\n    if (!animatedImage) {\n        return nil;\n    }\n    \n    NSMutableArray<SDImageFrame *> *frames = [NSMutableArray array];\n    NSUInteger frameCount = 0;\n    \n#if SD_UIKIT || SD_WATCH\n    NSArray<UIImage *> *animatedImages = animatedImage.images;\n    frameCount = animatedImages.count;\n    if (frameCount == 0) {\n        return nil;\n    }\n    \n    NSTimeInterval avgDuration = animatedImage.duration / frameCount;\n    if (avgDuration == 0) {\n        avgDuration = 0.1; // if it's a animated image but no duration, set it to default 100ms (this do not have that 10ms limit like GIF or WebP to allow custom coder provide the limit)\n    }\n    \n    __block NSUInteger index = 0;\n    __block NSUInteger repeatCount = 1;\n    __block UIImage *previousImage = animatedImages.firstObject;\n    [animatedImages enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {\n        // ignore first\n        if (idx == 0) {\n            return;\n        }\n        if ([image isEqual:previousImage]) {\n            repeatCount++;\n        } else {\n            SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount];\n            [frames addObject:frame];\n            repeatCount = 1;\n            index++;\n        }\n        previousImage = image;\n        // last one\n        if (idx == frameCount - 1) {\n            SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount];\n            [frames addObject:frame];\n        }\n    }];\n    \n#else\n    \n    NSRect imageRect = NSMakeRect(0, 0, animatedImage.size.width, animatedImage.size.height);\n    NSImageRep *imageRep = [animatedImage bestRepresentationForRect:imageRect context:nil hints:nil];\n    NSBitmapImageRep *bitmapImageRep;\n    if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {\n        bitmapImageRep = (NSBitmapImageRep *)imageRep;\n    }\n    if (!bitmapImageRep) {\n        return nil;\n    }\n    frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];\n    if (frameCount == 0) {\n        return nil;\n    }\n    CGFloat scale = animatedImage.scale;\n    \n    for (size_t i = 0; i < frameCount; i++) {\n        @autoreleasepool {\n            // NSBitmapImageRep need to manually change frame. \"Good taste\" API\n            [bitmapImageRep setProperty:NSImageCurrentFrame withValue:@(i)];\n            NSTimeInterval frameDuration = [[bitmapImageRep valueForProperty:NSImageCurrentFrameDuration] doubleValue];\n            NSImage *frameImage = [[NSImage alloc] initWithCGImage:bitmapImageRep.CGImage scale:scale orientation:kCGImagePropertyOrientationUp];\n            SDImageFrame *frame = [SDImageFrame frameWithImage:frameImage duration:frameDuration];\n            [frames addObject:frame];\n        }\n    }\n#endif\n    \n    return frames;\n}\n\n+ (CGColorSpaceRef)colorSpaceGetDeviceRGB {\n#if SD_MAC\n    CGColorSpaceRef screenColorSpace = NSScreen.mainScreen.colorSpace.CGColorSpace;\n    if (screenColorSpace) {\n        return screenColorSpace;\n    }\n#endif\n    static CGColorSpaceRef colorSpace;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n#if SD_UIKIT\n        if (@available(iOS 9.0, tvOS 9.0, *)) {\n            colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);\n        } else {\n            colorSpace = CGColorSpaceCreateDeviceRGB();\n        }\n#else\n        colorSpace = CGColorSpaceCreateDeviceRGB();\n#endif\n    });\n    return colorSpace;\n}\n\n+ (BOOL)CGImageContainsAlpha:(CGImageRef)cgImage {\n    if (!cgImage) {\n        return NO;\n    }\n    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(cgImage);\n    BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone ||\n                      alphaInfo == kCGImageAlphaNoneSkipFirst ||\n                      alphaInfo == kCGImageAlphaNoneSkipLast);\n    return hasAlpha;\n}\n\n+ (CGImageRef)CGImageCreateDecoded:(CGImageRef)cgImage {\n    return [self CGImageCreateDecoded:cgImage orientation:kCGImagePropertyOrientationUp];\n}\n\n+ (CGImageRef)CGImageCreateDecoded:(CGImageRef)cgImage orientation:(CGImagePropertyOrientation)orientation {\n    if (!cgImage) {\n        return NULL;\n    }\n    size_t width = CGImageGetWidth(cgImage);\n    size_t height = CGImageGetHeight(cgImage);\n    if (width == 0 || height == 0) return NULL;\n    size_t newWidth;\n    size_t newHeight;\n    switch (orientation) {\n        case kCGImagePropertyOrientationLeft:\n        case kCGImagePropertyOrientationLeftMirrored:\n        case kCGImagePropertyOrientationRight:\n        case kCGImagePropertyOrientationRightMirrored: {\n            // These orientation should swap width & height\n            newWidth = height;\n            newHeight = width;\n        }\n            break;\n        default: {\n            newWidth = width;\n            newHeight = height;\n        }\n            break;\n    }\n    \n    BOOL hasAlpha = [self CGImageContainsAlpha:cgImage];\n    // iOS prefer BGRA8888 (premultiplied) or BGRX8888 bitmapInfo for screen rendering, which is same as `UIGraphicsBeginImageContext()` or `- [CALayer drawInContext:]`\n    // Though you can use any supported bitmapInfo (see: https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html#//apple_ref/doc/uid/TP30001066-CH203-BCIBHHBB ) and let Core Graphics reorder it when you call `CGContextDrawImage`\n    // But since our build-in coders use this bitmapInfo, this can have a little performance benefit\n    CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;\n    bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;\n    CGContextRef context = CGBitmapContextCreate(NULL, newWidth, newHeight, 8, 0, [self colorSpaceGetDeviceRGB], bitmapInfo);\n    if (!context) {\n        return NULL;\n    }\n    \n    // Apply transform\n    CGAffineTransform transform = SDCGContextTransformFromOrientation(orientation, CGSizeMake(newWidth, newHeight));\n    CGContextConcatCTM(context, transform);\n    CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage); // The rect is bounding box of CGImage, don't swap width & height\n    CGImageRef newImageRef = CGBitmapContextCreateImage(context);\n    CGContextRelease(context);\n    \n    return newImageRef;\n}\n\n+ (CGImageRef)CGImageCreateScaled:(CGImageRef)cgImage size:(CGSize)size {\n    if (!cgImage) {\n        return NULL;\n    }\n    size_t width = CGImageGetWidth(cgImage);\n    size_t height = CGImageGetHeight(cgImage);\n    if (width == size.width && height == size.height) {\n        CGImageRetain(cgImage);\n        return cgImage;\n    }\n    \n    __block vImage_Buffer input_buffer = {}, output_buffer = {};\n    @onExit {\n        if (input_buffer.data) free(input_buffer.data);\n        if (output_buffer.data) free(output_buffer.data);\n    };\n    BOOL hasAlpha = [self CGImageContainsAlpha:cgImage];\n    // iOS display alpha info (BGRA8888/BGRX8888)\n    CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;\n    bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;\n    vImage_CGImageFormat format = (vImage_CGImageFormat) {\n        .bitsPerComponent = 8,\n        .bitsPerPixel = 32,\n        .colorSpace = NULL,\n        .bitmapInfo = bitmapInfo,\n        .version = 0,\n        .decode = NULL,\n        .renderingIntent = kCGRenderingIntentDefault,\n    };\n    \n    vImage_Error a_ret = vImageBuffer_InitWithCGImage(&input_buffer, &format, NULL, cgImage, kvImageNoFlags);\n    if (a_ret != kvImageNoError) return NULL;\n    output_buffer.width = MAX(size.width, 0);\n    output_buffer.height = MAX(size.height, 0);\n    output_buffer.rowBytes = SDByteAlign(output_buffer.width * 4, 64);\n    output_buffer.data = malloc(output_buffer.rowBytes * output_buffer.height);\n    if (!output_buffer.data) return NULL;\n    \n    vImage_Error ret = vImageScale_ARGB8888(&input_buffer, &output_buffer, NULL, kvImageHighQualityResampling);\n    if (ret != kvImageNoError) return NULL;\n    \n    CGImageRef outputImage = vImageCreateCGImageFromBuffer(&output_buffer, &format, NULL, NULL, kvImageNoFlags, &ret);\n    if (ret != kvImageNoError) {\n        CGImageRelease(outputImage);\n        return NULL;\n    }\n    \n    return outputImage;\n}\n\n+ (UIImage *)decodedImageWithImage:(UIImage *)image {\n    if (![self shouldDecodeImage:image]) {\n        return image;\n    }\n    \n    CGImageRef imageRef = [self CGImageCreateDecoded:image.CGImage];\n    if (!imageRef) {\n        return image;\n    }\n#if SD_MAC\n    UIImage *decodedImage = [[UIImage alloc] initWithCGImage:imageRef scale:image.scale orientation:kCGImagePropertyOrientationUp];\n#else\n    UIImage *decodedImage = [[UIImage alloc] initWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];\n#endif\n    CGImageRelease(imageRef);\n    SDImageCopyAssociatedObject(image, decodedImage);\n    decodedImage.sd_isDecoded = YES;\n    return decodedImage;\n}\n\n+ (UIImage *)decodedAndScaledDownImageWithImage:(UIImage *)image limitBytes:(NSUInteger)bytes {\n    if (![self shouldDecodeImage:image]) {\n        return image;\n    }\n    \n    if (![self shouldScaleDownImage:image limitBytes:bytes]) {\n        return [self decodedImageWithImage:image];\n    }\n    \n    CGFloat destTotalPixels;\n    CGFloat tileTotalPixels;\n    if (bytes == 0) {\n        bytes = kDestImageLimitBytes;\n    }\n    destTotalPixels = bytes / kBytesPerPixel;\n    tileTotalPixels = destTotalPixels / 3;\n    CGContextRef destContext;\n    \n    // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.\n    // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];\n    @autoreleasepool {\n        CGImageRef sourceImageRef = image.CGImage;\n        \n        CGSize sourceResolution = CGSizeZero;\n        sourceResolution.width = CGImageGetWidth(sourceImageRef);\n        sourceResolution.height = CGImageGetHeight(sourceImageRef);\n        CGFloat sourceTotalPixels = sourceResolution.width * sourceResolution.height;\n        // Determine the scale ratio to apply to the input image\n        // that results in an output image of the defined size.\n        // see kDestImageSizeMB, and how it relates to destTotalPixels.\n        CGFloat imageScale = sqrt(destTotalPixels / sourceTotalPixels);\n        CGSize destResolution = CGSizeZero;\n        destResolution.width = MAX(1, (int)(sourceResolution.width * imageScale));\n        destResolution.height = MAX(1, (int)(sourceResolution.height * imageScale));\n        \n        // device color space\n        CGColorSpaceRef colorspaceRef = [self colorSpaceGetDeviceRGB];\n        BOOL hasAlpha = [self CGImageContainsAlpha:sourceImageRef];\n        // iOS display alpha info (BGRA8888/BGRX8888)\n        CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;\n        bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;\n        \n        // kCGImageAlphaNone is not supported in CGBitmapContextCreate.\n        // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipFirst\n        // to create bitmap graphics contexts without alpha info.\n        destContext = CGBitmapContextCreate(NULL,\n                                            destResolution.width,\n                                            destResolution.height,\n                                            kBitsPerComponent,\n                                            0,\n                                            colorspaceRef,\n                                            bitmapInfo);\n        \n        if (destContext == NULL) {\n            return image;\n        }\n        CGContextSetInterpolationQuality(destContext, kCGInterpolationHigh);\n        \n        // Now define the size of the rectangle to be used for the\n        // incremental bits from the input image to the output image.\n        // we use a source tile width equal to the width of the source\n        // image due to the way that iOS retrieves image data from disk.\n        // iOS must decode an image from disk in full width 'bands', even\n        // if current graphics context is clipped to a subrect within that\n        // band. Therefore we fully utilize all of the pixel data that results\n        // from a decoding operation by anchoring our tile size to the full\n        // width of the input image.\n        CGRect sourceTile = CGRectZero;\n        sourceTile.size.width = sourceResolution.width;\n        // The source tile height is dynamic. Since we specified the size\n        // of the source tile in MB, see how many rows of pixels high it\n        // can be given the input image width.\n        sourceTile.size.height = MAX(1, (int)(tileTotalPixels / sourceTile.size.width));\n        sourceTile.origin.x = 0.0f;\n        // The output tile is the same proportions as the input tile, but\n        // scaled to image scale.\n        CGRect destTile;\n        destTile.size.width = destResolution.width;\n        destTile.size.height = sourceTile.size.height * imageScale;\n        destTile.origin.x = 0.0f;\n        // The source seem overlap is proportionate to the destination seem overlap.\n        // this is the amount of pixels to overlap each tile as we assemble the output image.\n        float sourceSeemOverlap = (int)((kDestSeemOverlap/destResolution.height)*sourceResolution.height);\n        CGImageRef sourceTileImageRef;\n        // calculate the number of read/write operations required to assemble the\n        // output image.\n        int iterations = (int)( sourceResolution.height / sourceTile.size.height );\n        // If tile height doesn't divide the image height evenly, add another iteration\n        // to account for the remaining pixels.\n        int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;\n        if(remainder) {\n            iterations++;\n        }\n        // Add seem overlaps to the tiles, but save the original tile height for y coordinate calculations.\n        float sourceTileHeightMinusOverlap = sourceTile.size.height;\n        sourceTile.size.height += sourceSeemOverlap;\n        destTile.size.height += kDestSeemOverlap;\n        for( int y = 0; y < iterations; ++y ) {\n            @autoreleasepool {\n                sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;\n                destTile.origin.y = destResolution.height - (( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + kDestSeemOverlap);\n                sourceTileImageRef = CGImageCreateWithImageInRect( sourceImageRef, sourceTile );\n                if( y == iterations - 1 && remainder ) {\n                    float dify = destTile.size.height;\n                    destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;\n                    dify -= destTile.size.height;\n                    destTile.origin.y += dify;\n                }\n                CGContextDrawImage( destContext, destTile, sourceTileImageRef );\n                CGImageRelease( sourceTileImageRef );\n            }\n        }\n        \n        CGImageRef destImageRef = CGBitmapContextCreateImage(destContext);\n        CGContextRelease(destContext);\n        if (destImageRef == NULL) {\n            return image;\n        }\n#if SD_MAC\n        UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:kCGImagePropertyOrientationUp];\n#else\n        UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:image.imageOrientation];\n#endif\n        CGImageRelease(destImageRef);\n        if (destImage == nil) {\n            return image;\n        }\n        SDImageCopyAssociatedObject(image, destImage);\n        destImage.sd_isDecoded = YES;\n        return destImage;\n    }\n}\n\n+ (NSUInteger)defaultScaleDownLimitBytes {\n    return kDestImageLimitBytes;\n}\n\n+ (void)setDefaultScaleDownLimitBytes:(NSUInteger)defaultScaleDownLimitBytes {\n    if (defaultScaleDownLimitBytes < kBytesPerPixel) {\n        return;\n    }\n    kDestImageLimitBytes = defaultScaleDownLimitBytes;\n}\n\n#if SD_UIKIT || SD_WATCH\n// Convert an EXIF image orientation to an iOS one.\n+ (UIImageOrientation)imageOrientationFromEXIFOrientation:(CGImagePropertyOrientation)exifOrientation {\n    UIImageOrientation imageOrientation = UIImageOrientationUp;\n    switch (exifOrientation) {\n        case kCGImagePropertyOrientationUp:\n            imageOrientation = UIImageOrientationUp;\n            break;\n        case kCGImagePropertyOrientationDown:\n            imageOrientation = UIImageOrientationDown;\n            break;\n        case kCGImagePropertyOrientationLeft:\n            imageOrientation = UIImageOrientationLeft;\n            break;\n        case kCGImagePropertyOrientationRight:\n            imageOrientation = UIImageOrientationRight;\n            break;\n        case kCGImagePropertyOrientationUpMirrored:\n            imageOrientation = UIImageOrientationUpMirrored;\n            break;\n        case kCGImagePropertyOrientationDownMirrored:\n            imageOrientation = UIImageOrientationDownMirrored;\n            break;\n        case kCGImagePropertyOrientationLeftMirrored:\n            imageOrientation = UIImageOrientationLeftMirrored;\n            break;\n        case kCGImagePropertyOrientationRightMirrored:\n            imageOrientation = UIImageOrientationRightMirrored;\n            break;\n        default:\n            break;\n    }\n    return imageOrientation;\n}\n\n// Convert an iOS orientation to an EXIF image orientation.\n+ (CGImagePropertyOrientation)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation {\n    CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp;\n    switch (imageOrientation) {\n        case UIImageOrientationUp:\n            exifOrientation = kCGImagePropertyOrientationUp;\n            break;\n        case UIImageOrientationDown:\n            exifOrientation = kCGImagePropertyOrientationDown;\n            break;\n        case UIImageOrientationLeft:\n            exifOrientation = kCGImagePropertyOrientationLeft;\n            break;\n        case UIImageOrientationRight:\n            exifOrientation = kCGImagePropertyOrientationRight;\n            break;\n        case UIImageOrientationUpMirrored:\n            exifOrientation = kCGImagePropertyOrientationUpMirrored;\n            break;\n        case UIImageOrientationDownMirrored:\n            exifOrientation = kCGImagePropertyOrientationDownMirrored;\n            break;\n        case UIImageOrientationLeftMirrored:\n            exifOrientation = kCGImagePropertyOrientationLeftMirrored;\n            break;\n        case UIImageOrientationRightMirrored:\n            exifOrientation = kCGImagePropertyOrientationRightMirrored;\n            break;\n        default:\n            break;\n    }\n    return exifOrientation;\n}\n#endif\n\n#pragma mark - Helper Function\n+ (BOOL)shouldDecodeImage:(nullable UIImage *)image {\n    // Prevent \"CGBitmapContextCreateImage: invalid context 0x0\" error\n    if (image == nil) {\n        return NO;\n    }\n    // Avoid extra decode\n    if (image.sd_isDecoded) {\n        return NO;\n    }\n    // do not decode animated images\n    if (image.sd_isAnimated) {\n        return NO;\n    }\n    // do not decode vector images\n    if (image.sd_isVector) {\n        return NO;\n    }\n    \n    return YES;\n}\n\n+ (BOOL)shouldScaleDownImage:(nonnull UIImage *)image limitBytes:(NSUInteger)bytes {\n    BOOL shouldScaleDown = YES;\n    \n    CGImageRef sourceImageRef = image.CGImage;\n    CGSize sourceResolution = CGSizeZero;\n    sourceResolution.width = CGImageGetWidth(sourceImageRef);\n    sourceResolution.height = CGImageGetHeight(sourceImageRef);\n    float sourceTotalPixels = sourceResolution.width * sourceResolution.height;\n    if (sourceTotalPixels <= 0) {\n        return NO;\n    }\n    CGFloat destTotalPixels;\n    if (bytes == 0) {\n        bytes = [self defaultScaleDownLimitBytes];\n    }\n    bytes = MAX(bytes, kBytesPerPixel);\n    destTotalPixels = bytes / kBytesPerPixel;\n    float imageScale = destTotalPixels / sourceTotalPixels;\n    if (imageScale < 1) {\n        shouldScaleDown = YES;\n    } else {\n        shouldScaleDown = NO;\n    }\n    \n    return shouldScaleDown;\n}\n\nstatic inline CGAffineTransform SDCGContextTransformFromOrientation(CGImagePropertyOrientation orientation, CGSize size) {\n    // Inspiration from @libfeihu\n    // We need to calculate the proper transformation to make the image upright.\n    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.\n    CGAffineTransform transform = CGAffineTransformIdentity;\n    \n    switch (orientation) {\n        case kCGImagePropertyOrientationDown:\n        case kCGImagePropertyOrientationDownMirrored:\n            transform = CGAffineTransformTranslate(transform, size.width, size.height);\n            transform = CGAffineTransformRotate(transform, M_PI);\n            break;\n            \n        case kCGImagePropertyOrientationLeft:\n        case kCGImagePropertyOrientationLeftMirrored:\n            transform = CGAffineTransformTranslate(transform, size.width, 0);\n            transform = CGAffineTransformRotate(transform, M_PI_2);\n            break;\n            \n        case kCGImagePropertyOrientationRight:\n        case kCGImagePropertyOrientationRightMirrored:\n            transform = CGAffineTransformTranslate(transform, 0, size.height);\n            transform = CGAffineTransformRotate(transform, -M_PI_2);\n            break;\n        case kCGImagePropertyOrientationUp:\n        case kCGImagePropertyOrientationUpMirrored:\n            break;\n    }\n    \n    switch (orientation) {\n        case kCGImagePropertyOrientationUpMirrored:\n        case kCGImagePropertyOrientationDownMirrored:\n            transform = CGAffineTransformTranslate(transform, size.width, 0);\n            transform = CGAffineTransformScale(transform, -1, 1);\n            break;\n            \n        case kCGImagePropertyOrientationLeftMirrored:\n        case kCGImagePropertyOrientationRightMirrored:\n            transform = CGAffineTransformTranslate(transform, size.height, 0);\n            transform = CGAffineTransformScale(transform, -1, 1);\n            break;\n        case kCGImagePropertyOrientationUp:\n        case kCGImagePropertyOrientationDown:\n        case kCGImagePropertyOrientationLeft:\n        case kCGImagePropertyOrientationRight:\n            break;\n    }\n    \n    return transform;\n}\n\n#if SD_UIKIT || SD_WATCH\nstatic NSUInteger gcd(NSUInteger a, NSUInteger b) {\n    NSUInteger c;\n    while (a != 0) {\n        c = a;\n        a = b % a;\n        b = c;\n    }\n    return b;\n}\n\nstatic NSUInteger gcdArray(size_t const count, NSUInteger const * const values) {\n    if (count == 0) {\n        return 0;\n    }\n    NSUInteger result = values[0];\n    for (size_t i = 1; i < count; ++i) {\n        result = gcd(values[i], result);\n    }\n    return result;\n}\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageCoder.h\"\n\n/**\n Global object holding the array of coders, so that we avoid passing them from object to object.\n Uses a priority queue behind scenes, which means the latest added coders have the highest priority.\n This is done so when encoding/decoding something, we go through the list and ask each coder if they can handle the current data.\n That way, users can add their custom coders while preserving our existing prebuilt ones\n \n Note: the `coders` getter will return the coders in their reversed order\n Example:\n - by default we internally set coders = `IOCoder`, `GIFCoder`, `APNGCoder`\n - calling `coders` will return `@[IOCoder, GIFCoder, APNGCoder]`\n - call `[addCoder:[MyCrazyCoder new]]`\n - calling `coders` now returns `@[IOCoder, GIFCoder, APNGCoder, MyCrazyCoder]`\n \n Coders\n ------\n A coder must conform to the `SDImageCoder` protocol or even to `SDProgressiveImageCoder` if it supports progressive decoding\n Conformance is important because that way, they will implement `canDecodeFromData` or `canEncodeToFormat`\n Those methods are called on each coder in the array (using the priority order) until one of them returns YES.\n That means that coder can decode that data / encode to that format\n */\n@interface SDImageCodersManager : NSObject <SDImageCoder>\n\n/**\n Returns the global shared coders manager instance.\n */\n@property (nonatomic, class, readonly, nonnull) SDImageCodersManager *sharedManager;\n\n/**\n All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority\n */\n@property (nonatomic, copy, nullable) NSArray<id<SDImageCoder>> *coders;\n\n/**\n Add a new coder to the end of coders array. Which has the highest priority.\n\n @param coder coder\n */\n- (void)addCoder:(nonnull id<SDImageCoder>)coder;\n\n/**\n Remove a coder in the coders array.\n\n @param coder coder\n */\n- (void)removeCoder:(nonnull id<SDImageCoder>)coder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCodersManager.h\"\n#import \"SDImageIOCoder.h\"\n#import \"SDImageGIFCoder.h\"\n#import \"SDImageAPNGCoder.h\"\n#import \"SDImageHEICCoder.h\"\n#import \"SDInternalMacros.h\"\n\n@interface SDImageCodersManager ()\n\n@property (nonatomic, strong, nonnull) NSMutableArray<id<SDImageCoder>> *imageCoders;\n\n@end\n\n@implementation SDImageCodersManager {\n    SD_LOCK_DECLARE(_codersLock);\n}\n\n+ (nonnull instancetype)sharedManager {\n    static dispatch_once_t once;\n    static id instance;\n    dispatch_once(&once, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n- (instancetype)init {\n    if (self = [super init]) {\n        // initialize with default coders\n        _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];\n        SD_LOCK_INIT(_codersLock);\n    }\n    return self;\n}\n\n- (NSArray<id<SDImageCoder>> *)coders {\n    SD_LOCK(_codersLock);\n    NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];\n    SD_UNLOCK(_codersLock);\n    return coders;\n}\n\n- (void)setCoders:(NSArray<id<SDImageCoder>> *)coders {\n    SD_LOCK(_codersLock);\n    [_imageCoders removeAllObjects];\n    if (coders.count) {\n        [_imageCoders addObjectsFromArray:coders];\n    }\n    SD_UNLOCK(_codersLock);\n}\n\n#pragma mark - Coder IO operations\n\n- (void)addCoder:(nonnull id<SDImageCoder>)coder {\n    if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {\n        return;\n    }\n    SD_LOCK(_codersLock);\n    [_imageCoders addObject:coder];\n    SD_UNLOCK(_codersLock);\n}\n\n- (void)removeCoder:(nonnull id<SDImageCoder>)coder {\n    if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {\n        return;\n    }\n    SD_LOCK(_codersLock);\n    [_imageCoders removeObject:coder];\n    SD_UNLOCK(_codersLock);\n}\n\n#pragma mark - SDImageCoder\n- (BOOL)canDecodeFromData:(NSData *)data {\n    NSArray<id<SDImageCoder>> *coders = self.coders;\n    for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {\n        if ([coder canDecodeFromData:data]) {\n            return YES;\n        }\n    }\n    return NO;\n}\n\n- (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    NSArray<id<SDImageCoder>> *coders = self.coders;\n    for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {\n        if ([coder canEncodeToFormat:format]) {\n            return YES;\n        }\n    }\n    return NO;\n}\n\n- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {\n    if (!data) {\n        return nil;\n    }\n    UIImage *image;\n    NSArray<id<SDImageCoder>> *coders = self.coders;\n    for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {\n        if ([coder canDecodeFromData:data]) {\n            image = [coder decodedImageWithData:data options:options];\n            break;\n        }\n    }\n    \n    return image;\n}\n\n- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options {\n    if (!image) {\n        return nil;\n    }\n    NSArray<id<SDImageCoder>> *coders = self.coders;\n    for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {\n        if ([coder canEncodeToFormat:format]) {\n            return [coder encodedDataWithImage:image format:format options:options];\n        }\n    }\n    return nil;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageFrame.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/**\n This class is used for creating animated images via `animatedImageWithFrames` in `SDImageCoderHelper`.\n @note If you need to specify animated images loop count, use `sd_imageLoopCount` property in `UIImage+Metadata.h`.\n */\n@interface SDImageFrame : NSObject\n\n/**\n The image of current frame. You should not set an animated image.\n */\n@property (nonatomic, strong, readonly, nonnull) UIImage *image;\n/**\n The duration of current frame to be displayed. The number is seconds but not milliseconds. You should not set this to zero.\n */\n@property (nonatomic, readonly, assign) NSTimeInterval duration;\n\n/**\n Create a frame instance with specify image and duration\n\n @param image current frame's image\n @param duration current frame's duration\n @return frame instance\n */\n+ (instancetype _Nonnull)frameWithImage:(UIImage * _Nonnull)image duration:(NSTimeInterval)duration;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageFrame.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageFrame.h\"\n\n@interface SDImageFrame ()\n\n@property (nonatomic, strong, readwrite, nonnull) UIImage *image;\n@property (nonatomic, readwrite, assign) NSTimeInterval duration;\n\n@end\n\n@implementation SDImageFrame\n\n+ (instancetype)frameWithImage:(UIImage *)image duration:(NSTimeInterval)duration {\n    SDImageFrame *frame = [[SDImageFrame alloc] init];\n    frame.image = image;\n    frame.duration = duration;\n    \n    return frame;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageIOAnimatedCoder.h\"\n\n/**\n Built in coder using ImageIO that supports animated GIF encoding/decoding\n @note `SDImageIOCoder` supports GIF but only as static (will use the 1st frame).\n @note Use `SDImageGIFCoder` for fully animated GIFs. For `UIImageView`, it will produce animated `UIImage`(`NSImage` on macOS) for rendering. For `SDAnimatedImageView`, it will use `SDAnimatedImage` for rendering.\n @note The recommended approach for animated GIFs is using `SDAnimatedImage` with `SDAnimatedImageView`. It's more performant than `UIImageView` for GIF displaying(especially on memory usage)\n */\n@interface SDImageGIFCoder : SDImageIOAnimatedCoder <SDProgressiveImageCoder, SDAnimatedImageCoder>\n\n@property (nonatomic, class, readonly, nonnull) SDImageGIFCoder *sharedCoder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageGIFCoder.h\"\n#if SD_MAC\n#import <CoreServices/CoreServices.h>\n#else\n#import <MobileCoreServices/MobileCoreServices.h>\n#endif\n\n@implementation SDImageGIFCoder\n\n+ (instancetype)sharedCoder {\n    static SDImageGIFCoder *coder;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        coder = [[SDImageGIFCoder alloc] init];\n    });\n    return coder;\n}\n\n#pragma mark - Subclass Override\n\n+ (SDImageFormat)imageFormat {\n    return SDImageFormatGIF;\n}\n\n+ (NSString *)imageUTType {\n    return (__bridge NSString *)kUTTypeGIF;\n}\n\n+ (NSString *)dictionaryProperty {\n    return (__bridge NSString *)kCGImagePropertyGIFDictionary;\n}\n\n+ (NSString *)unclampedDelayTimeProperty {\n    return (__bridge NSString *)kCGImagePropertyGIFUnclampedDelayTime;\n}\n\n+ (NSString *)delayTimeProperty {\n    return (__bridge NSString *)kCGImagePropertyGIFDelayTime;\n}\n\n+ (NSString *)loopCountProperty {\n    return (__bridge NSString *)kCGImagePropertyGIFLoopCount;\n}\n\n+ (NSUInteger)defaultLoopCount {\n    return 1;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import <CoreGraphics/CoreGraphics.h>\n\n/**\n These following graphics context method are provided to easily write cross-platform(AppKit/UIKit) code.\n For UIKit, these methods just call the same method in `UIGraphics.h`. See the documentation for usage.\n For AppKit, these methods use `NSGraphicsContext` to create image context and match the behavior like UIKit.\n @note If you don't care bitmap format (ARGB8888) and just draw image, use `SDGraphicsImageRenderer` instead. It's more performant on RAM usage.`\n */\n\n/// Returns the current graphics context.\nFOUNDATION_EXPORT CGContextRef __nullable SDGraphicsGetCurrentContext(void) CF_RETURNS_NOT_RETAINED;\n/// Creates a bitmap-based graphics context and makes it the current context.\nFOUNDATION_EXPORT void SDGraphicsBeginImageContext(CGSize size);\n/// Creates a bitmap-based graphics context with the specified options.\nFOUNDATION_EXPORT void SDGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);\n/// Removes the current bitmap-based graphics context from the top of the stack.\nFOUNDATION_EXPORT void SDGraphicsEndImageContext(void);\n/// Returns an image based on the contents of the current bitmap-based graphics context.\nFOUNDATION_EXPORT UIImage * __nullable SDGraphicsGetImageFromCurrentImageContext(void);\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageGraphics.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"objc/runtime.h\"\n\n#if SD_MAC\nstatic void *kNSGraphicsContextScaleFactorKey;\n\nstatic CGContextRef SDCGContextCreateBitmapContext(CGSize size, BOOL opaque, CGFloat scale) {\n    if (scale == 0) {\n        // Match `UIGraphicsBeginImageContextWithOptions`, reset to the scale factor of the device’s main screen if scale is 0.\n        scale = [NSScreen mainScreen].backingScaleFactor;\n    }\n    size_t width = ceil(size.width * scale);\n    size_t height = ceil(size.height * scale);\n    if (width < 1 || height < 1) return NULL;\n    \n    //pre-multiplied BGRA for non-opaque, BGRX for opaque, 8-bits per component, as Apple's doc\n    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();\n    CGImageAlphaInfo alphaInfo = kCGBitmapByteOrder32Host | (opaque ? kCGImageAlphaNoneSkipFirst : kCGImageAlphaPremultipliedFirst);\n    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, space, kCGBitmapByteOrderDefault | alphaInfo);\n    CGColorSpaceRelease(space);\n    if (!context) {\n        return NULL;\n    }\n    CGContextScaleCTM(context, scale, scale);\n    \n    return context;\n}\n#endif\n\nCGContextRef SDGraphicsGetCurrentContext(void) {\n#if SD_UIKIT || SD_WATCH\n    return UIGraphicsGetCurrentContext();\n#else\n    return NSGraphicsContext.currentContext.CGContext;\n#endif\n}\n\nvoid SDGraphicsBeginImageContext(CGSize size) {\n#if SD_UIKIT || SD_WATCH\n    UIGraphicsBeginImageContext(size);\n#else\n    SDGraphicsBeginImageContextWithOptions(size, NO, 1.0);\n#endif\n}\n\nvoid SDGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) {\n#if SD_UIKIT || SD_WATCH\n    UIGraphicsBeginImageContextWithOptions(size, opaque, scale);\n#else\n    CGContextRef context = SDCGContextCreateBitmapContext(size, opaque, scale);\n    if (!context) {\n        return;\n    }\n    NSGraphicsContext *graphicsContext = [NSGraphicsContext graphicsContextWithCGContext:context flipped:NO];\n    objc_setAssociatedObject(graphicsContext, &kNSGraphicsContextScaleFactorKey, @(scale), OBJC_ASSOCIATION_RETAIN);\n    CGContextRelease(context);\n    [NSGraphicsContext saveGraphicsState];\n    NSGraphicsContext.currentContext = graphicsContext;\n#endif\n}\n\nvoid SDGraphicsEndImageContext(void) {\n#if SD_UIKIT || SD_WATCH\n    UIGraphicsEndImageContext();\n#else\n    [NSGraphicsContext restoreGraphicsState];\n#endif\n}\n\nUIImage * SDGraphicsGetImageFromCurrentImageContext(void) {\n#if SD_UIKIT || SD_WATCH\n    return UIGraphicsGetImageFromCurrentImageContext();\n#else\n    NSGraphicsContext *context = NSGraphicsContext.currentContext;\n    CGContextRef contextRef = context.CGContext;\n    if (!contextRef) {\n        return nil;\n    }\n    CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);\n    if (!imageRef) {\n        return nil;\n    }\n    CGFloat scale = 0;\n    NSNumber *scaleFactor = objc_getAssociatedObject(context, &kNSGraphicsContextScaleFactorKey);\n    if ([scaleFactor isKindOfClass:[NSNumber class]]) {\n        scale = scaleFactor.doubleValue;\n    }\n    if (!scale) {\n        // reset to the scale factor of the device’s main screen if scale is 0.\n        scale = [NSScreen mainScreen].backingScaleFactor;\n    }\n    NSImage *image = [[NSImage alloc] initWithCGImage:imageRef scale:scale orientation:kCGImagePropertyOrientationUp];\n    CGImageRelease(imageRef);\n    return image;\n#endif\n}\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDImageIOAnimatedCoder.h\"\n\n/**\n This coder is used for HEIC (HEIF with HEVC container codec) image format.\n Image/IO provide the static HEIC (.heic) support in iOS 11/macOS 10.13/tvOS 11/watchOS 4+.\n Image/IO provide the animated HEIC (.heics) support in iOS 13/macOS 10.15/tvOS 13/watchOS 6+.\n See https://nokiatech.github.io/heif/technical.html for the standard.\n @note This coder is not in the default coder list for now, since HEIC animated image is really rare, and Apple's implementation still contains performance issues. You can enable if you need this.\n @note If you need to support lower firmware version for HEIF, you can have a try at https://github.com/SDWebImage/SDWebImageHEIFCoder\n */\nAPI_AVAILABLE(ios(13.0), tvos(13.0), macos(10.15), watchos(6.0))\n@interface SDImageHEICCoder : SDImageIOAnimatedCoder <SDProgressiveImageCoder, SDAnimatedImageCoder>\n\n@property (nonatomic, class, readonly, nonnull) SDImageHEICCoder *sharedCoder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDImageHEICCoder.h\"\n#import \"SDImageIOAnimatedCoderInternal.h\"\n\n// These constants are available from iOS 13+ and Xcode 11. This raw value is used for toolchain and firmware compatibility\nstatic NSString * kSDCGImagePropertyHEICSDictionary = @\"{HEICS}\";\nstatic NSString * kSDCGImagePropertyHEICSLoopCount = @\"LoopCount\";\nstatic NSString * kSDCGImagePropertyHEICSDelayTime = @\"DelayTime\";\nstatic NSString * kSDCGImagePropertyHEICSUnclampedDelayTime = @\"UnclampedDelayTime\";\n\n@implementation SDImageHEICCoder\n\n+ (void)initialize {\n    if (@available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)) {\n        // Use SDK instead of raw value\n        kSDCGImagePropertyHEICSDictionary = (__bridge NSString *)kCGImagePropertyHEICSDictionary;\n        kSDCGImagePropertyHEICSLoopCount = (__bridge NSString *)kCGImagePropertyHEICSLoopCount;\n        kSDCGImagePropertyHEICSDelayTime = (__bridge NSString *)kCGImagePropertyHEICSDelayTime;\n        kSDCGImagePropertyHEICSUnclampedDelayTime = (__bridge NSString *)kCGImagePropertyHEICSUnclampedDelayTime;\n    }\n}\n\n+ (instancetype)sharedCoder {\n    static SDImageHEICCoder *coder;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        coder = [[SDImageHEICCoder alloc] init];\n    });\n    return coder;\n}\n\n#pragma mark - SDImageCoder\n\n- (BOOL)canDecodeFromData:(nullable NSData *)data {\n    switch ([NSData sd_imageFormatForImageData:data]) {\n        case SDImageFormatHEIC:\n            // Check HEIC decoding compatibility\n            return [self.class canDecodeFromFormat:SDImageFormatHEIC];\n        case SDImageFormatHEIF:\n            // Check HEIF decoding compatibility\n            return [self.class canDecodeFromFormat:SDImageFormatHEIF];\n        default:\n            return NO;\n    }\n}\n\n- (BOOL)canIncrementalDecodeFromData:(NSData *)data {\n    return [self canDecodeFromData:data];\n}\n\n- (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    switch (format) {\n        case SDImageFormatHEIC:\n            // Check HEIC encoding compatibility\n            return [self.class canEncodeToFormat:SDImageFormatHEIC];\n        case SDImageFormatHEIF:\n            // Check HEIF encoding compatibility\n            return [self.class canEncodeToFormat:SDImageFormatHEIF];\n        default:\n            return NO;\n    }\n}\n\n#pragma mark - Subclass Override\n\n+ (SDImageFormat)imageFormat {\n    return SDImageFormatHEIC;\n}\n\n+ (NSString *)imageUTType {\n    return (__bridge NSString *)kSDUTTypeHEIC;\n}\n\n+ (NSString *)dictionaryProperty {\n    return kSDCGImagePropertyHEICSDictionary;\n}\n\n+ (NSString *)unclampedDelayTimeProperty {\n    return kSDCGImagePropertyHEICSUnclampedDelayTime;\n}\n\n+ (NSString *)delayTimeProperty {\n    return kSDCGImagePropertyHEICSDelayTime;\n}\n\n+ (NSString *)loopCountProperty {\n    return kSDCGImagePropertyHEICSLoopCount;\n}\n\n+ (NSUInteger)defaultLoopCount {\n    return 0;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import <ImageIO/ImageIO.h>\n#import \"SDImageCoder.h\"\n\n/**\n This is the abstract class for all animated coder, which use the Image/IO API. You can not use this directly as real coders. A exception will be raised if you use this class.\n All of the properties need the subclass to implement and works as expected.\n For Image/IO, See Apple's documentation: https://developer.apple.com/documentation/imageio\n */\n@interface SDImageIOAnimatedCoder : NSObject <SDProgressiveImageCoder, SDAnimatedImageCoder>\n\n#pragma mark - Subclass Override\n/**\n The supported animated image format. Such as `SDImageFormatGIF`.\n @note Subclass override.\n */\n@property (class, readonly) SDImageFormat imageFormat;\n/**\n The supported image format UTI Type. Such as `kUTTypeGIF`.\n This can be used for cases when we can not detect `SDImageFormat. Such as progressive decoding's hint format `kCGImageSourceTypeIdentifierHint`.\n @note Subclass override.\n */\n@property (class, readonly, nonnull) NSString *imageUTType;\n/**\n The image container property key used in Image/IO API. Such as `kCGImagePropertyGIFDictionary`.\n @note Subclass override.\n */\n@property (class, readonly, nonnull) NSString *dictionaryProperty;\n/**\n The image unclamped delay time property key used in Image/IO  API. Such as `kCGImagePropertyGIFUnclampedDelayTime`\n @note Subclass override.\n */\n@property (class, readonly, nonnull) NSString *unclampedDelayTimeProperty;\n/**\n The image delay time property key used in Image/IO API. Such as `kCGImagePropertyGIFDelayTime`.\n @note Subclass override.\n */\n@property (class, readonly, nonnull) NSString *delayTimeProperty;\n/**\n The image loop count property key used in Image/IO API. Such as `kCGImagePropertyGIFLoopCount`.\n @note Subclass override.\n */\n@property (class, readonly, nonnull) NSString *loopCountProperty;\n/**\n The default loop count when there are no any loop count information inside image container metadata.\n For example, for GIF format, the standard use 1 (play once). For APNG format, the standard use 0 (infinity loop).\n @note Subclass override.\n */\n@property (class, readonly) NSUInteger defaultLoopCount;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDImageIOAnimatedCoder.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"UIImage+Metadata.h\"\n#import \"NSData+ImageContentType.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDAnimatedImageRep.h\"\n#import \"UIImage+ForceDecode.h\"\n\n// Specify DPI for vector format in CGImageSource, like PDF\nstatic NSString * kSDCGImageSourceRasterizationDPI = @\"kCGImageSourceRasterizationDPI\";\n// Specify File Size for lossy format encoding, like JPEG\nstatic NSString * kSDCGImageDestinationRequestedFileSize = @\"kCGImageDestinationRequestedFileSize\";\n\n@interface SDImageIOCoderFrame : NSObject\n\n@property (nonatomic, assign) NSUInteger index; // Frame index (zero based)\n@property (nonatomic, assign) NSTimeInterval duration; // Frame duration in seconds\n\n@end\n\n@implementation SDImageIOCoderFrame\n@end\n\n@implementation SDImageIOAnimatedCoder {\n    size_t _width, _height;\n    CGImageSourceRef _imageSource;\n    NSData *_imageData;\n    CGFloat _scale;\n    NSUInteger _loopCount;\n    NSUInteger _frameCount;\n    NSArray<SDImageIOCoderFrame *> *_frames;\n    BOOL _finished;\n    BOOL _preserveAspectRatio;\n    CGSize _thumbnailSize;\n}\n\n- (void)dealloc\n{\n    if (_imageSource) {\n        CFRelease(_imageSource);\n        _imageSource = NULL;\n    }\n#if SD_UIKIT\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n}\n\n- (void)didReceiveMemoryWarning:(NSNotification *)notification\n{\n    if (_imageSource) {\n        for (size_t i = 0; i < _frameCount; i++) {\n            CGImageSourceRemoveCacheAtIndex(_imageSource, i);\n        }\n    }\n}\n\n#pragma mark - Subclass Override\n\n+ (SDImageFormat)imageFormat {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSString *)imageUTType {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSString *)dictionaryProperty {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSString *)unclampedDelayTimeProperty {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSString *)delayTimeProperty {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSString *)loopCountProperty {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n+ (NSUInteger)defaultLoopCount {\n    @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                   reason:[NSString stringWithFormat:@\"For `SDImageIOAnimatedCoder` subclass, you must override %@ method\", NSStringFromSelector(_cmd)]\n                                 userInfo:nil];\n}\n\n#pragma mark - Utils\n\n+ (BOOL)canDecodeFromFormat:(SDImageFormat)format {\n    static dispatch_once_t onceToken;\n    static NSSet *imageUTTypeSet;\n    dispatch_once(&onceToken, ^{\n        NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers();\n        imageUTTypeSet = [NSSet setWithArray:imageUTTypes];\n    });\n    CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format];\n    if ([imageUTTypeSet containsObject:(__bridge NSString *)(imageUTType)]) {\n        // Can decode from target format\n        return YES;\n    }\n    return NO;\n}\n\n+ (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    static dispatch_once_t onceToken;\n    static NSSet *imageUTTypeSet;\n    dispatch_once(&onceToken, ^{\n        NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageDestinationCopyTypeIdentifiers();\n        imageUTTypeSet = [NSSet setWithArray:imageUTTypes];\n    });\n    CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format];\n    if ([imageUTTypeSet containsObject:(__bridge NSString *)(imageUTType)]) {\n        // Can encode to target format\n        return YES;\n    }\n    return NO;\n}\n\n+ (NSUInteger)imageLoopCountWithSource:(CGImageSourceRef)source {\n    NSUInteger loopCount = self.defaultLoopCount;\n    NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, NULL);\n    NSDictionary *containerProperties = imageProperties[self.dictionaryProperty];\n    if (containerProperties) {\n        NSNumber *containerLoopCount = containerProperties[self.loopCountProperty];\n        if (containerLoopCount != nil) {\n            loopCount = containerLoopCount.unsignedIntegerValue;\n        }\n    }\n    return loopCount;\n}\n\n+ (NSTimeInterval)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {\n    NSDictionary *options = @{\n        (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES),\n        (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage\n    };\n    NSTimeInterval frameDuration = 0.1;\n    CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)options);\n    if (!cfFrameProperties) {\n        return frameDuration;\n    }\n    NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;\n    NSDictionary *containerProperties = frameProperties[self.dictionaryProperty];\n    \n    NSNumber *delayTimeUnclampedProp = containerProperties[self.unclampedDelayTimeProperty];\n    if (delayTimeUnclampedProp != nil) {\n        frameDuration = [delayTimeUnclampedProp doubleValue];\n    } else {\n        NSNumber *delayTimeProp = containerProperties[self.delayTimeProperty];\n        if (delayTimeProp != nil) {\n            frameDuration = [delayTimeProp doubleValue];\n        }\n    }\n    \n    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.\n    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify\n    // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>\n    // for more information.\n    \n    if (frameDuration < 0.011) {\n        frameDuration = 0.1;\n    }\n    \n    CFRelease(cfFrameProperties);\n    return frameDuration;\n}\n\n+ (UIImage *)createFrameAtIndex:(NSUInteger)index source:(CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(NSDictionary *)options {\n    // Some options need to pass to `CGImageSourceCopyPropertiesAtIndex` before `CGImageSourceCreateImageAtIndex`, or ImageIO will ignore them because they parse once :)\n    // Parse the image properties\n    NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)options);\n    NSUInteger pixelWidth = [properties[(__bridge NSString *)kCGImagePropertyPixelWidth] unsignedIntegerValue];\n    NSUInteger pixelHeight = [properties[(__bridge NSString *)kCGImagePropertyPixelHeight] unsignedIntegerValue];\n    CGImagePropertyOrientation exifOrientation = (CGImagePropertyOrientation)[properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue];\n    if (!exifOrientation) {\n        exifOrientation = kCGImagePropertyOrientationUp;\n    }\n    \n    CFStringRef uttype = CGImageSourceGetType(source);\n    // Check vector format\n    BOOL isVector = NO;\n    if ([NSData sd_imageFormatFromUTType:uttype] == SDImageFormatPDF) {\n        isVector = YES;\n    }\n\n    NSMutableDictionary *decodingOptions;\n    if (options) {\n        decodingOptions = [NSMutableDictionary dictionaryWithDictionary:options];\n    } else {\n        decodingOptions = [NSMutableDictionary dictionary];\n    }\n    CGImageRef imageRef;\n    BOOL createFullImage = thumbnailSize.width == 0 || thumbnailSize.height == 0 || pixelWidth == 0 || pixelHeight == 0 || (pixelWidth <= thumbnailSize.width && pixelHeight <= thumbnailSize.height);\n    if (createFullImage) {\n        if (isVector) {\n            if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {\n                // Provide the default pixel count for vector images, simply just use the screen size\n#if SD_WATCH\n                thumbnailSize = WKInterfaceDevice.currentDevice.screenBounds.size;\n#elif SD_UIKIT\n                thumbnailSize = UIScreen.mainScreen.bounds.size;\n#elif SD_MAC\n                thumbnailSize = NSScreen.mainScreen.frame.size;\n#endif\n            }\n            CGFloat maxPixelSize = MAX(thumbnailSize.width, thumbnailSize.height);\n            NSUInteger DPIPerPixel = 2;\n            NSUInteger rasterizationDPI = maxPixelSize * DPIPerPixel;\n            decodingOptions[kSDCGImageSourceRasterizationDPI] = @(rasterizationDPI);\n        }\n        imageRef = CGImageSourceCreateImageAtIndex(source, index, (__bridge CFDictionaryRef)[decodingOptions copy]);\n    } else {\n        decodingOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailWithTransform] = @(preserveAspectRatio);\n        CGFloat maxPixelSize;\n        if (preserveAspectRatio) {\n            CGFloat pixelRatio = pixelWidth / pixelHeight;\n            CGFloat thumbnailRatio = thumbnailSize.width / thumbnailSize.height;\n            if (pixelRatio > thumbnailRatio) {\n                maxPixelSize = thumbnailSize.width;\n            } else {\n                maxPixelSize = thumbnailSize.height;\n            }\n        } else {\n            maxPixelSize = MAX(thumbnailSize.width, thumbnailSize.height);\n        }\n        decodingOptions[(__bridge NSString *)kCGImageSourceThumbnailMaxPixelSize] = @(maxPixelSize);\n        decodingOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailFromImageAlways] = @(YES);\n        imageRef = CGImageSourceCreateThumbnailAtIndex(source, index, (__bridge CFDictionaryRef)[decodingOptions copy]);\n    }\n    if (!imageRef) {\n        return nil;\n    }\n    // Thumbnail image post-process\n    if (!createFullImage) {\n        if (preserveAspectRatio) {\n            // kCGImageSourceCreateThumbnailWithTransform will apply EXIF transform as well, we should not apply twice\n            exifOrientation = kCGImagePropertyOrientationUp;\n        } else {\n            // `CGImageSourceCreateThumbnailAtIndex` take only pixel dimension, if not `preserveAspectRatio`, we should manual scale to the target size\n            CGImageRef scaledImageRef = [SDImageCoderHelper CGImageCreateScaled:imageRef size:thumbnailSize];\n            CGImageRelease(imageRef);\n            imageRef = scaledImageRef;\n        }\n    }\n    \n#if SD_UIKIT || SD_WATCH\n    UIImageOrientation imageOrientation = [SDImageCoderHelper imageOrientationFromEXIFOrientation:exifOrientation];\n    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:imageOrientation];\n#else\n    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:exifOrientation];\n#endif\n    CGImageRelease(imageRef);\n    return image;\n}\n\n#pragma mark - Decode\n- (BOOL)canDecodeFromData:(nullable NSData *)data {\n    return ([NSData sd_imageFormatForImageData:data] == self.class.imageFormat);\n}\n\n- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {\n    if (!data) {\n        return nil;\n    }\n    CGFloat scale = 1;\n    NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n    if (scaleFactor != nil) {\n        scale = MAX([scaleFactor doubleValue], 1);\n    }\n    \n    CGSize thumbnailSize = CGSizeZero;\n    NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];\n    if (thumbnailSizeValue != nil) {\n#if SD_MAC\n        thumbnailSize = thumbnailSizeValue.sizeValue;\n#else\n        thumbnailSize = thumbnailSizeValue.CGSizeValue;\n#endif\n    }\n    \n    BOOL preserveAspectRatio = YES;\n    NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];\n    if (preserveAspectRatioValue != nil) {\n        preserveAspectRatio = preserveAspectRatioValue.boolValue;\n    }\n    \n#if SD_MAC\n    // If don't use thumbnail, prefers the built-in generation of frames (GIF/APNG)\n    // Which decode frames in time and reduce memory usage\n    if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {\n        SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];\n        NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);\n        imageRep.size = size;\n        NSImage *animatedImage = [[NSImage alloc] initWithSize:size];\n        [animatedImage addRepresentation:imageRep];\n        return animatedImage;\n    }\n#endif\n    \n    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);\n    if (!source) {\n        return nil;\n    }\n    size_t count = CGImageSourceGetCount(source);\n    UIImage *animatedImage;\n    \n    BOOL decodeFirstFrame = [options[SDImageCoderDecodeFirstFrameOnly] boolValue];\n    if (decodeFirstFrame || count <= 1) {\n        animatedImage = [self.class createFrameAtIndex:0 source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil];\n    } else {\n        NSMutableArray<SDImageFrame *> *frames = [NSMutableArray array];\n        \n        for (size_t i = 0; i < count; i++) {\n            UIImage *image = [self.class createFrameAtIndex:i source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil];\n            if (!image) {\n                continue;\n            }\n            \n            NSTimeInterval duration = [self.class frameDurationAtIndex:i source:source];\n            \n            SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration];\n            [frames addObject:frame];\n        }\n        \n        NSUInteger loopCount = [self.class imageLoopCountWithSource:source];\n        \n        animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames];\n        animatedImage.sd_imageLoopCount = loopCount;\n    }\n    animatedImage.sd_imageFormat = self.class.imageFormat;\n    CFRelease(source);\n    \n    return animatedImage;\n}\n\n#pragma mark - Progressive Decode\n\n- (BOOL)canIncrementalDecodeFromData:(NSData *)data {\n    return ([NSData sd_imageFormatForImageData:data] == self.class.imageFormat);\n}\n\n- (instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options {\n    self = [super init];\n    if (self) {\n        NSString *imageUTType = self.class.imageUTType;\n        _imageSource = CGImageSourceCreateIncremental((__bridge CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceTypeIdentifierHint : imageUTType});\n        CGFloat scale = 1;\n        NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n        if (scaleFactor != nil) {\n            scale = MAX([scaleFactor doubleValue], 1);\n        }\n        _scale = scale;\n        CGSize thumbnailSize = CGSizeZero;\n        NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];\n        if (thumbnailSizeValue != nil) {\n    #if SD_MAC\n            thumbnailSize = thumbnailSizeValue.sizeValue;\n    #else\n            thumbnailSize = thumbnailSizeValue.CGSizeValue;\n    #endif\n        }\n        _thumbnailSize = thumbnailSize;\n        BOOL preserveAspectRatio = YES;\n        NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];\n        if (preserveAspectRatioValue != nil) {\n            preserveAspectRatio = preserveAspectRatioValue.boolValue;\n        }\n        _preserveAspectRatio = preserveAspectRatio;\n#if SD_UIKIT\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    }\n    return self;\n}\n\n- (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished {\n    if (_finished) {\n        return;\n    }\n    _imageData = data;\n    _finished = finished;\n    \n    // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/\n    // Thanks to the author @Nyx0uf\n    \n    // Update the data source, we must pass ALL the data, not just the new bytes\n    CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)data, finished);\n    \n    if (_width + _height == 0) {\n        NSDictionary *options = @{\n            (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES),\n            (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage\n        };\n        CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, (__bridge CFDictionaryRef)options);\n        if (properties) {\n            CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);\n            if (val) CFNumberGetValue(val, kCFNumberLongType, &_height);\n            val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);\n            if (val) CFNumberGetValue(val, kCFNumberLongType, &_width);\n            CFRelease(properties);\n        }\n    }\n    \n    // For animated image progressive decoding because the frame count and duration may be changed.\n    [self scanAndCheckFramesValidWithImageSource:_imageSource];\n}\n\n- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options {\n    UIImage *image;\n    \n    if (_width + _height > 0) {\n        // Create the image\n        CGFloat scale = _scale;\n        NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n        if (scaleFactor != nil) {\n            scale = MAX([scaleFactor doubleValue], 1);\n        }\n        image = [self.class createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:nil];\n        if (image) {\n            image.sd_imageFormat = self.class.imageFormat;\n        }\n    }\n    \n    return image;\n}\n\n#pragma mark - Encode\n- (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    return (format == self.class.imageFormat);\n}\n\n- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options {\n    if (!image) {\n        return nil;\n    }\n    CGImageRef imageRef = image.CGImage;\n    if (!imageRef) {\n        // Earily return, supports CGImage only\n        return nil;\n    }\n    \n    if (format != self.class.imageFormat) {\n        return nil;\n    }\n    \n    NSMutableData *imageData = [NSMutableData data];\n    CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format];\n    NSArray<SDImageFrame *> *frames = [SDImageCoderHelper framesFromAnimatedImage:image];\n    \n    // Create an image destination. Animated Image does not support EXIF image orientation TODO\n    // The `CGImageDestinationCreateWithData` will log a warning when count is 0, use 1 instead.\n    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frames.count ?: 1, NULL);\n    if (!imageDestination) {\n        // Handle failure.\n        return nil;\n    }\n    NSMutableDictionary *properties = [NSMutableDictionary dictionary];\n    // Encoding Options\n    double compressionQuality = 1;\n    if (options[SDImageCoderEncodeCompressionQuality]) {\n        compressionQuality = [options[SDImageCoderEncodeCompressionQuality] doubleValue];\n    }\n    properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = @(compressionQuality);\n    CGColorRef backgroundColor = [options[SDImageCoderEncodeBackgroundColor] CGColor];\n    if (backgroundColor) {\n        properties[(__bridge NSString *)kCGImageDestinationBackgroundColor] = (__bridge id)(backgroundColor);\n    }\n    CGSize maxPixelSize = CGSizeZero;\n    NSValue *maxPixelSizeValue = options[SDImageCoderEncodeMaxPixelSize];\n    if (maxPixelSizeValue != nil) {\n#if SD_MAC\n        maxPixelSize = maxPixelSizeValue.sizeValue;\n#else\n        maxPixelSize = maxPixelSizeValue.CGSizeValue;\n#endif\n    }\n    NSUInteger pixelWidth = CGImageGetWidth(imageRef);\n    NSUInteger pixelHeight = CGImageGetHeight(imageRef);\n    CGFloat finalPixelSize = 0;\n    if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && pixelWidth > maxPixelSize.width && pixelHeight > maxPixelSize.height) {\n        CGFloat pixelRatio = pixelWidth / pixelHeight;\n        CGFloat maxPixelSizeRatio = maxPixelSize.width / maxPixelSize.height;\n        if (pixelRatio > maxPixelSizeRatio) {\n            finalPixelSize = maxPixelSize.width;\n        } else {\n            finalPixelSize = maxPixelSize.height;\n        }\n        properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize);\n    }\n    NSUInteger maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue];\n    if (maxFileSize > 0) {\n        properties[kSDCGImageDestinationRequestedFileSize] = @(maxFileSize);\n        // Remove the quality if we have file size limit\n        properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = nil;\n    }\n    BOOL embedThumbnail = NO;\n    if (options[SDImageCoderEncodeEmbedThumbnail]) {\n        embedThumbnail = [options[SDImageCoderEncodeEmbedThumbnail] boolValue];\n    }\n    properties[(__bridge NSString *)kCGImageDestinationEmbedThumbnail] = @(embedThumbnail);\n    \n    BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue];\n    if (encodeFirstFrame || frames.count == 0) {\n        // for static single images\n        CGImageDestinationAddImage(imageDestination, imageRef, (__bridge CFDictionaryRef)properties);\n    } else {\n        // for animated images\n        NSUInteger loopCount = image.sd_imageLoopCount;\n        NSDictionary *containerProperties = @{\n            self.class.dictionaryProperty: @{self.class.loopCountProperty : @(loopCount)}\n        };\n        // container level properties (applies for `CGImageDestinationSetProperties`, not individual frames)\n        CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)containerProperties);\n        \n        for (size_t i = 0; i < frames.count; i++) {\n            SDImageFrame *frame = frames[i];\n            NSTimeInterval frameDuration = frame.duration;\n            CGImageRef frameImageRef = frame.image.CGImage;\n            properties[self.class.dictionaryProperty] = @{self.class.delayTimeProperty : @(frameDuration)};\n            CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)properties);\n        }\n    }\n    // Finalize the destination.\n    if (CGImageDestinationFinalize(imageDestination) == NO) {\n        // Handle failure.\n        imageData = nil;\n    }\n    \n    CFRelease(imageDestination);\n    \n    return [imageData copy];\n}\n\n#pragma mark - SDAnimatedImageCoder\n- (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options {\n    if (!data) {\n        return nil;\n    }\n    self = [super init];\n    if (self) {\n        CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);\n        if (!imageSource) {\n            return nil;\n        }\n        BOOL framesValid = [self scanAndCheckFramesValidWithImageSource:imageSource];\n        if (!framesValid) {\n            CFRelease(imageSource);\n            return nil;\n        }\n        CGFloat scale = 1;\n        NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n        if (scaleFactor != nil) {\n            scale = MAX([scaleFactor doubleValue], 1);\n        }\n        _scale = scale;\n        CGSize thumbnailSize = CGSizeZero;\n        NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];\n        if (thumbnailSizeValue != nil) {\n    #if SD_MAC\n            thumbnailSize = thumbnailSizeValue.sizeValue;\n    #else\n            thumbnailSize = thumbnailSizeValue.CGSizeValue;\n    #endif\n        }\n        _thumbnailSize = thumbnailSize;\n        BOOL preserveAspectRatio = YES;\n        NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];\n        if (preserveAspectRatioValue != nil) {\n            preserveAspectRatio = preserveAspectRatioValue.boolValue;\n        }\n        _preserveAspectRatio = preserveAspectRatio;\n        _imageSource = imageSource;\n        _imageData = data;\n#if SD_UIKIT\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    }\n    return self;\n}\n\n- (BOOL)scanAndCheckFramesValidWithImageSource:(CGImageSourceRef)imageSource {\n    if (!imageSource) {\n        return NO;\n    }\n    NSUInteger frameCount = CGImageSourceGetCount(imageSource);\n    NSUInteger loopCount = [self.class imageLoopCountWithSource:imageSource];\n    NSMutableArray<SDImageIOCoderFrame *> *frames = [NSMutableArray array];\n    \n    for (size_t i = 0; i < frameCount; i++) {\n        SDImageIOCoderFrame *frame = [[SDImageIOCoderFrame alloc] init];\n        frame.index = i;\n        frame.duration = [self.class frameDurationAtIndex:i source:imageSource];\n        [frames addObject:frame];\n    }\n    \n    _frameCount = frameCount;\n    _loopCount = loopCount;\n    _frames = [frames copy];\n    \n    return YES;\n}\n\n- (NSData *)animatedImageData {\n    return _imageData;\n}\n\n- (NSUInteger)animatedImageLoopCount {\n    return _loopCount;\n}\n\n- (NSUInteger)animatedImageFrameCount {\n    return _frameCount;\n}\n\n- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {\n    if (index >= _frameCount) {\n        return 0;\n    }\n    return _frames[index].duration;\n}\n\n- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {\n    if (index >= _frameCount) {\n        return nil;\n    }\n    // Animated Image should not use the CGContext solution to force decode. Prefers to use Image/IO built in method, which is safer and memory friendly, see https://github.com/SDWebImage/SDWebImage/issues/2961\n    NSDictionary *options = @{\n        (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES),\n        (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage\n    };\n    UIImage *image = [self.class createFrameAtIndex:index source:_imageSource scale:_scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:options];\n    if (!image) {\n        return nil;\n    }\n    image.sd_imageFormat = self.class.imageFormat;\n    image.sd_isDecoded = YES;\n    return image;\n}\n\n@end\n\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDImageCoder.h\"\n\n/**\n Built in coder that supports PNG, JPEG, TIFF, includes support for progressive decoding.\n \n GIF\n Also supports static GIF (meaning will only handle the 1st frame).\n For a full GIF support, we recommend `SDAnimatedImageView` to keep both CPU and memory balanced.\n \n HEIC\n This coder also supports HEIC format because ImageIO supports it natively. But it depends on the system capabilities, so it won't work on all devices, see: https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf\n Decode(Software): !Simulator && (iOS 11 || tvOS 11 || macOS 10.13)\n Decode(Hardware): !Simulator && ((iOS 11 && A9Chip) || (macOS 10.13 && 6thGenerationIntelCPU))\n Encode(Software): macOS 10.13\n Encode(Hardware): !Simulator && ((iOS 11 && A10FusionChip) || (macOS 10.13 && 6thGenerationIntelCPU))\n */\n@interface SDImageIOCoder : NSObject <SDProgressiveImageCoder>\n\n@property (nonatomic, class, readonly, nonnull) SDImageIOCoder *sharedCoder;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageIOCoder.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"NSImage+Compatibility.h\"\n#import <ImageIO/ImageIO.h>\n#import \"UIImage+Metadata.h\"\n#import \"SDImageIOAnimatedCoderInternal.h\"\n\n// Specify File Size for lossy format encoding, like JPEG\nstatic NSString * kSDCGImageDestinationRequestedFileSize = @\"kCGImageDestinationRequestedFileSize\";\n\n@implementation SDImageIOCoder {\n    size_t _width, _height;\n    CGImagePropertyOrientation _orientation;\n    CGImageSourceRef _imageSource;\n    CGFloat _scale;\n    BOOL _finished;\n    BOOL _preserveAspectRatio;\n    CGSize _thumbnailSize;\n}\n\n- (void)dealloc {\n    if (_imageSource) {\n        CFRelease(_imageSource);\n        _imageSource = NULL;\n    }\n#if SD_UIKIT\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n}\n\n- (void)didReceiveMemoryWarning:(NSNotification *)notification\n{\n    if (_imageSource) {\n        CGImageSourceRemoveCacheAtIndex(_imageSource, 0);\n    }\n}\n\n+ (instancetype)sharedCoder {\n    static SDImageIOCoder *coder;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        coder = [[SDImageIOCoder alloc] init];\n    });\n    return coder;\n}\n\n#pragma mark - Decode\n- (BOOL)canDecodeFromData:(nullable NSData *)data {\n    return YES;\n}\n\n- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {\n    if (!data) {\n        return nil;\n    }\n    CGFloat scale = 1;\n    NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n    if (scaleFactor != nil) {\n        scale = MAX([scaleFactor doubleValue], 1) ;\n    }\n    \n    CGSize thumbnailSize = CGSizeZero;\n    NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];\n    if (thumbnailSizeValue != nil) {\n#if SD_MAC\n        thumbnailSize = thumbnailSizeValue.sizeValue;\n#else\n        thumbnailSize = thumbnailSizeValue.CGSizeValue;\n#endif\n    }\n    \n    BOOL preserveAspectRatio = YES;\n    NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];\n    if (preserveAspectRatioValue != nil) {\n        preserveAspectRatio = preserveAspectRatioValue.boolValue;\n    }\n    \n    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);\n    if (!source) {\n        return nil;\n    }\n    \n    UIImage *image = [SDImageIOAnimatedCoder createFrameAtIndex:0 source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil];\n    CFRelease(source);\n    if (!image) {\n        return nil;\n    }\n    \n    image.sd_imageFormat = [NSData sd_imageFormatForImageData:data];\n    return image;\n}\n\n#pragma mark - Progressive Decode\n\n- (BOOL)canIncrementalDecodeFromData:(NSData *)data {\n    return [self canDecodeFromData:data];\n}\n\n- (instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options {\n    self = [super init];\n    if (self) {\n        _imageSource = CGImageSourceCreateIncremental(NULL);\n        CGFloat scale = 1;\n        NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n        if (scaleFactor != nil) {\n            scale = MAX([scaleFactor doubleValue], 1);\n        }\n        _scale = scale;\n        CGSize thumbnailSize = CGSizeZero;\n        NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];\n        if (thumbnailSizeValue != nil) {\n    #if SD_MAC\n            thumbnailSize = thumbnailSizeValue.sizeValue;\n    #else\n            thumbnailSize = thumbnailSizeValue.CGSizeValue;\n    #endif\n        }\n        _thumbnailSize = thumbnailSize;\n        BOOL preserveAspectRatio = YES;\n        NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];\n        if (preserveAspectRatioValue != nil) {\n            preserveAspectRatio = preserveAspectRatioValue.boolValue;\n        }\n        _preserveAspectRatio = preserveAspectRatio;\n#if SD_UIKIT\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    }\n    return self;\n}\n\n- (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished {\n    if (_finished) {\n        return;\n    }\n    _finished = finished;\n    \n    // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/\n    // Thanks to the author @Nyx0uf\n    \n    // Update the data source, we must pass ALL the data, not just the new bytes\n    CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)data, finished);\n    \n    if (_width + _height == 0) {\n        CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, NULL);\n        if (properties) {\n            NSInteger orientationValue = 1;\n            CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);\n            if (val) CFNumberGetValue(val, kCFNumberLongType, &_height);\n            val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);\n            if (val) CFNumberGetValue(val, kCFNumberLongType, &_width);\n            val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);\n            if (val) CFNumberGetValue(val, kCFNumberNSIntegerType, &orientationValue);\n            CFRelease(properties);\n            \n            // When we draw to Core Graphics, we lose orientation information,\n            // which means the image below born of initWithCGIImage will be\n            // oriented incorrectly sometimes. (Unlike the image born of initWithData\n            // in didCompleteWithError.) So save it here and pass it on later.\n            _orientation = (CGImagePropertyOrientation)orientationValue;\n        }\n    }\n}\n\n- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options {\n    UIImage *image;\n    \n    if (_width + _height > 0) {\n        // Create the image\n        CGFloat scale = _scale;\n        NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];\n        if (scaleFactor != nil) {\n            scale = MAX([scaleFactor doubleValue], 1);\n        }\n        image = [SDImageIOAnimatedCoder createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:nil];\n        if (image) {\n            CFStringRef uttype = CGImageSourceGetType(_imageSource);\n            image.sd_imageFormat = [NSData sd_imageFormatFromUTType:uttype];\n        }\n    }\n    \n    return image;\n}\n\n#pragma mark - Encode\n- (BOOL)canEncodeToFormat:(SDImageFormat)format {\n    return YES;\n}\n\n- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options {\n    if (!image) {\n        return nil;\n    }\n    CGImageRef imageRef = image.CGImage;\n    if (!imageRef) {\n        // Earily return, supports CGImage only\n        return nil;\n    }\n    \n    if (format == SDImageFormatUndefined) {\n        BOOL hasAlpha = [SDImageCoderHelper CGImageContainsAlpha:imageRef];\n        if (hasAlpha) {\n            format = SDImageFormatPNG;\n        } else {\n            format = SDImageFormatJPEG;\n        }\n    }\n    \n    NSMutableData *imageData = [NSMutableData data];\n    CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format];\n    \n    // Create an image destination.\n    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL);\n    if (!imageDestination) {\n        // Handle failure.\n        return nil;\n    }\n    \n    NSMutableDictionary *properties = [NSMutableDictionary dictionary];\n#if SD_UIKIT || SD_WATCH\n    CGImagePropertyOrientation exifOrientation = [SDImageCoderHelper exifOrientationFromImageOrientation:image.imageOrientation];\n#else\n    CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp;\n#endif\n    properties[(__bridge NSString *)kCGImagePropertyOrientation] = @(exifOrientation);\n    // Encoding Options\n    double compressionQuality = 1;\n    if (options[SDImageCoderEncodeCompressionQuality]) {\n        compressionQuality = [options[SDImageCoderEncodeCompressionQuality] doubleValue];\n    }\n    properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = @(compressionQuality);\n    CGColorRef backgroundColor = [options[SDImageCoderEncodeBackgroundColor] CGColor];\n    if (backgroundColor) {\n        properties[(__bridge NSString *)kCGImageDestinationBackgroundColor] = (__bridge id)(backgroundColor);\n    }\n    CGSize maxPixelSize = CGSizeZero;\n    NSValue *maxPixelSizeValue = options[SDImageCoderEncodeMaxPixelSize];\n    if (maxPixelSizeValue != nil) {\n#if SD_MAC\n        maxPixelSize = maxPixelSizeValue.sizeValue;\n#else\n        maxPixelSize = maxPixelSizeValue.CGSizeValue;\n#endif\n    }\n    NSUInteger pixelWidth = CGImageGetWidth(imageRef);\n    NSUInteger pixelHeight = CGImageGetHeight(imageRef);\n    if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && pixelWidth > maxPixelSize.width && pixelHeight > maxPixelSize.height) {\n        CGFloat pixelRatio = pixelWidth / pixelHeight;\n        CGFloat maxPixelSizeRatio = maxPixelSize.width / maxPixelSize.height;\n        CGFloat finalPixelSize;\n        if (pixelRatio > maxPixelSizeRatio) {\n            finalPixelSize = maxPixelSize.width;\n        } else {\n            finalPixelSize = maxPixelSize.height;\n        }\n        properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize);\n    }\n    NSUInteger maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue];\n    if (maxFileSize > 0) {\n        properties[kSDCGImageDestinationRequestedFileSize] = @(maxFileSize);\n        // Remove the quality if we have file size limit\n        properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = nil;\n    }\n    BOOL embedThumbnail = NO;\n    if (options[SDImageCoderEncodeEmbedThumbnail]) {\n        embedThumbnail = [options[SDImageCoderEncodeEmbedThumbnail] boolValue];\n    }\n    properties[(__bridge NSString *)kCGImageDestinationEmbedThumbnail] = @(embedThumbnail);\n    \n    // Add your image to the destination.\n    CGImageDestinationAddImage(imageDestination, imageRef, (__bridge CFDictionaryRef)properties);\n    \n    // Finalize the destination.\n    if (CGImageDestinationFinalize(imageDestination) == NO) {\n        // Handle failure.\n        imageData = nil;\n    }\n    \n    CFRelease(imageDestination);\n    \n    return [imageData copy];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageLoader.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n#import \"SDWebImageOperation.h\"\n#import \"SDImageCoder.h\"\n\ntypedef void(^SDImageLoaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL);\ntypedef void(^SDImageLoaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished);\n\n#pragma mark - Context Options\n\n/**\n A `UIImage` instance from `SDWebImageManager` when you specify `SDWebImageRefreshCached` and image cache hit.\n This can be a hint for image loader to load the image from network and refresh the image from remote location if needed. If the image from remote location does not change, you should call the completion with `SDWebImageErrorCacheNotModified` error. (UIImage)\n @note If you don't implement `SDWebImageRefreshCached` support, you do not need to care about this context option.\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextLoaderCachedImage;\n\n#pragma mark - Helper method\n\n/**\n This is the built-in decoding process for image download from network or local file.\n @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image.\n\n @param imageData The image data from the network. Should not be nil\n @param imageURL The image URL from the input. Should not be nil\n @param options The options arg from the input\n @param context The context arg from the input\n @return The decoded image for current image data load from the network\n */\nFOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context);\n\n/**\n This is the built-in decoding process for image progressive download from network. It's used when `SDWebImageProgressiveLoad` option is set. (It's not required when your loader does not support progressive image loading)\n @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image.\n\n @param imageData The image data from the network so far. Should not be nil\n @param imageURL The image URL from the input. Should not be nil\n @param finished Pass NO to specify the download process has not finished. Pass YES when all image data has finished.\n @param operation The loader operation associated with current progressive download. Why to provide this is because progressive decoding need to store the partial decoded context for each operation to avoid conflict. You should provide the operation from `loadImageWithURL:` method return value.\n @param options The options arg from the input\n @param context The context arg from the input\n @return The decoded progressive image for current image data load from the network\n */\nFOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished,  id<SDWebImageOperation> _Nonnull operation, SDWebImageOptions options, SDWebImageContext * _Nullable context);\n\n/**\n This function get the progressive decoder for current loading operation. If no progressive decoding is happended or decoder is not able to construct, return nil.\n @return The progressive decoder associated with the loading operation.\n */\nFOUNDATION_EXPORT id<SDProgressiveImageCoder> _Nullable SDImageLoaderGetProgressiveCoder(id<SDWebImageOperation> _Nonnull operation);\n\n/**\n This function set the progressive decoder for current loading operation. If no progressive decoding is happended, pass nil.\n @param operation The loading operation to associate the progerssive decoder.\n */\nFOUNDATION_EXPORT void SDImageLoaderSetProgressiveCoder(id<SDWebImageOperation> _Nonnull operation, id<SDProgressiveImageCoder> _Nullable progressiveCoder);\n\n#pragma mark - SDImageLoader\n\n/**\n This is the protocol to specify custom image load process. You can create your own class to conform this protocol and use as a image loader to load image from network or any available remote resources defined by yourself.\n If you want to implement custom loader for image download from network or local file, you just need to concentrate on image data download only. After the download finish, call `SDImageLoaderDecodeImageData` or `SDImageLoaderDecodeProgressiveImageData` to use the built-in decoding process and produce image (Remember to call in the global queue). And finally callback the completion block.\n If you directly get the image instance using some third-party SDKs, such as image directly from Photos framework. You can process the image data and image instance by yourself without that built-in decoding process. And finally callback the completion block.\n @note It's your responsibility to load the image in the desired global queue(to avoid block main queue). We do not dispatch these method call in a global queue but just from the call queue (For `SDWebImageManager`, it typically call from the main queue).\n*/\n@protocol SDImageLoader <NSObject>\n\n@required\n/**\n Whether current image loader supports to load the provide image URL.\n This will be checked every time a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `requestImageWithURL:options:context:progress:completed:`.\n\n @param url The image URL to be loaded.\n @return YES to continue download, NO to stop download.\n */\n- (BOOL)canRequestImageForURL:(nullable NSURL *)url API_DEPRECATED(\"Use canRequestImageForURL:options:context: instead\", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));\n\n@optional\n/**\n Whether current image loader supports to load the provide image URL, with associated options and context.\n This will be checked every time a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `requestImageWithURL:options:context:progress:completed:`.\n\n @param url The image URL to be loaded.\n @param options A mask to specify options to use for this request\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @return YES to continue download, NO to stop download.\n */\n- (BOOL)canRequestImageForURL:(nullable NSURL *)url\n                      options:(SDWebImageOptions)options\n                      context:(nullable SDWebImageContext *)context;\n\n@required\n/**\n Load the image and image data with the given URL and return the image data. You're responsible for producing the image instance.\n\n @param url The URL represent the image. Note this may not be a HTTP URL\n @param options A mask to specify options to use for this request\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @param progressBlock A block called while image is downloading\n *                    @note the progress block is executed on a background queue\n @param completedBlock A block called when operation has been completed.\n @return An operation which allow the user to cancel the current request.\n */\n- (nullable id<SDWebImageOperation>)requestImageWithURL:(nullable NSURL *)url\n                                                options:(SDWebImageOptions)options\n                                                context:(nullable SDWebImageContext *)context\n                                               progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                              completed:(nullable SDImageLoaderCompletedBlock)completedBlock;\n\n\n/**\n Whether the error from image loader should be marked indeed un-recoverable or not.\n If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not.\n\n @param url The URL represent the image. Note this may not be a HTTP URL\n @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error.\n @return Whether to block this url or not. Return YES to mark this URL as failed.\n */\n- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url\n                              error:(nonnull NSError *)error API_DEPRECATED(\"Use shouldBlockFailedURLWithURL:error:options:context: instead\", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));\n\n@optional\n/**\n Whether the error from image loader should be marked indeed un-recoverable or not, with associated options and context.\n If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not.\n\n @param url The URL represent the image. Note this may not be a HTTP URL\n @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error.\n @param options A mask to specify options to use for this request\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @return Whether to block this url or not. Return YES to mark this URL as failed.\n */\n- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url\n                              error:(nonnull NSError *)error\n                            options:(SDWebImageOptions)options\n                            context:(nullable SDWebImageContext *)context;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageLoader.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageLoader.h\"\n#import \"SDWebImageCacheKeyFilter.h\"\n#import \"SDImageCodersManager.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDAnimatedImage.h\"\n#import \"UIImage+Metadata.h\"\n#import \"SDInternalMacros.h\"\n#import \"objc/runtime.h\"\n\nSDWebImageContextOption const SDWebImageContextLoaderCachedImage = @\"loaderCachedImage\";\n\nstatic void * SDImageLoaderProgressiveCoderKey = &SDImageLoaderProgressiveCoderKey;\n\nid<SDProgressiveImageCoder> SDImageLoaderGetProgressiveCoder(id<SDWebImageOperation> operation) {\n    NSCParameterAssert(operation);\n    return objc_getAssociatedObject(operation, SDImageLoaderProgressiveCoderKey);\n}\n\nvoid SDImageLoaderSetProgressiveCoder(id<SDWebImageOperation> operation, id<SDProgressiveImageCoder> progressiveCoder) {\n    NSCParameterAssert(operation);\n    objc_setAssociatedObject(operation, SDImageLoaderProgressiveCoderKey, progressiveCoder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\nUIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context) {\n    NSCParameterAssert(imageData);\n    NSCParameterAssert(imageURL);\n    \n    UIImage *image;\n    id<SDWebImageCacheKeyFilter> cacheKeyFilter = context[SDWebImageContextCacheKeyFilter];\n    NSString *cacheKey;\n    if (cacheKeyFilter) {\n        cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL];\n    } else {\n        cacheKey = imageURL.absoluteString;\n    }\n    BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);\n    NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];\n    CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey);\n    NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio];\n    NSValue *thumbnailSizeValue;\n    BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages);\n    if (shouldScaleDown) {\n        CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4;\n        CGFloat dimension = ceil(sqrt(thumbnailPixels));\n        thumbnailSizeValue = @(CGSizeMake(dimension, dimension));\n    }\n    if (context[SDWebImageContextImageThumbnailPixelSize]) {\n        thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];\n    }\n    \n    SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2];\n    mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame);\n    mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);\n    mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue;\n    mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue;\n    mutableCoderOptions[SDImageCoderWebImageContext] = context;\n    SDImageCoderOptions *coderOptions = [mutableCoderOptions copy];\n    \n    // Grab the image coder\n    id<SDImageCoder> imageCoder;\n    if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) {\n        imageCoder = context[SDWebImageContextImageCoder];\n    } else {\n        imageCoder = [SDImageCodersManager sharedManager];\n    }\n    \n    if (!decodeFirstFrame) {\n        // check whether we should use `SDAnimatedImage`\n        Class animatedImageClass = context[SDWebImageContextAnimatedImageClass];\n        if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) {\n            image = [[animatedImageClass alloc] initWithData:imageData scale:scale options:coderOptions];\n            if (image) {\n                // Preload frames if supported\n                if (options & SDWebImagePreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) {\n                    [((id<SDAnimatedImage>)image) preloadAllFrames];\n                }\n            } else {\n                // Check image class matching\n                if (options & SDWebImageMatchAnimatedImageClass) {\n                    return nil;\n                }\n            }\n        }\n    }\n    if (!image) {\n        image = [imageCoder decodedImageWithData:imageData options:coderOptions];\n    }\n    if (image) {\n        BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage);\n        if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {\n            // `SDAnimatedImage` do not decode\n            shouldDecode = NO;\n        } else if (image.sd_isAnimated) {\n            // animated image do not decode\n            shouldDecode = NO;\n        }\n        \n        if (shouldDecode) {\n            image = [SDImageCoderHelper decodedImageWithImage:image];\n        }\n    }\n    \n    return image;\n}\n\nUIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished,  id<SDWebImageOperation> _Nonnull operation, SDWebImageOptions options, SDWebImageContext * _Nullable context) {\n    NSCParameterAssert(imageData);\n    NSCParameterAssert(imageURL);\n    NSCParameterAssert(operation);\n    \n    UIImage *image;\n    id<SDWebImageCacheKeyFilter> cacheKeyFilter = context[SDWebImageContextCacheKeyFilter];\n    NSString *cacheKey;\n    if (cacheKeyFilter) {\n        cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL];\n    } else {\n        cacheKey = imageURL.absoluteString;\n    }\n    BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);\n    NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];\n    CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey);\n    NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio];\n    NSValue *thumbnailSizeValue;\n    BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages);\n    if (shouldScaleDown) {\n        CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4;\n        CGFloat dimension = ceil(sqrt(thumbnailPixels));\n        thumbnailSizeValue = @(CGSizeMake(dimension, dimension));\n    }\n    if (context[SDWebImageContextImageThumbnailPixelSize]) {\n        thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];\n    }\n    \n    SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2];\n    mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame);\n    mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);\n    mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue;\n    mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue;\n    mutableCoderOptions[SDImageCoderWebImageContext] = context;\n    SDImageCoderOptions *coderOptions = [mutableCoderOptions copy];\n    \n    // Grab the progressive image coder\n    id<SDProgressiveImageCoder> progressiveCoder = SDImageLoaderGetProgressiveCoder(operation);\n    if (!progressiveCoder) {\n        id<SDProgressiveImageCoder> imageCoder = context[SDWebImageContextImageCoder];\n        // Check the progressive coder if provided\n        if ([imageCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) {\n            progressiveCoder = [[[imageCoder class] alloc] initIncrementalWithOptions:coderOptions];\n        } else {\n            // We need to create a new instance for progressive decoding to avoid conflicts\n            for (id<SDImageCoder> coder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) {\n                if ([coder conformsToProtocol:@protocol(SDProgressiveImageCoder)] &&\n                    [((id<SDProgressiveImageCoder>)coder) canIncrementalDecodeFromData:imageData]) {\n                    progressiveCoder = [[[coder class] alloc] initIncrementalWithOptions:coderOptions];\n                    break;\n                }\n            }\n        }\n        SDImageLoaderSetProgressiveCoder(operation, progressiveCoder);\n    }\n    // If we can't find any progressive coder, disable progressive download\n    if (!progressiveCoder) {\n        return nil;\n    }\n    \n    [progressiveCoder updateIncrementalData:imageData finished:finished];\n    if (!decodeFirstFrame) {\n        // check whether we should use `SDAnimatedImage`\n        Class animatedImageClass = context[SDWebImageContextAnimatedImageClass];\n        if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [progressiveCoder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) {\n            image = [[animatedImageClass alloc] initWithAnimatedCoder:(id<SDAnimatedImageCoder>)progressiveCoder scale:scale];\n            if (image) {\n                // Progressive decoding does not preload frames\n            } else {\n                // Check image class matching\n                if (options & SDWebImageMatchAnimatedImageClass) {\n                    return nil;\n                }\n            }\n        }\n    }\n    if (!image) {\n        image = [progressiveCoder incrementalDecodedImageWithOptions:coderOptions];\n    }\n    if (image) {\n        BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage);\n        if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {\n            // `SDAnimatedImage` do not decode\n            shouldDecode = NO;\n        } else if (image.sd_isAnimated) {\n            // animated image do not decode\n            shouldDecode = NO;\n        }\n        if (shouldDecode) {\n            image = [SDImageCoderHelper decodedImageWithImage:image];\n        }\n        // mark the image as progressive (completed one are not mark as progressive)\n        image.sd_isIncremental = !finished;\n    }\n    \n    return image;\n}\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageLoader.h\"\n\n/**\n A loaders manager to manage multiple loaders\n */\n@interface SDImageLoadersManager : NSObject <SDImageLoader>\n\n/**\n Returns the global shared loaders manager instance. By default we will set [`SDWebImageDownloader.sharedDownloader`] into the loaders array.\n */\n@property (nonatomic, class, readonly, nonnull) SDImageLoadersManager *sharedManager;\n\n/**\n All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority\n */\n@property (nonatomic, copy, nullable) NSArray<id<SDImageLoader>>* loaders;\n\n/**\n Add a new image loader to the end of loaders array. Which has the highest priority.\n \n @param loader loader\n */\n- (void)addLoader:(nonnull id<SDImageLoader>)loader;\n\n/**\n Remove an image loader in the loaders array.\n \n @param loader loader\n */\n- (void)removeLoader:(nonnull id<SDImageLoader>)loader;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageLoadersManager.h\"\n#import \"SDWebImageDownloader.h\"\n#import \"SDInternalMacros.h\"\n\n@interface SDImageLoadersManager ()\n\n@property (nonatomic, strong, nonnull) NSMutableArray<id<SDImageLoader>> *imageLoaders;\n\n@end\n\n@implementation SDImageLoadersManager {\n    SD_LOCK_DECLARE(_loadersLock);\n}\n\n+ (SDImageLoadersManager *)sharedManager {\n    static dispatch_once_t onceToken;\n    static SDImageLoadersManager *manager;\n    dispatch_once(&onceToken, ^{\n        manager = [[SDImageLoadersManager alloc] init];\n    });\n    return manager;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        // initialize with default image loaders\n        _imageLoaders = [NSMutableArray arrayWithObject:[SDWebImageDownloader sharedDownloader]];\n        SD_LOCK_INIT(_loadersLock);\n    }\n    return self;\n}\n\n- (NSArray<id<SDImageLoader>> *)loaders {\n    SD_LOCK(_loadersLock);\n    NSArray<id<SDImageLoader>>* loaders = [_imageLoaders copy];\n    SD_UNLOCK(_loadersLock);\n    return loaders;\n}\n\n- (void)setLoaders:(NSArray<id<SDImageLoader>> *)loaders {\n    SD_LOCK(_loadersLock);\n    [_imageLoaders removeAllObjects];\n    if (loaders.count) {\n        [_imageLoaders addObjectsFromArray:loaders];\n    }\n    SD_UNLOCK(_loadersLock);\n}\n\n#pragma mark - Loader Property\n\n- (void)addLoader:(id<SDImageLoader>)loader {\n    if (![loader conformsToProtocol:@protocol(SDImageLoader)]) {\n        return;\n    }\n    SD_LOCK(_loadersLock);\n    [_imageLoaders addObject:loader];\n    SD_UNLOCK(_loadersLock);\n}\n\n- (void)removeLoader:(id<SDImageLoader>)loader {\n    if (![loader conformsToProtocol:@protocol(SDImageLoader)]) {\n        return;\n    }\n    SD_LOCK(_loadersLock);\n    [_imageLoaders removeObject:loader];\n    SD_UNLOCK(_loadersLock);\n}\n\n#pragma mark - SDImageLoader\n\n- (BOOL)canRequestImageForURL:(nullable NSURL *)url {\n    NSArray<id<SDImageLoader>> *loaders = self.loaders;\n    for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {\n        if ([loader canRequestImageForURL:url]) {\n            return YES;\n        }\n    }\n    return NO;\n}\n\n- (id<SDWebImageOperation>)requestImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock {\n    if (!url) {\n        return nil;\n    }\n    NSArray<id<SDImageLoader>> *loaders = self.loaders;\n    for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {\n        if ([loader canRequestImageForURL:url]) {\n            return [loader requestImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock];\n        }\n    }\n    return nil;\n}\n\n- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error {\n    NSArray<id<SDImageLoader>> *loaders = self.loaders;\n    for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {\n        if ([loader canRequestImageForURL:url]) {\n            return [loader shouldBlockFailedURLWithURL:url error:error];\n        }\n    }\n    return NO;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"UIImage+Transform.h\"\n\n/**\n Return the transformed cache key which applied with specify transformerKey.\n\n @param key The original cache key\n @param transformerKey The transformer key from the transformer\n @return The transformed cache key\n */\nFOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey);\n\n/**\n Return the thumbnailed cache key which applied with specify thumbnailSize and preserveAspectRatio control.\n @param key The original cache key\n @param thumbnailPixelSize The thumbnail pixel size\n @param preserveAspectRatio The preserve aspect ratio option\n @return The thumbnailed cache key\n @note If you have both transformer and thumbnail applied for image, call `SDThumbnailedKeyForKey` firstly and then with `SDTransformedKeyForKey`.`\n */\nFOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio);\n\n/**\n A transformer protocol to transform the image load from cache or from download.\n You can provide transformer to cache and manager (Through the `transformer` property or context option `SDWebImageContextImageTransformer`).\n \n @note The transform process is called from a global queue in order to not to block the main queue.\n */\n@protocol SDImageTransformer <NSObject>\n\n@required\n/**\n For each transformer, it must contains its cache key to used to store the image cache or query from the cache. This key will be appened after the original cache key generated by URL or from user.\n\n @return The cache key to appended after the original cache key. Should not be nil.\n */\n@property (nonatomic, copy, readonly, nonnull) NSString *transformerKey;\n\n/**\n Transform the image to another image.\n\n @param image The image to be transformed\n @param key The cache key associated to the image. This arg is a hint for image source, not always useful and should be nullable. In the future we will remove this arg.\n @return The transformed image, or nil if transform failed\n */\n- (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key API_DEPRECATED(\"The key arg will be removed in the future. Update your code and don't rely on that.\", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));\n\n@end\n\n#pragma mark - Pipeline\n\n/**\n Pipeline transformer. Which you can bind multiple transformers together to let the image to be transformed one by one in order and generate the final image.\n @note Because transformers are lightweight, if you want to append or arrange transformers, create another pipeline transformer instead. This class is considered as immutable.\n */\n@interface SDImagePipelineTransformer : NSObject <SDImageTransformer>\n\n/**\n All transformers in pipeline\n */\n@property (nonatomic, copy, readonly, nonnull) NSArray<id<SDImageTransformer>> *transformers;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithTransformers:(nonnull NSArray<id<SDImageTransformer>> *)transformers;\n\n@end\n\n// There are some built-in transformers based on the `UIImage+Transformer` category to provide the common image geometry, image blending and image effect process. Those transform are useful for static image only but you can create your own to support animated image as well.\n// Because transformers are lightweight, these class are considered as immutable.\n#pragma mark - Image Geometry\n\n/**\n Image round corner transformer\n */\n@interface SDImageRoundCornerTransformer: NSObject <SDImageTransformer>\n\n/**\n The radius of each corner oval. Values larger than half the\n rectangle's width or height are clamped appropriately to\n half the width or height.\n */\n@property (nonatomic, assign, readonly) CGFloat cornerRadius;\n\n/**\n A bitmask value that identifies the corners that you want\n rounded. You can use this parameter to round only a subset\n of the corners of the rectangle.\n */\n@property (nonatomic, assign, readonly) SDRectCorner corners;\n\n/**\n The inset border line width. Values larger than half the rectangle's\n width or height are clamped appropriately to half the width\n or height.\n */\n@property (nonatomic, assign, readonly) CGFloat borderWidth;\n\n/**\n The border stroke color. nil means clear color.\n */\n@property (nonatomic, strong, readonly, nullable) UIColor *borderColor;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor;\n\n@end\n\n/**\n Image resizing transformer\n */\n@interface SDImageResizingTransformer : NSObject <SDImageTransformer>\n\n/**\n The new size to be resized, values should be positive.\n */\n@property (nonatomic, assign, readonly) CGSize size;\n\n/**\n The scale mode for image content.\n */\n@property (nonatomic, assign, readonly) SDImageScaleMode scaleMode;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode;\n\n@end\n\n/**\n Image cropping transformer\n */\n@interface SDImageCroppingTransformer : NSObject <SDImageTransformer>\n\n/**\n Image's inner rect.\n */\n@property (nonatomic, assign, readonly) CGRect rect;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithRect:(CGRect)rect;\n\n@end\n\n/**\n Image flipping transformer\n */\n@interface SDImageFlippingTransformer : NSObject <SDImageTransformer>\n\n/**\n YES to flip the image horizontally. ⇋\n */\n@property (nonatomic, assign, readonly) BOOL horizontal;\n\n/**\n YES to flip the image vertically. ⥯\n */\n@property (nonatomic, assign, readonly) BOOL vertical;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;\n\n@end\n\n/**\n Image rotation transformer\n */\n@interface SDImageRotationTransformer : NSObject <SDImageTransformer>\n\n/**\n Rotated radians in counterclockwise.⟲\n */\n@property (nonatomic, assign, readonly) CGFloat angle;\n\n/**\n YES: new image's size is extend to fit all content.\n NO: image's size will not change, content may be clipped.\n */\n@property (nonatomic, assign, readonly) BOOL fitSize;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;\n\n@end\n\n#pragma mark - Image Blending\n\n/**\n Image tint color transformer\n */\n@interface SDImageTintTransformer : NSObject <SDImageTransformer>\n\n/**\n The tint color.\n */\n@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithColor:(nonnull UIColor *)tintColor;\n\n@end\n\n#pragma mark - Image Effect\n\n/**\n Image blur effect transformer\n */\n@interface SDImageBlurTransformer : NSObject <SDImageTransformer>\n\n/**\n The radius of the blur in points, 0 means no blur effect.\n */\n@property (nonatomic, assign, readonly) CGFloat blurRadius;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithRadius:(CGFloat)blurRadius;\n\n@end\n\n#if SD_UIKIT || SD_MAC\n/**\n Core Image filter transformer\n */\n@interface SDImageFilterTransformer: NSObject <SDImageTransformer>\n\n/**\n The CIFilter to be applied to the image.\n */\n@property (nonatomic, strong, readonly, nonnull) CIFilter *filter;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)transformerWithFilter:(nonnull CIFilter *)filter;\n\n@end\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageTransformer.h\"\n#import \"UIColor+SDHexString.h\"\n#if SD_UIKIT || SD_MAC\n#import <CoreImage/CoreImage.h>\n#endif\n\n// Separator for different transformerKey, for example, `image.png` |> flip(YES,NO) |> rotate(pi/4,YES) => 'image-SDImageFlippingTransformer(1,0)-SDImageRotationTransformer(0.78539816339,1).png'\nstatic NSString * const SDImageTransformerKeySeparator = @\"-\";\n\nNSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey) {\n    if (!key || !transformerKey) {\n        return nil;\n    }\n    // Find the file extension\n    NSURL *keyURL = [NSURL URLWithString:key];\n    NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension;\n    if (ext.length > 0) {\n        // For non-file URL\n        if (keyURL && !keyURL.isFileURL) {\n            // keep anything except path (like URL query)\n            NSURLComponents *component = [NSURLComponents componentsWithURL:keyURL resolvingAgainstBaseURL:NO];\n            component.path = [[[component.path.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext];\n            return component.URL.absoluteString;\n        } else {\n            // file URL\n            return [[[key.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext];\n        }\n    } else {\n        return [[key stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey];\n    }\n}\n\nNSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio) {\n    NSString *thumbnailKey = [NSString stringWithFormat:@\"Thumbnail({%f,%f},%d)\", thumbnailPixelSize.width, thumbnailPixelSize.height, preserveAspectRatio];\n    return SDTransformedKeyForKey(key, thumbnailKey);\n}\n\n@interface SDImagePipelineTransformer ()\n\n@property (nonatomic, copy, readwrite, nonnull) NSArray<id<SDImageTransformer>> *transformers;\n@property (nonatomic, copy, readwrite) NSString *transformerKey;\n\n@end\n\n@implementation SDImagePipelineTransformer\n\n+ (instancetype)transformerWithTransformers:(NSArray<id<SDImageTransformer>> *)transformers {\n    SDImagePipelineTransformer *transformer = [SDImagePipelineTransformer new];\n    transformer.transformers = transformers;\n    transformer.transformerKey = [[self class] cacheKeyForTransformers:transformers];\n    \n    return transformer;\n}\n\n+ (NSString *)cacheKeyForTransformers:(NSArray<id<SDImageTransformer>> *)transformers {\n    if (transformers.count == 0) {\n        return @\"\";\n    }\n    NSMutableArray<NSString *> *cacheKeys = [NSMutableArray arrayWithCapacity:transformers.count];\n    [transformers enumerateObjectsUsingBlock:^(id<SDImageTransformer>  _Nonnull transformer, NSUInteger idx, BOOL * _Nonnull stop) {\n        NSString *cacheKey = transformer.transformerKey;\n        [cacheKeys addObject:cacheKey];\n    }];\n    \n    return [cacheKeys componentsJoinedByString:SDImageTransformerKeySeparator];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    UIImage *transformedImage = image;\n    for (id<SDImageTransformer> transformer in self.transformers) {\n        transformedImage = [transformer transformedImageWithImage:transformedImage forKey:key];\n    }\n    return transformedImage;\n}\n\n@end\n\n@interface SDImageRoundCornerTransformer ()\n\n@property (nonatomic, assign) CGFloat cornerRadius;\n@property (nonatomic, assign) SDRectCorner corners;\n@property (nonatomic, assign) CGFloat borderWidth;\n@property (nonatomic, strong, nullable) UIColor *borderColor;\n\n@end\n\n@implementation SDImageRoundCornerTransformer\n\n+ (instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor {\n    SDImageRoundCornerTransformer *transformer = [SDImageRoundCornerTransformer new];\n    transformer.cornerRadius = cornerRadius;\n    transformer.corners = corners;\n    transformer.borderWidth = borderWidth;\n    transformer.borderColor = borderColor;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageRoundCornerTransformer(%f,%lu,%f,%@)\", self.cornerRadius, (unsigned long)self.corners, self.borderWidth, self.borderColor.sd_hexString];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_roundedCornerImageWithRadius:self.cornerRadius corners:self.corners borderWidth:self.borderWidth borderColor:self.borderColor];\n}\n\n@end\n\n@interface SDImageResizingTransformer ()\n\n@property (nonatomic, assign) CGSize size;\n@property (nonatomic, assign) SDImageScaleMode scaleMode;\n\n@end\n\n@implementation SDImageResizingTransformer\n\n+ (instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode {\n    SDImageResizingTransformer *transformer = [SDImageResizingTransformer new];\n    transformer.size = size;\n    transformer.scaleMode = scaleMode;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    CGSize size = self.size;\n    return [NSString stringWithFormat:@\"SDImageResizingTransformer({%f,%f},%lu)\", size.width, size.height, (unsigned long)self.scaleMode];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_resizedImageWithSize:self.size scaleMode:self.scaleMode];\n}\n\n@end\n\n@interface SDImageCroppingTransformer ()\n\n@property (nonatomic, assign) CGRect rect;\n\n@end\n\n@implementation SDImageCroppingTransformer\n\n+ (instancetype)transformerWithRect:(CGRect)rect {\n    SDImageCroppingTransformer *transformer = [SDImageCroppingTransformer new];\n    transformer.rect = rect;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    CGRect rect = self.rect;\n    return [NSString stringWithFormat:@\"SDImageCroppingTransformer({%f,%f,%f,%f})\", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_croppedImageWithRect:self.rect];\n}\n\n@end\n\n@interface SDImageFlippingTransformer ()\n\n@property (nonatomic, assign) BOOL horizontal;\n@property (nonatomic, assign) BOOL vertical;\n\n@end\n\n@implementation SDImageFlippingTransformer\n\n+ (instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {\n    SDImageFlippingTransformer *transformer = [SDImageFlippingTransformer new];\n    transformer.horizontal = horizontal;\n    transformer.vertical = vertical;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageFlippingTransformer(%d,%d)\", self.horizontal, self.vertical];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_flippedImageWithHorizontal:self.horizontal vertical:self.vertical];\n}\n\n@end\n\n@interface SDImageRotationTransformer ()\n\n@property (nonatomic, assign) CGFloat angle;\n@property (nonatomic, assign) BOOL fitSize;\n\n@end\n\n@implementation SDImageRotationTransformer\n\n+ (instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize {\n    SDImageRotationTransformer *transformer = [SDImageRotationTransformer new];\n    transformer.angle = angle;\n    transformer.fitSize = fitSize;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageRotationTransformer(%f,%d)\", self.angle, self.fitSize];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_rotatedImageWithAngle:self.angle fitSize:self.fitSize];\n}\n\n@end\n\n#pragma mark - Image Blending\n\n@interface SDImageTintTransformer ()\n\n@property (nonatomic, strong, nonnull) UIColor *tintColor;\n\n@end\n\n@implementation SDImageTintTransformer\n\n+ (instancetype)transformerWithColor:(UIColor *)tintColor {\n    SDImageTintTransformer *transformer = [SDImageTintTransformer new];\n    transformer.tintColor = tintColor;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageTintTransformer(%@)\", self.tintColor.sd_hexString];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_tintedImageWithColor:self.tintColor];\n}\n\n@end\n\n#pragma mark - Image Effect\n\n@interface SDImageBlurTransformer ()\n\n@property (nonatomic, assign) CGFloat blurRadius;\n\n@end\n\n@implementation SDImageBlurTransformer\n\n+ (instancetype)transformerWithRadius:(CGFloat)blurRadius {\n    SDImageBlurTransformer *transformer = [SDImageBlurTransformer new];\n    transformer.blurRadius = blurRadius;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageBlurTransformer(%f)\", self.blurRadius];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_blurredImageWithRadius:self.blurRadius];\n}\n\n@end\n\n#if SD_UIKIT || SD_MAC\n@interface SDImageFilterTransformer ()\n\n@property (nonatomic, strong, nonnull) CIFilter *filter;\n\n@end\n\n@implementation SDImageFilterTransformer\n\n+ (instancetype)transformerWithFilter:(CIFilter *)filter {\n    SDImageFilterTransformer *transformer = [SDImageFilterTransformer new];\n    transformer.filter = filter;\n    \n    return transformer;\n}\n\n- (NSString *)transformerKey {\n    return [NSString stringWithFormat:@\"SDImageFilterTransformer(%@)\", self.filter.name];\n}\n\n- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {\n    if (!image) {\n        return nil;\n    }\n    return [image sd_filteredImageWithFilter:self.filter];\n}\n\n@end\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n@class SDImageCacheConfig;\n/**\n A protocol to allow custom memory cache used in SDImageCache.\n */\n@protocol SDMemoryCache <NSObject>\n\n@required\n\n/**\n Create a new memory cache instance with the specify cache config. You can check `maxMemoryCost` and `maxMemoryCount` used for memory cache.\n\n @param config The cache config to be used to create the cache.\n @return The new memory cache instance.\n */\n- (nonnull instancetype)initWithConfig:(nonnull SDImageCacheConfig *)config;\n\n/**\n Returns the value associated with a given key.\n\n @param key An object identifying the value. If nil, just return nil.\n @return The value associated with key, or nil if no value is associated with key.\n */\n- (nullable id)objectForKey:(nonnull id)key;\n\n/**\n Sets the value of the specified key in the cache (0 cost).\n\n @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.\n @param key    The key with which to associate the value. If nil, this method has no effect.\n @discussion Unlike an NSMutableDictionary object, a cache does not copy the key\n objects that are put into it.\n */\n- (void)setObject:(nullable id)object forKey:(nonnull id)key;\n\n/**\n Sets the value of the specified key in the cache, and associates the key-value\n pair with the specified cost.\n\n @param object The object to store in the cache. If nil, it calls `removeObjectForKey`.\n @param key    The key with which to associate the value. If nil, this method has no effect.\n @param cost   The cost with which to associate the key-value pair.\n @discussion Unlike an NSMutableDictionary object, a cache does not copy the key\n objects that are put into it.\n */\n- (void)setObject:(nullable id)object forKey:(nonnull id)key cost:(NSUInteger)cost;\n\n/**\n Removes the value of the specified key in the cache.\n\n @param key The key identifying the value to be removed. If nil, this method has no effect.\n */\n- (void)removeObjectForKey:(nonnull id)key;\n\n/**\n Empties the cache immediately.\n */\n- (void)removeAllObjects;\n\n@end\n\n/**\n A memory cache which auto purge the cache on memory warning and support weak cache.\n */\n@interface SDMemoryCache <KeyType, ObjectType> : NSCache <KeyType, ObjectType> <SDMemoryCache>\n\n@property (nonatomic, strong, nonnull, readonly) SDImageCacheConfig *config;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDMemoryCache.h\"\n#import \"SDImageCacheConfig.h\"\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"SDInternalMacros.h\"\n\nstatic void * SDMemoryCacheContext = &SDMemoryCacheContext;\n\n@interface SDMemoryCache <KeyType, ObjectType> () {\n#if SD_UIKIT\n    SD_LOCK_DECLARE(_weakCacheLock); // a lock to keep the access to `weakCache` thread-safe\n#endif\n}\n\n@property (nonatomic, strong, nullable) SDImageCacheConfig *config;\n#if SD_UIKIT\n@property (nonatomic, strong, nonnull) NSMapTable<KeyType, ObjectType> *weakCache; // strong-weak cache\n#endif\n@end\n\n@implementation SDMemoryCache\n\n- (void)dealloc {\n    [_config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCost)) context:SDMemoryCacheContext];\n    [_config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCount)) context:SDMemoryCacheContext];\n#if SD_UIKIT\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    self.delegate = nil;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _config = [[SDImageCacheConfig alloc] init];\n        [self commonInit];\n    }\n    return self;\n}\n\n- (instancetype)initWithConfig:(SDImageCacheConfig *)config {\n    self = [super init];\n    if (self) {\n        _config = config;\n        [self commonInit];\n    }\n    return self;\n}\n\n- (void)commonInit {\n    SDImageCacheConfig *config = self.config;\n    self.totalCostLimit = config.maxMemoryCost;\n    self.countLimit = config.maxMemoryCount;\n\n    [config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCost)) options:0 context:SDMemoryCacheContext];\n    [config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCount)) options:0 context:SDMemoryCacheContext];\n\n#if SD_UIKIT\n    self.weakCache = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];\n    SD_LOCK_INIT(_weakCacheLock);\n\n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(didReceiveMemoryWarning:)\n                                                 name:UIApplicationDidReceiveMemoryWarningNotification\n                                               object:nil];\n#endif\n}\n\n// Current this seems no use on macOS (macOS use virtual memory and do not clear cache when memory warning). So we only override on iOS/tvOS platform.\n#if SD_UIKIT\n- (void)didReceiveMemoryWarning:(NSNotification *)notification {\n    // Only remove cache, but keep weak cache\n    [super removeAllObjects];\n}\n\n// `setObject:forKey:` just call this with 0 cost. Override this is enough\n- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g {\n    [super setObject:obj forKey:key cost:g];\n    if (!self.config.shouldUseWeakMemoryCache) {\n        return;\n    }\n    if (key && obj) {\n        // Store weak cache\n        SD_LOCK(_weakCacheLock);\n        [self.weakCache setObject:obj forKey:key];\n        SD_UNLOCK(_weakCacheLock);\n    }\n}\n\n- (id)objectForKey:(id)key {\n    id obj = [super objectForKey:key];\n    if (!self.config.shouldUseWeakMemoryCache) {\n        return obj;\n    }\n    if (key && !obj) {\n        // Check weak cache\n        SD_LOCK(_weakCacheLock);\n        obj = [self.weakCache objectForKey:key];\n        SD_UNLOCK(_weakCacheLock);\n        if (obj) {\n            // Sync cache\n            NSUInteger cost = 0;\n            if ([obj isKindOfClass:[UIImage class]]) {\n                cost = [(UIImage *)obj sd_memoryCost];\n            }\n            [super setObject:obj forKey:key cost:cost];\n        }\n    }\n    return obj;\n}\n\n- (void)removeObjectForKey:(id)key {\n    [super removeObjectForKey:key];\n    if (!self.config.shouldUseWeakMemoryCache) {\n        return;\n    }\n    if (key) {\n        // Remove weak cache\n        SD_LOCK(_weakCacheLock);\n        [self.weakCache removeObjectForKey:key];\n        SD_UNLOCK(_weakCacheLock);\n    }\n}\n\n- (void)removeAllObjects {\n    [super removeAllObjects];\n    if (!self.config.shouldUseWeakMemoryCache) {\n        return;\n    }\n    // Manually remove should also remove weak cache\n    SD_LOCK(_weakCacheLock);\n    [self.weakCache removeAllObjects];\n    SD_UNLOCK(_weakCacheLock);\n}\n#endif\n\n#pragma mark - KVO\n\n- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {\n    if (context == SDMemoryCacheContext) {\n        if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxMemoryCost))]) {\n            self.totalCostLimit = self.config.maxMemoryCost;\n        } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxMemoryCount))]) {\n            self.countLimit = self.config.maxMemoryCount;\n        }\n    } else {\n        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];\n    }\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\ntypedef NSString * _Nullable(^SDWebImageCacheKeyFilterBlock)(NSURL * _Nonnull url);\n\n/**\n This is the protocol for cache key filter.\n We can use a block to specify the cache key filter. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.\n */\n@protocol SDWebImageCacheKeyFilter <NSObject>\n\n- (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url;\n\n@end\n\n/**\n A cache key filter class with block.\n */\n@interface SDWebImageCacheKeyFilter : NSObject <SDWebImageCacheKeyFilter>\n\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block;\n+ (nonnull instancetype)cacheKeyFilterWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCacheKeyFilter.h\"\n\n@interface SDWebImageCacheKeyFilter ()\n\n@property (nonatomic, copy, nonnull) SDWebImageCacheKeyFilterBlock block;\n\n@end\n\n@implementation SDWebImageCacheKeyFilter\n\n- (instancetype)initWithBlock:(SDWebImageCacheKeyFilterBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)cacheKeyFilterWithBlock:(SDWebImageCacheKeyFilterBlock)block {\n    SDWebImageCacheKeyFilter *cacheKeyFilter = [[SDWebImageCacheKeyFilter alloc] initWithBlock:block];\n    return cacheKeyFilter;\n}\n\n- (NSString *)cacheKeyForURL:(NSURL *)url {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(url);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\ntypedef NSData * _Nullable(^SDWebImageCacheSerializerBlock)(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL);\n\n/**\n This is the protocol for cache serializer.\n We can use a block to specify the cache serializer. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.\n */\n@protocol SDWebImageCacheSerializer <NSObject>\n\n/// Provide the image data associated to the image and store to disk cache\n/// @param image The loaded image\n/// @param data The original loaded image data\n/// @param imageURL The image URL\n- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL;\n\n@end\n\n/**\n A cache serializer class with block.\n */\n@interface SDWebImageCacheSerializer : NSObject <SDWebImageCacheSerializer>\n\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageCacheSerializerBlock)block;\n+ (nonnull instancetype)cacheSerializerWithBlock:(nonnull SDWebImageCacheSerializerBlock)block;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCacheSerializer.h\"\n\n@interface SDWebImageCacheSerializer ()\n\n@property (nonatomic, copy, nonnull) SDWebImageCacheSerializerBlock block;\n\n@end\n\n@implementation SDWebImageCacheSerializer\n\n- (instancetype)initWithBlock:(SDWebImageCacheSerializerBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)cacheSerializerWithBlock:(SDWebImageCacheSerializerBlock)block {\n    SDWebImageCacheSerializer *cacheSerializer = [[SDWebImageCacheSerializer alloc] initWithBlock:block];\n    return cacheSerializer;\n}\n\n- (NSData *)cacheDataWithImage:(UIImage *)image originalData:(NSData *)data imageURL:(nullable NSURL *)imageURL {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(image, data, imageURL);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Jamie Pinkham\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <TargetConditionals.h>\n\n#ifdef __OBJC_GC__\n    #error SDWebImage does not support Objective-C Garbage Collection\n#endif\n\n// Seems like TARGET_OS_MAC is always defined (on all platforms).\n// To determine if we are running on macOS, use TARGET_OS_OSX in Xcode 8\n#if TARGET_OS_OSX\n    #define SD_MAC 1\n#else\n    #define SD_MAC 0\n#endif\n\n// iOS and tvOS are very similar, UIKit exists on both platforms\n// Note: watchOS also has UIKit, but it's very limited\n#if TARGET_OS_IOS || TARGET_OS_TV\n    #define SD_UIKIT 1\n#else\n    #define SD_UIKIT 0\n#endif\n\n#if TARGET_OS_IOS\n    #define SD_IOS 1\n#else\n    #define SD_IOS 0\n#endif\n\n#if TARGET_OS_TV\n    #define SD_TV 1\n#else\n    #define SD_TV 0\n#endif\n\n#if TARGET_OS_WATCH\n    #define SD_WATCH 1\n#else\n    #define SD_WATCH 0\n#endif\n\n\n#if SD_MAC\n    #import <AppKit/AppKit.h>\n    #ifndef UIImage\n        #define UIImage NSImage\n    #endif\n    #ifndef UIImageView\n        #define UIImageView NSImageView\n    #endif\n    #ifndef UIView\n        #define UIView NSView\n    #endif\n    #ifndef UIColor\n        #define UIColor NSColor\n    #endif\n#else\n    #if SD_UIKIT\n        #import <UIKit/UIKit.h>\n    #endif\n    #if SD_WATCH\n        #import <WatchKit/WatchKit.h>\n        #ifndef UIView\n            #define UIView WKInterfaceObject\n        #endif\n        #ifndef UIImageView\n            #define UIImageView WKInterfaceImage\n        #endif\n    #endif\n#endif\n\n#ifndef NS_ENUM\n#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type\n#endif\n\n#ifndef NS_OPTIONS\n#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type\n#endif\n\n#ifndef dispatch_main_async_safe\n#define dispatch_main_async_safe(block)\\\n    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\\\n        block();\\\n    } else {\\\n        dispatch_async(dispatch_get_main_queue(), block);\\\n    }\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if !__has_feature(objc_arc)\n    #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag\n#endif\n\n#if !OS_OBJECT_USE_OBJC\n    #error SDWebImage need ARC for dispatch object\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\ntypedef void(^SDWebImageNoParamsBlock)(void);\ntypedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;\ntypedef NSDictionary<SDWebImageContextOption, id> SDWebImageContext;\ntypedef NSMutableDictionary<SDWebImageContextOption, id> SDWebImageMutableContext;\n\n#pragma mark - Image scale\n\n/**\n Return the image scale factor for the specify key, supports file name and url key.\n This is the built-in way to check the scale factor when we have no context about it. Because scale factor is not stored in image data (It's typically from filename).\n However, you can also provide custom scale factor as well, see `SDWebImageContextImageScaleFactor`.\n\n @param key The image cache key\n @return The scale factor for image\n */\nFOUNDATION_EXPORT CGFloat SDImageScaleFactorForKey(NSString * _Nullable key);\n\n/**\n Scale the image with the scale factor for the specify key. If no need to scale, return the original image.\n This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+Metadata.h`.\n @note This is actually a convenience function, which firstly call `SDImageScaleFactorForKey` and then call `SDScaledImageForScaleFactor`, kept for backward compatibility.\n\n @param key The image cache key\n @param image The image\n @return The scaled image\n */\nFOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image);\n\n/**\n Scale the image with the scale factor. If no need to scale, return the original image.\n This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+Metadata.h`.\n \n @param scale The image scale factor\n @param image The image\n @return The scaled image\n */\nFOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image);\n\n#pragma mark - WebCache Options\n\n/// WebCache options\ntypedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {\n    /**\n     * By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying.\n     * This flag disable this blacklisting.\n     */\n    SDWebImageRetryFailed = 1 << 0,\n    \n    /**\n     * By default, image downloads are started during UI interactions, this flags disable this feature,\n     * leading to delayed download on UIScrollView deceleration for instance.\n     */\n    SDWebImageLowPriority = 1 << 1,\n    \n    /**\n     * This flag enables progressive download, the image is displayed progressively during download as a browser would do.\n     * By default, the image is only displayed once completely downloaded.\n     */\n    SDWebImageProgressiveLoad = 1 << 2,\n    \n    /**\n     * Even if the image is cached, respect the HTTP response cache control, and refresh the image from remote location if needed.\n     * The disk caching will be handled by NSURLCache instead of SDWebImage leading to slight performance degradation.\n     * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics.\n     * If a cached image is refreshed, the completion block is called once with the cached image and again with the final image.\n     *\n     * Use this flag only if you can't make your URLs static with embedded cache busting parameter.\n     */\n    SDWebImageRefreshCached = 1 << 3,\n    \n    /**\n     * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for\n     * extra time in background to let the request finish. If the background task expires the operation will be cancelled.\n     */\n    SDWebImageContinueInBackground = 1 << 4,\n    \n    /**\n     * Handles cookies stored in NSHTTPCookieStore by setting\n     * NSMutableURLRequest.HTTPShouldHandleCookies = YES;\n     */\n    SDWebImageHandleCookies = 1 << 5,\n    \n    /**\n     * Enable to allow untrusted SSL certificates.\n     * Useful for testing purposes. Use with caution in production.\n     */\n    SDWebImageAllowInvalidSSLCertificates = 1 << 6,\n    \n    /**\n     * By default, images are loaded in the order in which they were queued. This flag moves them to\n     * the front of the queue.\n     */\n    SDWebImageHighPriority = 1 << 7,\n    \n    /**\n     * By default, placeholder images are loaded while the image is loading. This flag will delay the loading\n     * of the placeholder image until after the image has finished loading.\n     */\n    SDWebImageDelayPlaceholder = 1 << 8,\n    \n    /**\n     * We usually don't apply transform on animated images as most transformers could not manage animated images.\n     * Use this flag to transform them anyway.\n     */\n    SDWebImageTransformAnimatedImage = 1 << 9,\n    \n    /**\n     * By default, image is added to the imageView after download. But in some cases, we want to\n     * have the hand before setting the image (apply a filter or add it with cross-fade animation for instance)\n     * Use this flag if you want to manually set the image in the completion when success\n     */\n    SDWebImageAvoidAutoSetImage = 1 << 10,\n    \n    /**\n     * By default, images are decoded respecting their original size.\n     * This flag will scale down the images to a size compatible with the constrained memory of devices.\n     * To control the limit memory bytes, check `SDImageCoderHelper.defaultScaleDownLimitBytes` (Defaults to 60MB on iOS)\n     * This will actually translate to use context option `.imageThumbnailPixelSize` from v5.5.0 (Defaults to (3966, 3966) on iOS). Previously does not.\n     * This flags effect the progressive and animated images as well from v5.5.0. Previously does not.\n     * @note If you need detail controls, it's better to use context option `imageThumbnailPixelSize` and `imagePreserveAspectRatio` instead.\n     */\n    SDWebImageScaleDownLargeImages = 1 << 11,\n    \n    /**\n     * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDWebImageQueryMemoryDataSync`\n     */\n    SDWebImageQueryMemoryData = 1 << 12,\n    \n    /**\n     * By default, when you only specify `SDWebImageQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously.\n     * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing.\n     */\n    SDWebImageQueryMemoryDataSync = 1 << 13,\n    \n    /**\n     * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously.\n     * @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page.\n     * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing.\n     */\n    SDWebImageQueryDiskDataSync = 1 << 14,\n    \n    /**\n     * By default, when the cache missed, the image is load from the loader. This flag can prevent this to load from cache only.\n     */\n    SDWebImageFromCacheOnly = 1 << 15,\n    \n    /**\n     * By default, we query the cache before the image is load from the loader. This flag can prevent this to load from loader only.\n     */\n    SDWebImageFromLoaderOnly = 1 << 16,\n    \n    /**\n     * By default, when you use `SDWebImageTransition` to do some view transition after the image load finished, this transition is only applied for image when the callback from manager is asynchronous (from network, or disk cache query)\n     * This mask can force to apply view transition for any cases, like memory cache query, or sync disk cache query.\n     */\n    SDWebImageForceTransition = 1 << 17,\n    \n    /**\n     * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.\n     * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.\n     */\n    SDWebImageAvoidDecodeImage = 1 << 18,\n    \n    /**\n     * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image.\n     */\n    SDWebImageDecodeFirstFrameOnly = 1 << 19,\n    \n    /**\n     * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. However, you can specify to preload all frames into memory to reduce CPU usage when the animated image is shared by lots of imageViews.\n     * This will actually trigger `preloadAllAnimatedImageFrames` in the background queue(Disk Cache & Download only).\n     */\n    SDWebImagePreloadAllFrames = 1 << 20,\n    \n    /**\n     * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available to produce one exactlly matching your custom class as a fallback solution.\n     * Using this option, can ensure we always callback image with your provided class. If failed to produce one, a error with code `SDWebImageErrorBadImageData` will been used.\n     * Note this options is not compatible with `SDWebImageDecodeFirstFrameOnly`, which always produce a UIImage/NSImage.\n     */\n    SDWebImageMatchAnimatedImageClass = 1 << 21,\n    \n    /**\n     * By default, when we load the image from network, the image will be written to the cache (memory and disk, controlled by your `storeCacheType` context option)\n     * This maybe an asynchronously operation and the final `SDInternalCompletionBlock` callback does not guarantee the disk cache written is finished and may cause logic error. (For example, you modify the disk data just in completion block, however, the disk cache is not ready)\n     * If you need to process with the disk cache in the completion block, you should use this option to ensure the disk cache already been written when callback.\n     * Note if you use this when using the custom cache serializer, or using the transformer, we will also wait until the output image data written is finished.\n     */\n    SDWebImageWaitStoreCache = 1 << 22,\n    \n    /**\n     * We usually don't apply transform on vector images, because vector images supports dynamically changing to any size, rasterize to a fixed size will loss details. To modify vector images, you can process the vector data at runtime (such as modifying PDF tag / SVG element).\n     * Use this flag to transform them anyway.\n     */\n    SDWebImageTransformVectorImage = 1 << 23\n};\n\n\n#pragma mark - Context Options\n\n/**\n A String to be used as the operation key for view category to store the image load operation. This is used for view instance which supports different image loading process. If nil, will use the class name as operation key. (NSString *)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextSetImageOperationKey;\n\n/**\n A SDWebImageManager instance to control the image download and cache process using in UIImageView+WebCache category and likes. If not provided, use the shared manager (SDWebImageManager *)\n @deprecated Deprecated in the future. This context options can be replaced by other context option control like `.imageCache`, `.imageLoader`, `.imageTransformer` (See below), which already matches all the properties in SDWebImageManager.\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCustomManager API_DEPRECATED(\"Use individual context option like .imageCache, .imageLoader and .imageTransformer instead\", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));\n\n/**\n A id<SDImageCache> instance which conforms to `SDImageCache` protocol. It's used to override the image manager's cache during the image loading pipeline.\n In other word, if you just want to specify a custom cache during image loading, you don't need to re-create a dummy SDWebImageManager instance with the cache. If not provided, use the image manager's cache (id<SDImageCache>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageCache;\n\n/**\n A id<SDImageLoader> instance which conforms to `SDImageLoader` protocol. It's used to override the image manager's loader during the image loading pipeline.\n In other word, if you just want to specify a custom loader during image loading, you don't need to re-create a dummy SDWebImageManager instance with the loader. If not provided, use the image manager's cache (id<SDImageLoader>)\n*/\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageLoader;\n\n/**\n A id<SDImageCoder> instance which conforms to `SDImageCoder` protocol. It's used to override the default image coder for image decoding(including progressive) and encoding during the image loading process.\n If you use this context option, we will not always use `SDImageCodersManager.shared` to loop through all registered coders and find the suitable one. Instead, we will arbitrarily use the exact provided coder without extra checking (We may not call `canDecodeFromData:`).\n @note This is only useful for cases which you can ensure the loading url matches your coder, or you find it's too hard to write a common coder which can used for generic usage. This will bind the loading url with the coder logic, which is not always a good design, but possible. (id<SDImageCache>)\n*/\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageCoder;\n\n/**\n A id<SDImageTransformer> instance which conforms `SDImageTransformer` protocol. It's used for image transform after the image load finished and store the transformed image to cache. If you provide one, it will ignore the `transformer` in manager and use provided one instead. If you pass NSNull, the transformer feature will be disabled. (id<SDImageTransformer>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageTransformer;\n\n/**\n A CGFloat raw value which specify the image scale factor. The number should be greater than or equal to 1.0. If not provide or the number is invalid, we will use the cache key to specify the scale factor. (NSNumber)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageScaleFactor;\n\n/**\n A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format).\n Defaults to YES. (NSNumber)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImagePreserveAspectRatio;\n\n/**\n A CGSize raw value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.imagePreserveAspectRatio`) the value size.\n @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.\n Defaults to CGSizeZero, which means no thumbnail generation at all. (NSValue)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageThumbnailPixelSize;\n\n/**\n A SDImageCacheType raw value which specify the source of cache to query. Specify `SDImageCacheTypeDisk` to query from disk cache only; `SDImageCacheTypeMemory` to query from memory only. And `SDImageCacheTypeAll` to query from both memory cache and disk cache. Specify `SDImageCacheTypeNone` is invalid and totally ignore the cache query.\n If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextQueryCacheType;\n\n/**\n A SDImageCacheType raw value which specify the store cache type when the image has just been downloaded and will be stored to the cache. Specify `SDImageCacheTypeNone` to disable cache storage; `SDImageCacheTypeDisk` to store in disk cache only; `SDImageCacheTypeMemory` to store in memory only. And `SDImageCacheTypeAll` to store in both memory cache and disk cache.\n If you use image transformer feature, this actually apply for the transformed image, but not the original image itself. Use `SDWebImageContextOriginalStoreCacheType` if you want to control the original image's store cache type at the same time.\n If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextStoreCacheType;\n\n/**\n The same behavior like `SDWebImageContextQueryCacheType`, but control the query cache type for the original image when you use image transformer feature. This allows the detail control of cache query for these two images. For example, if you want to query the transformed image from both memory/disk cache, query the original image from disk cache only, use `[.queryCacheType : .all, .originalQueryCacheType : .disk]`\n If not provide or the value is invalid, we will use `SDImageCacheTypeDisk`, which query the original full image data from disk cache after transformed image cache miss. This is suitable for most common cases to avoid re-downloading the full data for different transform variants. (NSNumber)\n @note Which means, if you set this value to not be `.none`, we will query the original image from cache, then do transform with transformer, instead of actual downloading, which can save bandwidth usage.\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalQueryCacheType;\n\n/**\n The same behavior like `SDWebImageContextStoreCacheType`, but control the store cache type for the original image when you use image transformer feature. This allows the detail control of cache storage for these two images. For example, if you want to store the transformed image into both memory/disk cache, store the original image into disk cache only, use `[.storeCacheType : .all, .originalStoreCacheType : .disk]`\n If not provide or the value is invalid, we will use `SDImageCacheTypeDisk`, which store the original full image data into disk cache after storing the transformed image. This is suitable for most common cases to avoid re-downloading the full data for different transform variants. (NSNumber)\n @note This only store the original image, if you want to use the original image without downloading in next query, specify `SDWebImageContextOriginalQueryCacheType` as well.\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalStoreCacheType;\n\n/**\n A id<SDImageCache> instance which conforms to `SDImageCache` protocol. It's used to control the cache for original image when using the transformer. If you provide one, the original image (full size image) will query and write from that cache instance instead, the transformed image will query and write from the default `SDWebImageContextImageCache` instead. (id<SDImageCache>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalImageCache;\n\n/**\n A Class object which the instance is a `UIImage/NSImage` subclass and adopt `SDAnimatedImage` protocol. We will call `initWithData:scale:options:` to create the instance (or `initWithAnimatedCoder:scale:` when using progressive download) . If the instance create failed, fallback to normal `UIImage/NSImage`.\n This can be used to improve animated images rendering performance (especially memory usage on big animated images) with `SDAnimatedImageView` (Class).\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextAnimatedImageClass;\n\n/**\n A id<SDWebImageDownloaderRequestModifier> instance to modify the image download request. It's used for downloader to modify the original request from URL and options. If you provide one, it will ignore the `requestModifier` in downloader and use provided one instead. (id<SDWebImageDownloaderRequestModifier>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadRequestModifier;\n\n/**\n A id<SDWebImageDownloaderResponseModifier> instance to modify the image download response. It's used for downloader to modify the original response from URL and options.  If you provide one, it will ignore the `responseModifier` in downloader and use provided one instead. (id<SDWebImageDownloaderResponseModifier>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadResponseModifier;\n\n/**\n A id<SDWebImageContextDownloadDecryptor> instance to decrypt the image download data. This can be used for image data decryption, such as Base64 encoded image. If you provide one, it will ignore the `decryptor` in downloader and use provided one instead. (id<SDWebImageContextDownloadDecryptor>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadDecryptor;\n\n/**\n A id<SDWebImageCacheKeyFilter> instance to convert an URL into a cache key. It's used when manager need cache key to use image cache. If you provide one, it will ignore the `cacheKeyFilter` in manager and use provided one instead. (id<SDWebImageCacheKeyFilter>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCacheKeyFilter;\n\n/**\n A id<SDWebImageCacheSerializer> instance to convert the decoded image, the source downloaded data, to the actual data. It's used for manager to store image to the disk cache. If you provide one, it will ignore the `cacheSerializer` in manager and use provided one instead. (id<SDWebImageCacheSerializer>)\n */\nFOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCacheSerializer;\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageDefine.h\"\n#import \"UIImage+Metadata.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDAssociatedObject.h\"\n\n#pragma mark - Image scale\n\nstatic inline NSArray<NSNumber *> * _Nonnull SDImageScaleFactors() {\n    return @[@2, @3];\n}\n\ninline CGFloat SDImageScaleFactorForKey(NSString * _Nullable key) {\n    CGFloat scale = 1;\n    if (!key) {\n        return scale;\n    }\n    // Check if target OS support scale\n#if SD_WATCH\n    if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)])\n#elif SD_UIKIT\n    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])\n#elif SD_MAC\n    if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)])\n#endif\n    {\n        // a@2x.png -> 8\n        if (key.length >= 8) {\n            // Fast check\n            BOOL isURL = [key hasPrefix:@\"http://\"] || [key hasPrefix:@\"https://\"];\n            for (NSNumber *scaleFactor in SDImageScaleFactors()) {\n                // @2x. for file name and normal url\n                NSString *fileScale = [NSString stringWithFormat:@\"@%@x.\", scaleFactor];\n                if ([key containsString:fileScale]) {\n                    scale = scaleFactor.doubleValue;\n                    return scale;\n                }\n                if (isURL) {\n                    // %402x. for url encode\n                    NSString *urlScale = [NSString stringWithFormat:@\"%%40%@x.\", scaleFactor];\n                    if ([key containsString:urlScale]) {\n                        scale = scaleFactor.doubleValue;\n                        return scale;\n                    }\n                }\n            }\n        }\n    }\n    return scale;\n}\n\ninline UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {\n    if (!image) {\n        return nil;\n    }\n    CGFloat scale = SDImageScaleFactorForKey(key);\n    return SDScaledImageForScaleFactor(scale, image);\n}\n\ninline UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image) {\n    if (!image) {\n        return nil;\n    }\n    if (scale <= 1) {\n        return image;\n    }\n    if (scale == image.scale) {\n        return image;\n    }\n    UIImage *scaledImage;\n    if (image.sd_isAnimated) {\n        UIImage *animatedImage;\n#if SD_UIKIT || SD_WATCH\n        // `UIAnimatedImage` images share the same size and scale.\n        NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];\n        \n        for (UIImage *tempImage in image.images) {\n            UIImage *tempScaledImage = [[UIImage alloc] initWithCGImage:tempImage.CGImage scale:scale orientation:tempImage.imageOrientation];\n            [scaledImages addObject:tempScaledImage];\n        }\n        \n        animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];\n        animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;\n#else\n        // Animated GIF for `NSImage` need to grab `NSBitmapImageRep`;\n        NSRect imageRect = NSMakeRect(0, 0, image.size.width, image.size.height);\n        NSImageRep *imageRep = [image bestRepresentationForRect:imageRect context:nil hints:nil];\n        NSBitmapImageRep *bitmapImageRep;\n        if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {\n            bitmapImageRep = (NSBitmapImageRep *)imageRep;\n        }\n        if (bitmapImageRep) {\n            NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale);\n            animatedImage = [[NSImage alloc] initWithSize:size];\n            bitmapImageRep.size = size;\n            [animatedImage addRepresentation:bitmapImageRep];\n        }\n#endif\n        scaledImage = animatedImage;\n    } else {\n#if SD_UIKIT || SD_WATCH\n        scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];\n#else\n        scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:kCGImagePropertyOrientationUp];\n#endif\n    }\n    SDImageCopyAssociatedObject(image, scaledImage);\n    \n    return scaledImage;\n}\n\n#pragma mark - Context option\n\nSDWebImageContextOption const SDWebImageContextSetImageOperationKey = @\"setImageOperationKey\";\nSDWebImageContextOption const SDWebImageContextCustomManager = @\"customManager\";\nSDWebImageContextOption const SDWebImageContextImageCache = @\"imageCache\";\nSDWebImageContextOption const SDWebImageContextImageLoader = @\"imageLoader\";\nSDWebImageContextOption const SDWebImageContextImageCoder = @\"imageCoder\";\nSDWebImageContextOption const SDWebImageContextImageTransformer = @\"imageTransformer\";\nSDWebImageContextOption const SDWebImageContextImageScaleFactor = @\"imageScaleFactor\";\nSDWebImageContextOption const SDWebImageContextImagePreserveAspectRatio = @\"imagePreserveAspectRatio\";\nSDWebImageContextOption const SDWebImageContextImageThumbnailPixelSize = @\"imageThumbnailPixelSize\";\nSDWebImageContextOption const SDWebImageContextQueryCacheType = @\"queryCacheType\";\nSDWebImageContextOption const SDWebImageContextStoreCacheType = @\"storeCacheType\";\nSDWebImageContextOption const SDWebImageContextOriginalQueryCacheType = @\"originalQueryCacheType\";\nSDWebImageContextOption const SDWebImageContextOriginalStoreCacheType = @\"originalStoreCacheType\";\nSDWebImageContextOption const SDWebImageContextOriginalImageCache = @\"originalImageCache\";\nSDWebImageContextOption const SDWebImageContextAnimatedImageClass = @\"animatedImageClass\";\nSDWebImageContextOption const SDWebImageContextDownloadRequestModifier = @\"downloadRequestModifier\";\nSDWebImageContextOption const SDWebImageContextDownloadResponseModifier = @\"downloadResponseModifier\";\nSDWebImageContextOption const SDWebImageContextDownloadDecryptor = @\"downloadDecryptor\";\nSDWebImageContextOption const SDWebImageContextCacheKeyFilter = @\"cacheKeyFilter\";\nSDWebImageContextOption const SDWebImageContextCacheSerializer = @\"cacheSerializer\";\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n#import \"SDWebImageOperation.h\"\n#import \"SDWebImageDownloaderConfig.h\"\n#import \"SDWebImageDownloaderRequestModifier.h\"\n#import \"SDWebImageDownloaderResponseModifier.h\"\n#import \"SDWebImageDownloaderDecryptor.h\"\n#import \"SDImageLoader.h\"\n\n/// Downloader options\ntypedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {\n    /**\n     * Put the download in the low queue priority and task priority.\n     */\n    SDWebImageDownloaderLowPriority = 1 << 0,\n    \n    /**\n     * This flag enables progressive download, the image is displayed progressively during download as a browser would do.\n     */\n    SDWebImageDownloaderProgressiveLoad = 1 << 1,\n\n    /**\n     * By default, request prevent the use of NSURLCache. With this flag, NSURLCache\n     * is used with default policies.\n     */\n    SDWebImageDownloaderUseNSURLCache = 1 << 2,\n\n    /**\n     * Call completion block with nil image/imageData if the image was read from NSURLCache\n     * And the error code is `SDWebImageErrorCacheNotModified`\n     * This flag should be combined with `SDWebImageDownloaderUseNSURLCache`.\n     */\n    SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,\n    \n    /**\n     * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for\n     * extra time in background to let the request finish. If the background task expires the operation will be cancelled.\n     */\n    SDWebImageDownloaderContinueInBackground = 1 << 4,\n\n    /**\n     * Handles cookies stored in NSHTTPCookieStore by setting \n     * NSMutableURLRequest.HTTPShouldHandleCookies = YES;\n     */\n    SDWebImageDownloaderHandleCookies = 1 << 5,\n\n    /**\n     * Enable to allow untrusted SSL certificates.\n     * Useful for testing purposes. Use with caution in production.\n     */\n    SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,\n\n    /**\n     * Put the download in the high queue priority and task priority.\n     */\n    SDWebImageDownloaderHighPriority = 1 << 7,\n    \n    /**\n     * By default, images are decoded respecting their original size. On iOS, this flag will scale down the\n     * images to a size compatible with the constrained memory of devices.\n     * This flag take no effect if `SDWebImageDownloaderAvoidDecodeImage` is set. And it will be ignored if `SDWebImageDownloaderProgressiveLoad` is set.\n     */\n    SDWebImageDownloaderScaleDownLargeImages = 1 << 8,\n    \n    /**\n     * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.\n     * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.\n     */\n    SDWebImageDownloaderAvoidDecodeImage = 1 << 9,\n    \n    /**\n     * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image.\n     */\n    SDWebImageDownloaderDecodeFirstFrameOnly = 1 << 10,\n    \n    /**\n     * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from network\n     */\n    SDWebImageDownloaderPreloadAllFrames = 1 << 11,\n    \n    /**\n     * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution.\n     * Using this option, can ensure we always produce image with your provided class. If failed, a error with code `SDWebImageErrorBadImageData` will been used.\n     * Note this options is not compatible with `SDWebImageDownloaderDecodeFirstFrameOnly`, which always produce a UIImage/NSImage.\n     */\n    SDWebImageDownloaderMatchAnimatedImageClass = 1 << 12,\n};\n\nFOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadStartNotification;\nFOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadReceiveResponseNotification;\nFOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadStopNotification;\nFOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadFinishNotification;\n\ntypedef SDImageLoaderProgressBlock SDWebImageDownloaderProgressBlock;\ntypedef SDImageLoaderCompletedBlock SDWebImageDownloaderCompletedBlock;\n\n/**\n *  A token associated with each download. Can be used to cancel a download\n */\n@interface SDWebImageDownloadToken : NSObject <SDWebImageOperation>\n\n/**\n Cancel the current download.\n */\n- (void)cancel;\n\n/**\n The download's URL.\n */\n@property (nonatomic, strong, nullable, readonly) NSURL *url;\n\n/**\n The download's request.\n */\n@property (nonatomic, strong, nullable, readonly) NSURLRequest *request;\n\n/**\n The download's response.\n */\n@property (nonatomic, strong, nullable, readonly) NSURLResponse *response;\n\n/**\n The download's metrics. This will be nil if download operation does not support metrics.\n */\n@property (nonatomic, strong, nullable, readonly) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));\n\n@end\n\n\n/**\n * Asynchronous downloader dedicated and optimized for image loading.\n */\n@interface SDWebImageDownloader : NSObject\n\n/**\n * Downloader Config object - storing all kind of settings.\n * Most config properties support dynamic changes during download, except something like `sessionConfiguration`, see `SDWebImageDownloaderConfig` for more detail.\n */\n@property (nonatomic, copy, readonly, nonnull) SDWebImageDownloaderConfig *config;\n\n/**\n * Set the request modifier to modify the original download request before image load.\n * This request modifier method will be called for each downloading image request. Return the original request means no modification. Return nil will cancel the download request.\n * Defaults to nil, means does not modify the original download request.\n * @note If you want to modify single request, consider using `SDWebImageContextDownloadRequestModifier` context option.\n */\n@property (nonatomic, strong, nullable) id<SDWebImageDownloaderRequestModifier> requestModifier;\n\n/**\n * Set the response modifier to modify the original download response during image load.\n * This request modifier method will be called for each downloading image response. Return the original response means no modification. Return nil will mark current download as cancelled.\n * Defaults to nil, means does not modify the original download response.\n * @note If you want to modify single response, consider using `SDWebImageContextDownloadResponseModifier` context option.\n */\n@property (nonatomic, strong, nullable) id<SDWebImageDownloaderResponseModifier> responseModifier;\n\n/**\n * Set the decryptor to decrypt the original download data before image decoding. This can be used for encrypted image data, like Base64.\n * This decryptor method will be called for each downloading image data. Return the original data means no modification. Return nil will mark this download failed.\n * Defaults to nil, means does not modify the original download data.\n * @note When using decryptor, progressive decoding will be disabled, to avoid data corrupt issue.\n * @note If you want to decrypt single download data, consider using `SDWebImageContextDownloadDecryptor` context option.\n */\n@property (nonatomic, strong, nullable) id<SDWebImageDownloaderDecryptor> decryptor;\n\n/**\n * The configuration in use by the internal NSURLSession. If you want to provide a custom sessionConfiguration, use `SDWebImageDownloaderConfig.sessionConfiguration` and create a new downloader instance.\n @note This is immutable according to NSURLSession's documentation. Mutating this object directly has no effect.\n */\n@property (nonatomic, readonly, nonnull) NSURLSessionConfiguration *sessionConfiguration;\n\n/**\n * Gets/Sets the download queue suspension state.\n */\n@property (nonatomic, assign, getter=isSuspended) BOOL suspended;\n\n/**\n * Shows the current amount of downloads that still need to be downloaded\n */\n@property (nonatomic, assign, readonly) NSUInteger currentDownloadCount;\n\n/**\n *  Returns the global shared downloader instance. Which use the `SDWebImageDownloaderConfig.defaultDownloaderConfig` config.\n */\n@property (nonatomic, class, readonly, nonnull) SDWebImageDownloader *sharedDownloader;\n\n/**\n Creates an instance of a downloader with specified downloader config.\n You can specify session configuration, timeout or operation class through downloader config.\n\n @param config The downloader config. If you specify nil, the `defaultDownloaderConfig` will be used.\n @return new instance of downloader class\n */\n- (nonnull instancetype)initWithConfig:(nullable SDWebImageDownloaderConfig *)config NS_DESIGNATED_INITIALIZER;\n\n/**\n * Set a value for a HTTP header to be appended to each download HTTP request.\n *\n * @param value The value for the header field. Use `nil` value to remove the header field.\n * @param field The name of the header field to set.\n */\n- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field;\n\n/**\n * Returns the value of the specified HTTP header field.\n *\n * @return The value associated with the header field field, or `nil` if there is no corresponding header field.\n */\n- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field;\n\n/**\n * Creates a SDWebImageDownloader async downloader instance with a given URL\n *\n * The delegate will be informed when the image is finish downloaded or an error has happen.\n *\n * @see SDWebImageDownloaderDelegate\n *\n * @param url            The URL to the image to download\n * @param completedBlock A block called once the download is completed.\n *                       If the download succeeded, the image parameter is set, in case of error,\n *                       error parameter is set with the error. The last parameter is always YES\n *                       if SDWebImageDownloaderProgressiveDownload isn't use. With the\n *                       SDWebImageDownloaderProgressiveDownload option, this block is called\n *                       repeatedly with the partial image object and the finished argument set to NO\n *                       before to be called a last time with the full image and finished argument\n *                       set to YES. In case of error, the finished argument is always YES.\n *\n * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation\n */\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url\n                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;\n\n/**\n * Creates a SDWebImageDownloader async downloader instance with a given URL\n *\n * The delegate will be informed when the image is finish downloaded or an error has happen.\n *\n * @see SDWebImageDownloaderDelegate\n *\n * @param url            The URL to the image to download\n * @param options        The options to be used for this download\n * @param progressBlock  A block called repeatedly while the image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called once the download is completed.\n *                       If the download succeeded, the image parameter is set, in case of error,\n *                       error parameter is set with the error. The last parameter is always YES\n *                       if SDWebImageDownloaderProgressiveLoad isn't use. With the\n *                       SDWebImageDownloaderProgressiveLoad option, this block is called\n *                       repeatedly with the partial image object and the finished argument set to NO\n *                       before to be called a last time with the full image and finished argument\n *                       set to YES. In case of error, the finished argument is always YES.\n *\n * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation\n */\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url\n                                                   options:(SDWebImageDownloaderOptions)options\n                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;\n\n/**\n * Creates a SDWebImageDownloader async downloader instance with a given URL\n *\n * The delegate will be informed when the image is finish downloaded or an error has happen.\n *\n * @see SDWebImageDownloaderDelegate\n *\n * @param url            The URL to the image to download\n * @param options        The options to be used for this download\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called repeatedly while the image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called once the download is completed.\n *\n * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation\n */\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url\n                                                   options:(SDWebImageDownloaderOptions)options\n                                                   context:(nullable SDWebImageContext *)context\n                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;\n\n/**\n * Cancels all download operations in the queue\n */\n- (void)cancelAllDownloads;\n\n/**\n * Invalidates the managed session, optionally canceling pending operations.\n * @note If you use custom downloader instead of the shared downloader, you need call this method when you do not use it to avoid memory leak\n * @param cancelPendingOperations Whether or not to cancel pending operations.\n * @note Calling this method on the shared downloader has no effect.\n */\n- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations;\n\n@end\n\n\n/**\n SDWebImageDownloader is the built-in image loader conform to `SDImageLoader`. Which provide the HTTP/HTTPS/FTP download, or local file URL using NSURLSession.\n However, this downloader class itself also support customization for advanced users. You can specify `operationClass` in download config to custom download operation, See `SDWebImageDownloaderOperation`.\n If you want to provide some image loader which beyond network or local file, consider to create your own custom class conform to `SDImageLoader`.\n */\n@interface SDWebImageDownloader (SDImageLoader) <SDImageLoader>\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageDownloader.h\"\n#import \"SDWebImageDownloaderConfig.h\"\n#import \"SDWebImageDownloaderOperation.h\"\n#import \"SDWebImageError.h\"\n#import \"SDInternalMacros.h\"\n\nNSNotificationName const SDWebImageDownloadStartNotification = @\"SDWebImageDownloadStartNotification\";\nNSNotificationName const SDWebImageDownloadReceiveResponseNotification = @\"SDWebImageDownloadReceiveResponseNotification\";\nNSNotificationName const SDWebImageDownloadStopNotification = @\"SDWebImageDownloadStopNotification\";\nNSNotificationName const SDWebImageDownloadFinishNotification = @\"SDWebImageDownloadFinishNotification\";\n\nstatic void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;\n\n@interface SDWebImageDownloadToken ()\n\n@property (nonatomic, strong, nullable, readwrite) NSURL *url;\n@property (nonatomic, strong, nullable, readwrite) NSURLRequest *request;\n@property (nonatomic, strong, nullable, readwrite) NSURLResponse *response;\n@property (nonatomic, strong, nullable, readwrite) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));\n@property (nonatomic, weak, nullable, readwrite) id downloadOperationCancelToken;\n@property (nonatomic, weak, nullable) NSOperation<SDWebImageDownloaderOperation> *downloadOperation;\n@property (nonatomic, assign, getter=isCancelled) BOOL cancelled;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n+ (nonnull instancetype)new  NS_UNAVAILABLE;\n- (nonnull instancetype)initWithDownloadOperation:(nullable NSOperation<SDWebImageDownloaderOperation> *)downloadOperation;\n\n@end\n\n@interface SDWebImageDownloader () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>\n\n@property (strong, nonatomic, nonnull) NSOperationQueue *downloadQueue;\n@property (strong, nonatomic, nonnull) NSMutableDictionary<NSURL *, NSOperation<SDWebImageDownloaderOperation> *> *URLOperations;\n@property (strong, nonatomic, nullable) NSMutableDictionary<NSString *, NSString *> *HTTPHeaders;\n\n// The session in which data tasks will run\n@property (strong, nonatomic) NSURLSession *session;\n\n@end\n\n@implementation SDWebImageDownloader {\n    SD_LOCK_DECLARE(_HTTPHeadersLock); // A lock to keep the access to `HTTPHeaders` thread-safe\n    SD_LOCK_DECLARE(_operationsLock); // A lock to keep the access to `URLOperations` thread-safe\n}\n\n+ (void)initialize {\n    // Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator )\n    // To use it, just add #import \"SDNetworkActivityIndicator.h\" in addition to the SDWebImage import\n    if (NSClassFromString(@\"SDNetworkActivityIndicator\")) {\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        id activityIndicator = [NSClassFromString(@\"SDNetworkActivityIndicator\") performSelector:NSSelectorFromString(@\"sharedActivityIndicator\")];\n#pragma clang diagnostic pop\n\n        // Remove observer in case it was previously added.\n        [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStartNotification object:nil];\n        [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStopNotification object:nil];\n\n        [[NSNotificationCenter defaultCenter] addObserver:activityIndicator\n                                                 selector:NSSelectorFromString(@\"startActivity\")\n                                                     name:SDWebImageDownloadStartNotification object:nil];\n        [[NSNotificationCenter defaultCenter] addObserver:activityIndicator\n                                                 selector:NSSelectorFromString(@\"stopActivity\")\n                                                     name:SDWebImageDownloadStopNotification object:nil];\n    }\n}\n\n+ (nonnull instancetype)sharedDownloader {\n    static dispatch_once_t once;\n    static id instance;\n    dispatch_once(&once, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n- (nonnull instancetype)init {\n    return [self initWithConfig:SDWebImageDownloaderConfig.defaultDownloaderConfig];\n}\n\n- (instancetype)initWithConfig:(SDWebImageDownloaderConfig *)config {\n    self = [super init];\n    if (self) {\n        if (!config) {\n            config = SDWebImageDownloaderConfig.defaultDownloaderConfig;\n        }\n        _config = [config copy];\n        [_config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) options:0 context:SDWebImageDownloaderContext];\n        _downloadQueue = [NSOperationQueue new];\n        _downloadQueue.maxConcurrentOperationCount = _config.maxConcurrentDownloads;\n        _downloadQueue.name = @\"com.hackemist.SDWebImageDownloader\";\n        _URLOperations = [NSMutableDictionary new];\n        NSMutableDictionary<NSString *, NSString *> *headerDictionary = [NSMutableDictionary dictionary];\n        NSString *userAgent = nil;\n#if SD_UIKIT\n        // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43\n        userAgent = [NSString stringWithFormat:@\"%@/%@ (%@; iOS %@; Scale/%0.2f)\", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@\"CFBundleShortVersionString\"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];\n#elif SD_WATCH\n        // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43\n        userAgent = [NSString stringWithFormat:@\"%@/%@ (%@; watchOS %@; Scale/%0.2f)\", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@\"CFBundleShortVersionString\"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[WKInterfaceDevice currentDevice] model], [[WKInterfaceDevice currentDevice] systemVersion], [[WKInterfaceDevice currentDevice] screenScale]];\n#elif SD_MAC\n        userAgent = [NSString stringWithFormat:@\"%@/%@ (Mac OS X %@)\", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@\"CFBundleShortVersionString\"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]];\n#endif\n        if (userAgent) {\n            if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {\n                NSMutableString *mutableUserAgent = [userAgent mutableCopy];\n                if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@\"Any-Latin; Latin-ASCII; [:^ASCII:] Remove\", false)) {\n                    userAgent = mutableUserAgent;\n                }\n            }\n            headerDictionary[@\"User-Agent\"] = userAgent;\n        }\n        headerDictionary[@\"Accept\"] = @\"image/*,*/*;q=0.8\";\n        _HTTPHeaders = headerDictionary;\n        SD_LOCK_INIT(_HTTPHeadersLock);\n        SD_LOCK_INIT(_operationsLock);\n        NSURLSessionConfiguration *sessionConfiguration = _config.sessionConfiguration;\n        if (!sessionConfiguration) {\n            sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];\n        }\n        /**\n         *  Create the session for this task\n         *  We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate\n         *  method calls and completion handler calls.\n         */\n        _session = [NSURLSession sessionWithConfiguration:sessionConfiguration\n                                                 delegate:self\n                                            delegateQueue:nil];\n    }\n    return self;\n}\n\n- (void)dealloc {\n    [self.downloadQueue cancelAllOperations];\n    [self.config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) context:SDWebImageDownloaderContext];\n    \n    // Invalide the URLSession after all operations been cancelled\n    [self.session invalidateAndCancel];\n    self.session = nil;\n}\n\n- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations {\n    if (self == [SDWebImageDownloader sharedDownloader]) {\n        return;\n    }\n    if (cancelPendingOperations) {\n        [self.session invalidateAndCancel];\n    } else {\n        [self.session finishTasksAndInvalidate];\n    }\n}\n\n- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field {\n    if (!field) {\n        return;\n    }\n    SD_LOCK(_HTTPHeadersLock);\n    [self.HTTPHeaders setValue:value forKey:field];\n    SD_UNLOCK(_HTTPHeadersLock);\n}\n\n- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field {\n    if (!field) {\n        return nil;\n    }\n    SD_LOCK(_HTTPHeadersLock);\n    NSString *value = [self.HTTPHeaders objectForKey:field];\n    SD_UNLOCK(_HTTPHeadersLock);\n    return value;\n}\n\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url\n                                                 completed:(SDWebImageDownloaderCompletedBlock)completedBlock {\n    return [self downloadImageWithURL:url options:0 progress:nil completed:completedBlock];\n}\n\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url\n                                                   options:(SDWebImageDownloaderOptions)options\n                                                  progress:(SDWebImageDownloaderProgressBlock)progressBlock\n                                                 completed:(SDWebImageDownloaderCompletedBlock)completedBlock {\n    return [self downloadImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url\n                                                   options:(SDWebImageDownloaderOptions)options\n                                                   context:(nullable SDWebImageContext *)context\n                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {\n    // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data.\n    if (url == nil) {\n        if (completedBlock) {\n            NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @\"Image url is nil\"}];\n            completedBlock(nil, nil, error, YES);\n        }\n        return nil;\n    }\n    \n    SD_LOCK(_operationsLock);\n    id downloadOperationCancelToken;\n    NSOperation<SDWebImageDownloaderOperation> *operation = [self.URLOperations objectForKey:url];\n    // There is a case that the operation may be marked as finished or cancelled, but not been removed from `self.URLOperations`.\n    if (!operation || operation.isFinished || operation.isCancelled) {\n        operation = [self createDownloaderOperationWithUrl:url options:options context:context];\n        if (!operation) {\n            SD_UNLOCK(_operationsLock);\n            if (completedBlock) {\n                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @\"Downloader operation is nil\"}];\n                completedBlock(nil, nil, error, YES);\n            }\n            return nil;\n        }\n        @weakify(self);\n        operation.completionBlock = ^{\n            @strongify(self);\n            if (!self) {\n                return;\n            }\n            SD_LOCK(self->_operationsLock);\n            [self.URLOperations removeObjectForKey:url];\n            SD_UNLOCK(self->_operationsLock);\n        };\n        self.URLOperations[url] = operation;\n        // Add the handlers before submitting to operation queue, avoid the race condition that operation finished before setting handlers.\n        downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock];\n        // Add operation to operation queue only after all configuration done according to Apple's doc.\n        // `addOperation:` does not synchronously execute the `operation.completionBlock` so this will not cause deadlock.\n        [self.downloadQueue addOperation:operation];\n    } else {\n        // When we reuse the download operation to attach more callbacks, there may be thread safe issue because the getter of callbacks may in another queue (decoding queue or delegate queue)\n        // So we lock the operation here, and in `SDWebImageDownloaderOperation`, we use `@synchonzied (self)`, to ensure the thread safe between these two classes.\n        @synchronized (operation) {\n            downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock];\n        }\n        if (!operation.isExecuting) {\n            if (options & SDWebImageDownloaderHighPriority) {\n                operation.queuePriority = NSOperationQueuePriorityHigh;\n            } else if (options & SDWebImageDownloaderLowPriority) {\n                operation.queuePriority = NSOperationQueuePriorityLow;\n            } else {\n                operation.queuePriority = NSOperationQueuePriorityNormal;\n            }\n        }\n    }\n    SD_UNLOCK(_operationsLock);\n    \n    SDWebImageDownloadToken *token = [[SDWebImageDownloadToken alloc] initWithDownloadOperation:operation];\n    token.url = url;\n    token.request = operation.request;\n    token.downloadOperationCancelToken = downloadOperationCancelToken;\n    \n    return token;\n}\n\n- (nullable NSOperation<SDWebImageDownloaderOperation> *)createDownloaderOperationWithUrl:(nonnull NSURL *)url\n                                                                                  options:(SDWebImageDownloaderOptions)options\n                                                                                  context:(nullable SDWebImageContext *)context {\n    NSTimeInterval timeoutInterval = self.config.downloadTimeout;\n    if (timeoutInterval == 0.0) {\n        timeoutInterval = 15.0;\n    }\n    \n    // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise\n    NSURLRequestCachePolicy cachePolicy = options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData;\n    NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:cachePolicy timeoutInterval:timeoutInterval];\n    mutableRequest.HTTPShouldHandleCookies = SD_OPTIONS_CONTAINS(options, SDWebImageDownloaderHandleCookies);\n    mutableRequest.HTTPShouldUsePipelining = YES;\n    SD_LOCK(_HTTPHeadersLock);\n    mutableRequest.allHTTPHeaderFields = self.HTTPHeaders;\n    SD_UNLOCK(_HTTPHeadersLock);\n    \n    // Context Option\n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    \n    // Request Modifier\n    id<SDWebImageDownloaderRequestModifier> requestModifier;\n    if ([context valueForKey:SDWebImageContextDownloadRequestModifier]) {\n        requestModifier = [context valueForKey:SDWebImageContextDownloadRequestModifier];\n    } else {\n        requestModifier = self.requestModifier;\n    }\n    \n    NSURLRequest *request;\n    if (requestModifier) {\n        NSURLRequest *modifiedRequest = [requestModifier modifiedRequestWithRequest:[mutableRequest copy]];\n        // If modified request is nil, early return\n        if (!modifiedRequest) {\n            return nil;\n        } else {\n            request = [modifiedRequest copy];\n        }\n    } else {\n        request = [mutableRequest copy];\n    }\n    // Response Modifier\n    id<SDWebImageDownloaderResponseModifier> responseModifier;\n    if ([context valueForKey:SDWebImageContextDownloadResponseModifier]) {\n        responseModifier = [context valueForKey:SDWebImageContextDownloadResponseModifier];\n    } else {\n        responseModifier = self.responseModifier;\n    }\n    if (responseModifier) {\n        mutableContext[SDWebImageContextDownloadResponseModifier] = responseModifier;\n    }\n    // Decryptor\n    id<SDWebImageDownloaderDecryptor> decryptor;\n    if ([context valueForKey:SDWebImageContextDownloadDecryptor]) {\n        decryptor = [context valueForKey:SDWebImageContextDownloadDecryptor];\n    } else {\n        decryptor = self.decryptor;\n    }\n    if (decryptor) {\n        mutableContext[SDWebImageContextDownloadDecryptor] = decryptor;\n    }\n    \n    context = [mutableContext copy];\n    \n    // Operation Class\n    Class operationClass = self.config.operationClass;\n    if (operationClass && [operationClass isSubclassOfClass:[NSOperation class]] && [operationClass conformsToProtocol:@protocol(SDWebImageDownloaderOperation)]) {\n        // Custom operation class\n    } else {\n        operationClass = [SDWebImageDownloaderOperation class];\n    }\n    NSOperation<SDWebImageDownloaderOperation> *operation = [[operationClass alloc] initWithRequest:request inSession:self.session options:options context:context];\n    \n    if ([operation respondsToSelector:@selector(setCredential:)]) {\n        if (self.config.urlCredential) {\n            operation.credential = self.config.urlCredential;\n        } else if (self.config.username && self.config.password) {\n            operation.credential = [NSURLCredential credentialWithUser:self.config.username password:self.config.password persistence:NSURLCredentialPersistenceForSession];\n        }\n    }\n        \n    if ([operation respondsToSelector:@selector(setMinimumProgressInterval:)]) {\n        operation.minimumProgressInterval = MIN(MAX(self.config.minimumProgressInterval, 0), 1);\n    }\n    \n    if (options & SDWebImageDownloaderHighPriority) {\n        operation.queuePriority = NSOperationQueuePriorityHigh;\n    } else if (options & SDWebImageDownloaderLowPriority) {\n        operation.queuePriority = NSOperationQueuePriorityLow;\n    }\n    \n    if (self.config.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {\n        // Emulate LIFO execution order by systematically, each previous adding operation can dependency the new operation\n        // This can gurantee the new operation to be execulated firstly, even if when some operations finished, meanwhile you appending new operations\n        // Just make last added operation dependents new operation can not solve this problem. See test case #test15DownloaderLIFOExecutionOrder\n        for (NSOperation *pendingOperation in self.downloadQueue.operations) {\n            [pendingOperation addDependency:operation];\n        }\n    }\n    \n    return operation;\n}\n\n- (void)cancelAllDownloads {\n    [self.downloadQueue cancelAllOperations];\n}\n\n#pragma mark - Properties\n\n- (BOOL)isSuspended {\n    return self.downloadQueue.isSuspended;\n}\n\n- (void)setSuspended:(BOOL)suspended {\n    self.downloadQueue.suspended = suspended;\n}\n\n- (NSUInteger)currentDownloadCount {\n    return self.downloadQueue.operationCount;\n}\n\n- (NSURLSessionConfiguration *)sessionConfiguration {\n    return self.session.configuration;\n}\n\n#pragma mark - KVO\n\n- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {\n    if (context == SDWebImageDownloaderContext) {\n        if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxConcurrentDownloads))]) {\n            self.downloadQueue.maxConcurrentOperationCount = self.config.maxConcurrentDownloads;\n        }\n    } else {\n        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];\n    }\n}\n\n#pragma mark Helper methods\n\n- (NSOperation<SDWebImageDownloaderOperation> *)operationWithTask:(NSURLSessionTask *)task {\n    NSOperation<SDWebImageDownloaderOperation> *returnOperation = nil;\n    for (NSOperation<SDWebImageDownloaderOperation> *operation in self.downloadQueue.operations) {\n        if ([operation respondsToSelector:@selector(dataTask)]) {\n            // So we lock the operation here, and in `SDWebImageDownloaderOperation`, we use `@synchonzied (self)`, to ensure the thread safe between these two classes.\n            NSURLSessionTask *operationTask;\n            @synchronized (operation) {\n                operationTask = operation.dataTask;\n            }\n            if (operationTask.taskIdentifier == task.taskIdentifier) {\n                returnOperation = operation;\n                break;\n            }\n        }\n    }\n    return returnOperation;\n}\n\n#pragma mark NSURLSessionDataDelegate\n\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\ndidReceiveResponse:(NSURLResponse *)response\n completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {\n\n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:dataTask];\n    if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:didReceiveResponse:completionHandler:)]) {\n        [dataOperation URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler];\n    } else {\n        if (completionHandler) {\n            completionHandler(NSURLSessionResponseAllow);\n        }\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {\n\n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:dataTask];\n    if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:didReceiveData:)]) {\n        [dataOperation URLSession:session dataTask:dataTask didReceiveData:data];\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\n willCacheResponse:(NSCachedURLResponse *)proposedResponse\n completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler {\n\n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:dataTask];\n    if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:willCacheResponse:completionHandler:)]) {\n        [dataOperation URLSession:session dataTask:dataTask willCacheResponse:proposedResponse completionHandler:completionHandler];\n    } else {\n        if (completionHandler) {\n            completionHandler(proposedResponse);\n        }\n    }\n}\n\n#pragma mark NSURLSessionTaskDelegate\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {\n    \n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task];\n    if ([dataOperation respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]) {\n        [dataOperation URLSession:session task:task didCompleteWithError:error];\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {\n    \n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task];\n    if ([dataOperation respondsToSelector:@selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)]) {\n        [dataOperation URLSession:session task:task willPerformHTTPRedirection:response newRequest:request completionHandler:completionHandler];\n    } else {\n        if (completionHandler) {\n            completionHandler(request);\n        }\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {\n\n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task];\n    if ([dataOperation respondsToSelector:@selector(URLSession:task:didReceiveChallenge:completionHandler:)]) {\n        [dataOperation URLSession:session task:task didReceiveChallenge:challenge completionHandler:completionHandler];\n    } else {\n        if (completionHandler) {\n            completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);\n        }\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) {\n    \n    // Identify the operation that runs this task and pass it the delegate method\n    NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task];\n    if ([dataOperation respondsToSelector:@selector(URLSession:task:didFinishCollectingMetrics:)]) {\n        [dataOperation URLSession:session task:task didFinishCollectingMetrics:metrics];\n    }\n}\n\n@end\n\n@implementation SDWebImageDownloadToken\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:SDWebImageDownloadReceiveResponseNotification object:nil];\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:SDWebImageDownloadStopNotification object:nil];\n}\n\n- (instancetype)initWithDownloadOperation:(NSOperation<SDWebImageDownloaderOperation> *)downloadOperation {\n    self = [super init];\n    if (self) {\n        _downloadOperation = downloadOperation;\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidReceiveResponse:) name:SDWebImageDownloadReceiveResponseNotification object:downloadOperation];\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidStop:) name:SDWebImageDownloadStopNotification object:downloadOperation];\n    }\n    return self;\n}\n\n- (void)downloadDidReceiveResponse:(NSNotification *)notification {\n    NSOperation<SDWebImageDownloaderOperation> *downloadOperation = notification.object;\n    if (downloadOperation && downloadOperation == self.downloadOperation) {\n        self.response = downloadOperation.response;\n    }\n}\n\n- (void)downloadDidStop:(NSNotification *)notification {\n    NSOperation<SDWebImageDownloaderOperation> *downloadOperation = notification.object;\n    if (downloadOperation && downloadOperation == self.downloadOperation) {\n        if ([downloadOperation respondsToSelector:@selector(metrics)]) {\n            if (@available(iOS 10.0, tvOS 10.0, macOS 10.12, watchOS 3.0, *)) {\n                self.metrics = downloadOperation.metrics;\n            }\n        }\n    }\n}\n\n- (void)cancel {\n    @synchronized (self) {\n        if (self.isCancelled) {\n            return;\n        }\n        self.cancelled = YES;\n        [self.downloadOperation cancel:self.downloadOperationCancelToken];\n        self.downloadOperationCancelToken = nil;\n    }\n}\n\n@end\n\n@implementation SDWebImageDownloader (SDImageLoader)\n\n- (BOOL)canRequestImageForURL:(NSURL *)url {\n    return [self canRequestImageForURL:url options:0 context:nil];\n}\n\n- (BOOL)canRequestImageForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context {\n    if (!url) {\n        return NO;\n    }\n    // Always pass YES to let URLSession or custom download operation to determine\n    return YES;\n}\n\n- (id<SDWebImageOperation>)requestImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock {\n    UIImage *cachedImage = context[SDWebImageContextLoaderCachedImage];\n    \n    SDWebImageDownloaderOptions downloaderOptions = 0;\n    if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority;\n    if (options & SDWebImageProgressiveLoad) downloaderOptions |= SDWebImageDownloaderProgressiveLoad;\n    if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;\n    if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground;\n    if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies;\n    if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates;\n    if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority;\n    if (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages;\n    if (options & SDWebImageAvoidDecodeImage) downloaderOptions |= SDWebImageDownloaderAvoidDecodeImage;\n    if (options & SDWebImageDecodeFirstFrameOnly) downloaderOptions |= SDWebImageDownloaderDecodeFirstFrameOnly;\n    if (options & SDWebImagePreloadAllFrames) downloaderOptions |= SDWebImageDownloaderPreloadAllFrames;\n    if (options & SDWebImageMatchAnimatedImageClass) downloaderOptions |= SDWebImageDownloaderMatchAnimatedImageClass;\n    \n    if (cachedImage && options & SDWebImageRefreshCached) {\n        // force progressive off if image already cached but forced refreshing\n        downloaderOptions &= ~SDWebImageDownloaderProgressiveLoad;\n        // ignore image read from NSURLCache if image if cached but force refreshing\n        downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;\n    }\n    \n    return [self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock];\n}\n\n- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error {\n    return [self shouldBlockFailedURLWithURL:url error:error options:0 context:nil];\n}\n\n- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error options:(SDWebImageOptions)options context:(SDWebImageContext *)context {\n    BOOL shouldBlockFailedURL;\n    // Filter the error domain and check error codes\n    if ([error.domain isEqualToString:SDWebImageErrorDomain]) {\n        shouldBlockFailedURL = (   error.code == SDWebImageErrorInvalidURL\n                                || error.code == SDWebImageErrorBadImageData);\n    } else if ([error.domain isEqualToString:NSURLErrorDomain]) {\n        shouldBlockFailedURL = (   error.code != NSURLErrorNotConnectedToInternet\n                                && error.code != NSURLErrorCancelled\n                                && error.code != NSURLErrorTimedOut\n                                && error.code != NSURLErrorInternationalRoamingOff\n                                && error.code != NSURLErrorDataNotAllowed\n                                && error.code != NSURLErrorCannotFindHost\n                                && error.code != NSURLErrorCannotConnectToHost\n                                && error.code != NSURLErrorNetworkConnectionLost);\n    } else {\n        shouldBlockFailedURL = NO;\n    }\n    return shouldBlockFailedURL;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// Operation execution order\ntypedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {\n    /**\n     * Default value. All download operations will execute in queue style (first-in-first-out).\n     */\n    SDWebImageDownloaderFIFOExecutionOrder,\n    \n    /**\n     * All download operations will execute in stack style (last-in-first-out).\n     */\n    SDWebImageDownloaderLIFOExecutionOrder\n};\n\n/**\n The class contains all the config for image downloader\n @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well.\n */\n@interface SDWebImageDownloaderConfig : NSObject <NSCopying>\n\n/**\n Gets the default downloader config used for shared instance or initialization when it does not provide any downloader config. Such as `SDWebImageDownloader.sharedDownloader`.\n @note You can modify the property on default downloader config, which can be used for later created downloader instance. The already created downloader instance does not get affected.\n */\n@property (nonatomic, class, readonly, nonnull) SDWebImageDownloaderConfig *defaultDownloaderConfig;\n\n/**\n * The maximum number of concurrent downloads.\n * Defaults to 6.\n */\n@property (nonatomic, assign) NSInteger maxConcurrentDownloads;\n\n/**\n * The timeout value (in seconds) for each download operation.\n * Defaults to 15.0.\n */\n@property (nonatomic, assign) NSTimeInterval downloadTimeout;\n\n/**\n * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected.\n * The value should be 0.0-1.0.\n * @note If you're using progressive decoding feature, this will also effect the image refresh rate.\n * @note This value may enhance the performance if you don't want progress callback too frequently.\n * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately.\n */\n@property (nonatomic, assign) double minimumProgressInterval;\n\n/**\n * The custom session configuration in use by NSURLSession. If you don't provide one, we will use `defaultSessionConfiguration` instead.\n * Defatuls to nil.\n * @note This property does not support dynamic changes, means it's immutable after the downloader instance initialized.\n */\n@property (nonatomic, strong, nullable) NSURLSessionConfiguration *sessionConfiguration;\n\n/**\n * Gets/Sets a subclass of `SDWebImageDownloaderOperation` as the default\n * `NSOperation` to be used each time SDWebImage constructs a request\n * operation to download an image.\n * Defaults to nil.\n * @note Passing `NSOperation<SDWebImageDownloaderOperation>` to set as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`.\n */\n@property (nonatomic, assign, nullable) Class operationClass;\n\n/**\n * Changes download operations execution order.\n * Defaults to `SDWebImageDownloaderFIFOExecutionOrder`.\n */\n@property (nonatomic, assign) SDWebImageDownloaderExecutionOrder executionOrder;\n\n/**\n * Set the default URL credential to be set for request operations.\n * Defaults to nil.\n */\n@property (nonatomic, copy, nullable) NSURLCredential *urlCredential;\n\n/**\n * Set username using for HTTP Basic authentication.\n * Defaults to nil.\n */\n@property (nonatomic, copy, nullable) NSString *username;\n\n/**\n * Set password using for HTTP Basic authentication.\n * Defaults to nil.\n */\n@property (nonatomic, copy, nullable) NSString *password;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageDownloaderConfig.h\"\n\nstatic SDWebImageDownloaderConfig * _defaultDownloaderConfig;\n\n@implementation SDWebImageDownloaderConfig\n\n+ (SDWebImageDownloaderConfig *)defaultDownloaderConfig {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _defaultDownloaderConfig = [SDWebImageDownloaderConfig new];\n    });\n    return _defaultDownloaderConfig;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _maxConcurrentDownloads = 6;\n        _downloadTimeout = 15.0;\n        _executionOrder = SDWebImageDownloaderFIFOExecutionOrder;\n    }\n    return self;\n}\n\n- (id)copyWithZone:(NSZone *)zone {\n    SDWebImageDownloaderConfig *config = [[[self class] allocWithZone:zone] init];\n    config.maxConcurrentDownloads = self.maxConcurrentDownloads;\n    config.downloadTimeout = self.downloadTimeout;\n    config.minimumProgressInterval = self.minimumProgressInterval;\n    config.sessionConfiguration = [self.sessionConfiguration copyWithZone:zone];\n    config.operationClass = self.operationClass;\n    config.executionOrder = self.executionOrder;\n    config.urlCredential = self.urlCredential;\n    config.username = self.username;\n    config.password = self.password;\n    \n    return config;\n}\n\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\ntypedef NSData * _Nullable (^SDWebImageDownloaderDecryptorBlock)(NSData * _Nonnull data, NSURLResponse * _Nullable response);\n\n/**\nThis is the protocol for downloader decryptor. Which decrypt the original encrypted data before decoding. Note progressive decoding is not compatible for decryptor.\nWe can use a block to specify the downloader decryptor. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.\n*/\n@protocol SDWebImageDownloaderDecryptor <NSObject>\n\n/// Decrypt the original download data and return a new data. You can use this to decrypt the data using your preferred algorithm.\n/// @param data The original download data\n/// @param response The URL response for data. If you modify the original URL response via response modifier, the modified version will be here. This arg is nullable.\n/// @note If nil is returned, the image download will be marked as failed with error `SDWebImageErrorBadImageData`\n- (nullable NSData *)decryptedDataWithData:(nonnull NSData *)data response:(nullable NSURLResponse *)response;\n\n@end\n\n/**\nA downloader response modifier class with block.\n*/\n@interface SDWebImageDownloaderDecryptor : NSObject <SDWebImageDownloaderDecryptor>\n\n/// Create the data decryptor with block\n/// @param block A block to control decrypt logic\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderDecryptorBlock)block;\n\n/// Create the data decryptor with block\n/// @param block A block to control decrypt logic\n+ (nonnull instancetype)decryptorWithBlock:(nonnull SDWebImageDownloaderDecryptorBlock)block;\n\n@end\n\n/// Convenience way to create decryptor for common data encryption.\n@interface SDWebImageDownloaderDecryptor (Conveniences)\n\n/// Base64 Encoded image data decryptor\n@property (class, readonly, nonnull) SDWebImageDownloaderDecryptor *base64Decryptor;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDWebImageDownloaderDecryptor.h\"\n\n@interface SDWebImageDownloaderDecryptor ()\n\n@property (nonatomic, copy, nonnull) SDWebImageDownloaderDecryptorBlock block;\n\n@end\n\n@implementation SDWebImageDownloaderDecryptor\n\n- (instancetype)initWithBlock:(SDWebImageDownloaderDecryptorBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)decryptorWithBlock:(SDWebImageDownloaderDecryptorBlock)block {\n    SDWebImageDownloaderDecryptor *decryptor = [[SDWebImageDownloaderDecryptor alloc] initWithBlock:block];\n    return decryptor;\n}\n\n- (nullable NSData *)decryptedDataWithData:(nonnull NSData *)data response:(nullable NSURLResponse *)response {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(data, response);\n}\n\n@end\n\n@implementation SDWebImageDownloaderDecryptor (Conveniences)\n\n+ (SDWebImageDownloaderDecryptor *)base64Decryptor {\n    static SDWebImageDownloaderDecryptor *decryptor;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        decryptor = [SDWebImageDownloaderDecryptor decryptorWithBlock:^NSData * _Nullable(NSData * _Nonnull data, NSURLResponse * _Nullable response) {\n            NSData *modifiedData = [[NSData alloc] initWithBase64EncodedData:data options:NSDataBase64DecodingIgnoreUnknownCharacters];\n            return modifiedData;\n        }];\n    });\n    return decryptor;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageDownloader.h\"\n#import \"SDWebImageOperation.h\"\n\n/**\n Describes a downloader operation. If one wants to use a custom downloader op, it needs to inherit from `NSOperation` and conform to this protocol\n For the description about these methods, see `SDWebImageDownloaderOperation`\n @note If your custom operation class does not use `NSURLSession` at all, do not implement the optional methods and session delegate methods.\n */\n@protocol SDWebImageDownloaderOperation <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>\n@required\n- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request\n                              inSession:(nullable NSURLSession *)session\n                                options:(SDWebImageDownloaderOptions)options;\n\n- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request\n                              inSession:(nullable NSURLSession *)session\n                                options:(SDWebImageDownloaderOptions)options\n                                context:(nullable SDWebImageContext *)context;\n\n- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;\n\n- (BOOL)cancel:(nullable id)token;\n\n@property (strong, nonatomic, readonly, nullable) NSURLRequest *request;\n@property (strong, nonatomic, readonly, nullable) NSURLResponse *response;\n\n@optional\n@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask;\n@property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));\n@property (strong, nonatomic, nullable) NSURLCredential *credential;\n@property (assign, nonatomic) double minimumProgressInterval;\n\n@end\n\n\n/**\n The download operation class for SDWebImageDownloader.\n */\n@interface SDWebImageDownloaderOperation : NSOperation <SDWebImageDownloaderOperation>\n\n/**\n * The request used by the operation's task.\n */\n@property (strong, nonatomic, readonly, nullable) NSURLRequest *request;\n\n/**\n * The response returned by the operation's task.\n */\n@property (strong, nonatomic, readonly, nullable) NSURLResponse *response;\n\n/**\n * The operation's task\n */\n@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask;\n\n/**\n * The collected metrics from `-URLSession:task:didFinishCollectingMetrics:`.\n * This can be used to collect the network metrics like download duration, DNS lookup duration, SSL handshake duration, etc. See Apple's documentation: https://developer.apple.com/documentation/foundation/urlsessiontaskmetrics\n */\n@property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));\n\n/**\n * The credential used for authentication challenges in `-URLSession:task:didReceiveChallenge:completionHandler:`.\n *\n * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.\n */\n@property (strong, nonatomic, nullable) NSURLCredential *credential;\n\n/**\n * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected.\n * The value should be 0.0-1.0.\n * @note If you're using progressive decoding feature, this will also effect the image refresh rate.\n * @note This value may enhance the performance if you don't want progress callback too frequently.\n * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately.\n */\n@property (assign, nonatomic) double minimumProgressInterval;\n\n/**\n * The options for the receiver.\n */\n@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;\n\n/**\n * The context for the receiver.\n */\n@property (copy, nonatomic, readonly, nullable) SDWebImageContext *context;\n\n/**\n *  Initializes a `SDWebImageDownloaderOperation` object\n *\n *  @see SDWebImageDownloaderOperation\n *\n *  @param request        the URL request\n *  @param session        the URL session in which this operation will run\n *  @param options        downloader options\n *\n *  @return the initialized instance\n */\n- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request\n                              inSession:(nullable NSURLSession *)session\n                                options:(SDWebImageDownloaderOptions)options;\n\n/**\n *  Initializes a `SDWebImageDownloaderOperation` object\n *\n *  @see SDWebImageDownloaderOperation\n *\n *  @param request        the URL request\n *  @param session        the URL session in which this operation will run\n *  @param options        downloader options\n *  @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n *\n *  @return the initialized instance\n */\n- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request\n                              inSession:(nullable NSURLSession *)session\n                                options:(SDWebImageDownloaderOptions)options\n                                context:(nullable SDWebImageContext *)context NS_DESIGNATED_INITIALIZER;\n\n/**\n *  Adds handlers for progress and completion. Returns a token that can be passed to -cancel: to cancel this set of\n *  callbacks.\n *\n *  @param progressBlock  the block executed when a new chunk of data arrives.\n *                        @note the progress block is executed on a background queue\n *  @param completedBlock the block executed when the download is done.\n *                        @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue\n *\n *  @return the token to use to cancel this set of handlers\n */\n- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;\n\n/**\n *  Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled.\n *\n *  @param token the token representing a set of callbacks to cancel\n *\n *  @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise.\n */\n- (BOOL)cancel:(nullable id)token;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageDownloaderOperation.h\"\n#import \"SDWebImageError.h\"\n#import \"SDInternalMacros.h\"\n#import \"SDWebImageDownloaderResponseModifier.h\"\n#import \"SDWebImageDownloaderDecryptor.h\"\n\nstatic NSString *const kProgressCallbackKey = @\"progress\";\nstatic NSString *const kCompletedCallbackKey = @\"completed\";\n\ntypedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;\n\n@interface SDWebImageDownloaderOperation ()\n\n@property (strong, nonatomic, nonnull) NSMutableArray<SDCallbacksDictionary *> *callbackBlocks;\n\n@property (assign, nonatomic, readwrite) SDWebImageDownloaderOptions options;\n@property (copy, nonatomic, readwrite, nullable) SDWebImageContext *context;\n\n@property (assign, nonatomic, getter = isExecuting) BOOL executing;\n@property (assign, nonatomic, getter = isFinished) BOOL finished;\n@property (strong, nonatomic, nullable) NSMutableData *imageData;\n@property (copy, nonatomic, nullable) NSData *cachedData; // for `SDWebImageDownloaderIgnoreCachedResponse`\n@property (assign, nonatomic) NSUInteger expectedSize; // may be 0\n@property (assign, nonatomic) NSUInteger receivedSize;\n@property (strong, nonatomic, nullable, readwrite) NSURLResponse *response;\n@property (strong, nonatomic, nullable) NSError *responseError;\n@property (assign, nonatomic) double previousProgress; // previous progress percent\n\n@property (strong, nonatomic, nullable) id<SDWebImageDownloaderResponseModifier> responseModifier; // modify original URLResponse\n@property (strong, nonatomic, nullable) id<SDWebImageDownloaderDecryptor> decryptor; // decrypt image data\n\n// This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run\n// the task associated with this operation\n@property (weak, nonatomic, nullable) NSURLSession *unownedSession;\n// This is set if we're using not using an injected NSURLSession. We're responsible of invalidating this one\n@property (strong, nonatomic, nullable) NSURLSession *ownedSession;\n\n@property (strong, nonatomic, readwrite, nullable) NSURLSessionTask *dataTask;\n\n@property (strong, nonatomic, readwrite, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));\n\n@property (strong, nonatomic, nonnull) NSOperationQueue *coderQueue; // the serial operation queue to do image decoding\n#if SD_UIKIT\n@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId;\n#endif\n\n@end\n\n@implementation SDWebImageDownloaderOperation\n\n@synthesize executing = _executing;\n@synthesize finished = _finished;\n\n- (nonnull instancetype)init {\n    return [self initWithRequest:nil inSession:nil options:0];\n}\n\n- (instancetype)initWithRequest:(NSURLRequest *)request inSession:(NSURLSession *)session options:(SDWebImageDownloaderOptions)options {\n    return [self initWithRequest:request inSession:session options:options context:nil];\n}\n\n- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request\n                              inSession:(nullable NSURLSession *)session\n                                options:(SDWebImageDownloaderOptions)options\n                                context:(nullable SDWebImageContext *)context {\n    if ((self = [super init])) {\n        _request = [request copy];\n        _options = options;\n        _context = [context copy];\n        _callbackBlocks = [NSMutableArray new];\n        _responseModifier = context[SDWebImageContextDownloadResponseModifier];\n        _decryptor = context[SDWebImageContextDownloadDecryptor];\n        _executing = NO;\n        _finished = NO;\n        _expectedSize = 0;\n        _unownedSession = session;\n        _coderQueue = [NSOperationQueue new];\n        _coderQueue.maxConcurrentOperationCount = 1;\n#if SD_UIKIT\n        _backgroundTaskId = UIBackgroundTaskInvalid;\n#endif\n    }\n    return self;\n}\n\n- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock\n                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {\n    SDCallbacksDictionary *callbacks = [NSMutableDictionary new];\n    if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];\n    if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];\n    @synchronized (self) {\n        [self.callbackBlocks addObject:callbacks];\n    }\n    return callbacks;\n}\n\n- (nullable NSArray<id> *)callbacksForKey:(NSString *)key {\n    NSMutableArray<id> *callbacks;\n    @synchronized (self) {\n        callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];\n    }\n    // We need to remove [NSNull null] because there might not always be a progress block for each callback\n    [callbacks removeObjectIdenticalTo:[NSNull null]];\n    return [callbacks copy]; // strip mutability here\n}\n\n- (BOOL)cancel:(nullable id)token {\n    if (!token) return NO;\n    \n    BOOL shouldCancel = NO;\n    @synchronized (self) {\n        NSMutableArray *tempCallbackBlocks = [self.callbackBlocks mutableCopy];\n        [tempCallbackBlocks removeObjectIdenticalTo:token];\n        if (tempCallbackBlocks.count == 0) {\n            shouldCancel = YES;\n        }\n    }\n    if (shouldCancel) {\n        // Cancel operation running and callback last token's completion block\n        [self cancel];\n    } else {\n        // Only callback this token's completion block\n        @synchronized (self) {\n            [self.callbackBlocks removeObjectIdenticalTo:token];\n        }\n        SDWebImageDownloaderCompletedBlock completedBlock = [token valueForKey:kCompletedCallbackKey];\n        dispatch_main_async_safe(^{\n            if (completedBlock) {\n                completedBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user during sending the request\"}], YES);\n            }\n        });\n    }\n    return shouldCancel;\n}\n\n- (void)start {\n    @synchronized (self) {\n        if (self.isCancelled) {\n            if (!self.isFinished) self.finished = YES;\n            // Operation cancelled by user before sending the request\n            [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user before sending the request\"}]];\n            [self reset];\n            return;\n        }\n\n#if SD_UIKIT\n        Class UIApplicationClass = NSClassFromString(@\"UIApplication\");\n        BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)];\n        if (hasApplication && [self shouldContinueWhenAppEntersBackground]) {\n            __weak typeof(self) wself = self;\n            UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)];\n            self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{\n                [wself cancel];\n            }];\n        }\n#endif\n        NSURLSession *session = self.unownedSession;\n        if (!session) {\n            NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];\n            sessionConfig.timeoutIntervalForRequest = 15;\n            \n            /**\n             *  Create the session for this task\n             *  We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate\n             *  method calls and completion handler calls.\n             */\n            session = [NSURLSession sessionWithConfiguration:sessionConfig\n                                                    delegate:self\n                                               delegateQueue:nil];\n            self.ownedSession = session;\n        }\n        \n        if (self.options & SDWebImageDownloaderIgnoreCachedResponse) {\n            // Grab the cached data for later check\n            NSURLCache *URLCache = session.configuration.URLCache;\n            if (!URLCache) {\n                URLCache = [NSURLCache sharedURLCache];\n            }\n            NSCachedURLResponse *cachedResponse;\n            // NSURLCache's `cachedResponseForRequest:` is not thread-safe, see https://developer.apple.com/documentation/foundation/nsurlcache#2317483\n            @synchronized (URLCache) {\n                cachedResponse = [URLCache cachedResponseForRequest:self.request];\n            }\n            if (cachedResponse) {\n                self.cachedData = cachedResponse.data;\n            }\n        }\n        \n        if (!session.delegate) {\n            // Session been invalid and has no delegate at all\n            [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @\"Session delegate is nil and invalid\"}]];\n            [self reset];\n            return;\n        }\n        \n        self.dataTask = [session dataTaskWithRequest:self.request];\n        self.executing = YES;\n    }\n\n    if (self.dataTask) {\n        if (self.options & SDWebImageDownloaderHighPriority) {\n            self.dataTask.priority = NSURLSessionTaskPriorityHigh;\n            self.coderQueue.qualityOfService = NSQualityOfServiceUserInteractive;\n        } else if (self.options & SDWebImageDownloaderLowPriority) {\n            self.dataTask.priority = NSURLSessionTaskPriorityLow;\n            self.coderQueue.qualityOfService = NSQualityOfServiceBackground;\n        } else {\n            self.dataTask.priority = NSURLSessionTaskPriorityDefault;\n            self.coderQueue.qualityOfService = NSQualityOfServiceDefault;\n        }\n        [self.dataTask resume];\n        for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {\n            progressBlock(0, NSURLResponseUnknownLength, self.request.URL);\n        }\n        __block typeof(self) strongSelf = self;\n        dispatch_async(dispatch_get_main_queue(), ^{\n            [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:strongSelf];\n        });\n    } else {\n        if (!self.isFinished) self.finished = YES;\n        [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @\"Task can't be initialized\"}]];\n        [self reset];\n    }\n}\n\n- (void)cancel {\n    @synchronized (self) {\n        [self cancelInternal];\n    }\n}\n\n- (void)cancelInternal {\n    if (self.isFinished) return;\n    [super cancel];\n    \n    __block typeof(self) strongSelf = self;\n    dispatch_async(dispatch_get_main_queue(), ^{\n        [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:strongSelf];\n    });\n\n    if (self.dataTask) {\n        // Cancel the URLSession, `URLSession:task:didCompleteWithError:` delegate callback will be ignored\n        [self.dataTask cancel];\n        self.dataTask = nil;\n    }\n    \n    // NSOperation disallow setFinished=YES **before** operation's start method been called\n    // We check for the initialized status, which is isExecuting == NO && isFinished = NO\n    // Ony update for non-intialized status, which is !(isExecuting == NO && isFinished = NO), or if (self.isExecuting || self.isFinished) {...}\n    if (self.isExecuting || self.isFinished) {\n        if (self.isExecuting) self.executing = NO;\n        if (!self.isFinished) self.finished = YES;\n    }\n    \n    // Operation cancelled by user during sending the request\n    [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user during sending the request\"}]];\n\n    [self reset];\n}\n\n- (void)done {\n    self.finished = YES;\n    self.executing = NO;\n    [self reset];\n}\n\n- (void)reset {\n    @synchronized (self) {\n        [self.callbackBlocks removeAllObjects];\n        self.dataTask = nil;\n        \n        if (self.ownedSession) {\n            [self.ownedSession invalidateAndCancel];\n            self.ownedSession = nil;\n        }\n        \n#if SD_UIKIT\n        if (self.backgroundTaskId != UIBackgroundTaskInvalid) {\n            // If backgroundTaskId != UIBackgroundTaskInvalid, sharedApplication is always exist\n            UIApplication * app = [UIApplication performSelector:@selector(sharedApplication)];\n            [app endBackgroundTask:self.backgroundTaskId];\n            self.backgroundTaskId = UIBackgroundTaskInvalid;\n        }\n#endif\n    }\n}\n\n- (void)setFinished:(BOOL)finished {\n    [self willChangeValueForKey:@\"isFinished\"];\n    _finished = finished;\n    [self didChangeValueForKey:@\"isFinished\"];\n}\n\n- (void)setExecuting:(BOOL)executing {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    _executing = executing;\n    [self didChangeValueForKey:@\"isExecuting\"];\n}\n\n- (BOOL)isConcurrent {\n    return YES;\n}\n\n#pragma mark NSURLSessionDataDelegate\n\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\ndidReceiveResponse:(NSURLResponse *)response\n completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {\n    NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow;\n    \n    // Check response modifier, if return nil, will marked as cancelled.\n    BOOL valid = YES;\n    if (self.responseModifier && response) {\n        response = [self.responseModifier modifiedResponseWithResponse:response];\n        if (!response) {\n            valid = NO;\n            self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadResponse userInfo:@{NSLocalizedDescriptionKey : @\"Download marked as failed because response is nil\"}];\n        }\n    }\n    \n    NSInteger expected = (NSInteger)response.expectedContentLength;\n    expected = expected > 0 ? expected : 0;\n    self.expectedSize = expected;\n    self.response = response;\n    \n    NSInteger statusCode = [response respondsToSelector:@selector(statusCode)] ? ((NSHTTPURLResponse *)response).statusCode : 200;\n    // Status code should between [200,400)\n    BOOL statusCodeValid = statusCode >= 200 && statusCode < 400;\n    if (!statusCodeValid) {\n        valid = NO;\n        self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadStatusCode userInfo:@{NSLocalizedDescriptionKey : @\"Download marked as failed because response status code is not in 200-400\", SDWebImageErrorDownloadStatusCodeKey : @(statusCode)}];\n    }\n    //'304 Not Modified' is an exceptional one\n    //URLSession current behavior will return 200 status code when the server respond 304 and URLCache hit. But this is not a standard behavior and we just add a check\n    if (statusCode == 304 && !self.cachedData) {\n        valid = NO;\n        self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCacheNotModified userInfo:@{NSLocalizedDescriptionKey : @\"Download response status code is 304 not modified and ignored\"}];\n    }\n    \n    if (valid) {\n        for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {\n            progressBlock(0, expected, self.request.URL);\n        }\n    } else {\n        // Status code invalid and marked as cancelled. Do not call `[self.dataTask cancel]` which may mass up URLSession life cycle\n        disposition = NSURLSessionResponseCancel;\n    }\n    __block typeof(self) strongSelf = self;\n    dispatch_async(dispatch_get_main_queue(), ^{\n        [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadReceiveResponseNotification object:strongSelf];\n    });\n    \n    if (completionHandler) {\n        completionHandler(disposition);\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {\n    if (!self.imageData) {\n        self.imageData = [[NSMutableData alloc] initWithCapacity:self.expectedSize];\n    }\n    [self.imageData appendData:data];\n    \n    self.receivedSize = self.imageData.length;\n    if (self.expectedSize == 0) {\n        // Unknown expectedSize, immediately call progressBlock and return\n        for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {\n            progressBlock(self.receivedSize, self.expectedSize, self.request.URL);\n        }\n        return;\n    }\n    \n    // Get the finish status\n    BOOL finished = (self.receivedSize >= self.expectedSize);\n    // Get the current progress\n    double currentProgress = (double)self.receivedSize / (double)self.expectedSize;\n    double previousProgress = self.previousProgress;\n    double progressInterval = currentProgress - previousProgress;\n    // Check if we need callback progress\n    if (!finished && (progressInterval < self.minimumProgressInterval)) {\n        return;\n    }\n    self.previousProgress = currentProgress;\n    \n    // Using data decryptor will disable the progressive decoding, since there are no support for progressive decrypt\n    BOOL supportProgressive = (self.options & SDWebImageDownloaderProgressiveLoad) && !self.decryptor;\n    // Progressive decoding Only decode partial image, full image in `URLSession:task:didCompleteWithError:`\n    if (supportProgressive && !finished) {\n        // Get the image data\n        NSData *imageData = [self.imageData copy];\n        \n        // keep maximum one progressive decode process during download\n        if (self.coderQueue.operationCount == 0) {\n            // NSOperation have autoreleasepool, don't need to create extra one\n            @weakify(self);\n            [self.coderQueue addOperationWithBlock:^{\n                @strongify(self);\n                if (!self) {\n                    return;\n                }\n                UIImage *image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, NO, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);\n                if (image) {\n                    // We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding.\n                    \n                    [self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO];\n                }\n            }];\n        }\n    }\n    \n    for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {\n        progressBlock(self.receivedSize, self.expectedSize, self.request.URL);\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\n willCacheResponse:(NSCachedURLResponse *)proposedResponse\n completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler {\n    \n    NSCachedURLResponse *cachedResponse = proposedResponse;\n\n    if (!(self.options & SDWebImageDownloaderUseNSURLCache)) {\n        // Prevents caching of responses\n        cachedResponse = nil;\n    }\n    if (completionHandler) {\n        completionHandler(cachedResponse);\n    }\n}\n\n#pragma mark NSURLSessionTaskDelegate\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {\n    // If we already cancel the operation or anything mark the operation finished, don't callback twice\n    if (self.isFinished) return;\n    \n    @synchronized(self) {\n        self.dataTask = nil;\n        __block typeof(self) strongSelf = self;\n        dispatch_async(dispatch_get_main_queue(), ^{\n            [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:strongSelf];\n            if (!error) {\n                [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:strongSelf];\n            }\n        });\n    }\n    \n    // make sure to call `[self done]` to mark operation as finished\n    if (error) {\n        // custom error instead of URLSession error\n        if (self.responseError) {\n            error = self.responseError;\n        }\n        [self callCompletionBlocksWithError:error];\n        [self done];\n    } else {\n        if ([self callbacksForKey:kCompletedCallbackKey].count > 0) {\n            NSData *imageData = self.imageData;\n            self.imageData = nil;\n            // data decryptor\n            if (imageData && self.decryptor) {\n                imageData = [self.decryptor decryptedDataWithData:imageData response:self.response];\n            }\n            if (imageData) {\n                /**  if you specified to only use cached data via `SDWebImageDownloaderIgnoreCachedResponse`,\n                 *  then we should check if the cached data is equal to image data\n                 */\n                if (self.options & SDWebImageDownloaderIgnoreCachedResponse && [self.cachedData isEqualToData:imageData]) {\n                    self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCacheNotModified userInfo:@{NSLocalizedDescriptionKey : @\"Downloaded image is not modified and ignored\"}];\n                    // call completion block with not modified error\n                    [self callCompletionBlocksWithError:self.responseError];\n                    [self done];\n                } else {\n                    // decode the image in coder queue, cancel all previous decoding process\n                    [self.coderQueue cancelAllOperations];\n                    @weakify(self);\n                    [self.coderQueue addOperationWithBlock:^{\n                        @strongify(self);\n                        if (!self) {\n                            return;\n                        }\n                        // check if we already use progressive decoding, use that to produce faster decoding\n                        id<SDProgressiveImageCoder> progressiveCoder = SDImageLoaderGetProgressiveCoder(self);\n                        UIImage *image;\n                        if (progressiveCoder) {\n                            image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, YES, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);\n                        } else {\n                            image = SDImageLoaderDecodeImageData(imageData, self.request.URL, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);\n                        }\n                        CGSize imageSize = image.size;\n                        if (imageSize.width == 0 || imageSize.height == 0) {\n                            NSString *description = image == nil ? @\"Downloaded image decode failed\" : @\"Downloaded image has 0 pixels\";\n                            [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : description}]];\n                        } else {\n                            [self callCompletionBlocksWithImage:image imageData:imageData error:nil finished:YES];\n                        }\n                        [self done];\n                    }];\n                }\n            } else {\n                [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : @\"Image data is nil\"}]];\n                [self done];\n            }\n        } else {\n            [self done];\n        }\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {\n    \n    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;\n    __block NSURLCredential *credential = nil;\n    \n    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {\n        if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates)) {\n            disposition = NSURLSessionAuthChallengePerformDefaultHandling;\n        } else {\n            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];\n            disposition = NSURLSessionAuthChallengeUseCredential;\n        }\n    } else {\n        if (challenge.previousFailureCount == 0) {\n            if (self.credential) {\n                credential = self.credential;\n                disposition = NSURLSessionAuthChallengeUseCredential;\n            } else {\n                disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;\n            }\n        } else {\n            disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;\n        }\n    }\n    \n    if (completionHandler) {\n        completionHandler(disposition, credential);\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) {\n    self.metrics = metrics;\n}\n\n#pragma mark Helper methods\n+ (SDWebImageOptions)imageOptionsFromDownloaderOptions:(SDWebImageDownloaderOptions)downloadOptions {\n    SDWebImageOptions options = 0;\n    if (downloadOptions & SDWebImageDownloaderScaleDownLargeImages) options |= SDWebImageScaleDownLargeImages;\n    if (downloadOptions & SDWebImageDownloaderDecodeFirstFrameOnly) options |= SDWebImageDecodeFirstFrameOnly;\n    if (downloadOptions & SDWebImageDownloaderPreloadAllFrames) options |= SDWebImagePreloadAllFrames;\n    if (downloadOptions & SDWebImageDownloaderAvoidDecodeImage) options |= SDWebImageAvoidDecodeImage;\n    if (downloadOptions & SDWebImageDownloaderMatchAnimatedImageClass) options |= SDWebImageMatchAnimatedImageClass;\n    \n    return options;\n}\n\n- (BOOL)shouldContinueWhenAppEntersBackground {\n    return SD_OPTIONS_CONTAINS(self.options, SDWebImageDownloaderContinueInBackground);\n}\n\n- (void)callCompletionBlocksWithError:(nullable NSError *)error {\n    [self callCompletionBlocksWithImage:nil imageData:nil error:error finished:YES];\n}\n\n- (void)callCompletionBlocksWithImage:(nullable UIImage *)image\n                            imageData:(nullable NSData *)imageData\n                                error:(nullable NSError *)error\n                             finished:(BOOL)finished {\n    NSArray<id> *completionBlocks = [self callbacksForKey:kCompletedCallbackKey];\n    dispatch_main_async_safe(^{\n        for (SDWebImageDownloaderCompletedBlock completedBlock in completionBlocks) {\n            completedBlock(image, imageData, error, finished);\n        }\n    });\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\ntypedef NSURLRequest * _Nullable (^SDWebImageDownloaderRequestModifierBlock)(NSURLRequest * _Nonnull request);\n\n/**\n This is the protocol for downloader request modifier.\n We can use a block to specify the downloader request modifier. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.\n */\n@protocol SDWebImageDownloaderRequestModifier <NSObject>\n\n/// Modify the original URL request and return a new one instead. You can modify the HTTP header, cachePolicy, etc for this URL.\n/// @param request The original URL request for image loading\n/// @note If return nil, the URL request will be cancelled.\n- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request;\n\n@end\n\n/**\n A downloader request modifier class with block.\n */\n@interface SDWebImageDownloaderRequestModifier : NSObject <SDWebImageDownloaderRequestModifier>\n\n/// Create the request modifier with block\n/// @param block A block to control modifier logic\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block;\n\n/// Create the request modifier with block\n/// @param block A block to control modifier logic\n+ (nonnull instancetype)requestModifierWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block;\n\n@end\n\n/**\nA convenient request modifier to provide the HTTP request including HTTP Method, Headers and Body.\n*/\n@interface SDWebImageDownloaderRequestModifier (Conveniences)\n\n/// Create the request modifier with HTTP Method.\n/// @param method HTTP Method, nil means to GET.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithMethod:(nullable NSString *)method;\n\n/// Create the request modifier with HTTP Headers.\n/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original request.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithHeaders:(nullable NSDictionary<NSString *, NSString *> *)headers;\n\n/// Create the request modifier with HTTP Body.\n/// @param body HTTP Body.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithBody:(nullable NSData *)body;\n\n/// Create the request modifier with HTTP Method, Headers and Body.\n/// @param method HTTP Method, nil means to GET.\n/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original request.\n/// @param body HTTP Body.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithMethod:(nullable NSString *)method headers:(nullable NSDictionary<NSString *, NSString *> *)headers body:(nullable NSData *)body;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageDownloaderRequestModifier.h\"\n\n@interface SDWebImageDownloaderRequestModifier ()\n\n@property (nonatomic, copy, nonnull) SDWebImageDownloaderRequestModifierBlock block;\n\n@end\n\n@implementation SDWebImageDownloaderRequestModifier\n\n- (instancetype)initWithBlock:(SDWebImageDownloaderRequestModifierBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)requestModifierWithBlock:(SDWebImageDownloaderRequestModifierBlock)block {\n    SDWebImageDownloaderRequestModifier *requestModifier = [[SDWebImageDownloaderRequestModifier alloc] initWithBlock:block];\n    return requestModifier;\n}\n\n- (NSURLRequest *)modifiedRequestWithRequest:(NSURLRequest *)request {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(request);\n}\n\n@end\n\n@implementation SDWebImageDownloaderRequestModifier (Conveniences)\n\n- (instancetype)initWithMethod:(NSString *)method {\n    return [self initWithMethod:method headers:nil body:nil];\n}\n\n- (instancetype)initWithHeaders:(NSDictionary<NSString *,NSString *> *)headers {\n    return [self initWithMethod:nil headers:headers body:nil];\n}\n\n- (instancetype)initWithBody:(NSData *)body {\n    return [self initWithMethod:nil headers:nil body:body];\n}\n\n- (instancetype)initWithMethod:(NSString *)method headers:(NSDictionary<NSString *,NSString *> *)headers body:(NSData *)body {\n    method = method ? [method copy] : @\"GET\";\n    headers = [headers copy];\n    body = [body copy];\n    return [self initWithBlock:^NSURLRequest * _Nullable(NSURLRequest * _Nonnull request) {\n        NSMutableURLRequest *mutableRequest = [request mutableCopy];\n        mutableRequest.HTTPMethod = method;\n        mutableRequest.HTTPBody = body;\n        for (NSString *header in headers) {\n            NSString *value = headers[header];\n            [mutableRequest setValue:value forHTTPHeaderField:header];\n        }\n        return [mutableRequest copy];\n    }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\ntypedef NSURLResponse * _Nullable (^SDWebImageDownloaderResponseModifierBlock)(NSURLResponse * _Nonnull response);\n\n/**\n This is the protocol for downloader response modifier.\n We can use a block to specify the downloader response modifier. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.\n */\n@protocol SDWebImageDownloaderResponseModifier <NSObject>\n\n/// Modify the original URL response and return a new response. You can use this to check MIME-Type, mock server response, etc.\n/// @param response The original URL response, note for HTTP request it's actually a `NSHTTPURLResponse` instance\n/// @note If nil is returned, the image download will marked as cancelled with error `SDWebImageErrorInvalidDownloadResponse`\n- (nullable NSURLResponse *)modifiedResponseWithResponse:(nonnull NSURLResponse *)response;\n\n@end\n\n/**\n A downloader response modifier class with block.\n */\n@interface SDWebImageDownloaderResponseModifier : NSObject <SDWebImageDownloaderResponseModifier>\n\n/// Create the response modifier with block\n/// @param block A block to control modifier logic\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderResponseModifierBlock)block;\n\n/// Create the response modifier with block\n/// @param block A block to control modifier logic\n+ (nonnull instancetype)responseModifierWithBlock:(nonnull SDWebImageDownloaderResponseModifierBlock)block;\n\n@end\n\n/**\nA convenient response modifier to provide the HTTP response including HTTP Status Code, Version and Headers.\n*/\n@interface SDWebImageDownloaderResponseModifier (Conveniences)\n\n/// Create the response modifier with HTTP Status code.\n/// @param statusCode HTTP Status Code.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithStatusCode:(NSInteger)statusCode;\n\n/// Create the response modifier with HTTP Version. Status code defaults to 200.\n/// @param version HTTP Version, nil means \"HTTP/1.1\".\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithVersion:(nullable NSString *)version;\n\n/// Create the response modifier with HTTP Headers. Status code defaults to 200.\n/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original response.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithHeaders:(nullable NSDictionary<NSString *, NSString *> *)headers;\n\n/// Create the response modifier with HTTP Status Code, Version and Headers.\n/// @param statusCode HTTP Status Code.\n/// @param version HTTP Version, nil means \"HTTP/1.1\".\n/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original response.\n/// @note This is for convenience, if you need code to control the logic, use block API instead.\n- (nonnull instancetype)initWithStatusCode:(NSInteger)statusCode version:(nullable NSString *)version headers:(nullable NSDictionary<NSString *, NSString *> *)headers;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n\n#import \"SDWebImageDownloaderResponseModifier.h\"\n\n@interface SDWebImageDownloaderResponseModifier ()\n\n@property (nonatomic, copy, nonnull) SDWebImageDownloaderResponseModifierBlock block;\n\n@end\n\n@implementation SDWebImageDownloaderResponseModifier\n\n- (instancetype)initWithBlock:(SDWebImageDownloaderResponseModifierBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)responseModifierWithBlock:(SDWebImageDownloaderResponseModifierBlock)block {\n    SDWebImageDownloaderResponseModifier *responseModifier = [[SDWebImageDownloaderResponseModifier alloc] initWithBlock:block];\n    return responseModifier;\n}\n\n- (nullable NSURLResponse *)modifiedResponseWithResponse:(nonnull NSURLResponse *)response {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(response);\n}\n\n@end\n\n@implementation SDWebImageDownloaderResponseModifier (Conveniences)\n\n- (instancetype)initWithStatusCode:(NSInteger)statusCode {\n    return [self initWithStatusCode:statusCode version:nil headers:nil];\n}\n\n- (instancetype)initWithVersion:(NSString *)version {\n    return [self initWithStatusCode:200 version:version headers:nil];\n}\n\n- (instancetype)initWithHeaders:(NSDictionary<NSString *,NSString *> *)headers {\n    return [self initWithStatusCode:200 version:nil headers:headers];\n}\n\n- (instancetype)initWithStatusCode:(NSInteger)statusCode version:(NSString *)version headers:(NSDictionary<NSString *,NSString *> *)headers {\n    version = version ? [version copy] : @\"HTTP/1.1\";\n    headers = [headers copy];\n    return [self initWithBlock:^NSURLResponse * _Nullable(NSURLResponse * _Nonnull response) {\n        if (![response isKindOfClass:NSHTTPURLResponse.class]) {\n            return response;\n        }\n        NSMutableDictionary *mutableHeaders = [((NSHTTPURLResponse *)response).allHeaderFields mutableCopy];\n        for (NSString *header in headers) {\n            NSString *value = headers[header];\n            mutableHeaders[header] = value;\n        }\n        NSHTTPURLResponse *httpResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL statusCode:statusCode HTTPVersion:version headerFields:[mutableHeaders copy]];\n        return httpResponse;\n    }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageError.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Jamie Pinkham\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\nFOUNDATION_EXPORT NSErrorDomain const _Nonnull SDWebImageErrorDomain;\n\n/// The HTTP status code for invalid download response (NSNumber *)\nFOUNDATION_EXPORT NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadStatusCodeKey;\n\n/// SDWebImage error domain and codes\ntypedef NS_ERROR_ENUM(SDWebImageErrorDomain, SDWebImageError) {\n    SDWebImageErrorInvalidURL = 1000, // The URL is invalid, such as nil URL or corrupted URL\n    SDWebImageErrorBadImageData = 1001, // The image data can not be decoded to image, or the image data is empty\n    SDWebImageErrorCacheNotModified = 1002, // The remote location specify that the cached image is not modified, such as the HTTP response 304 code. It's useful for `SDWebImageRefreshCached`\n    SDWebImageErrorBlackListed = 1003, // The URL is blacklisted because of unrecoverable failure marked by downloader (such as 404), you can use `.retryFailed` option to avoid this\n    SDWebImageErrorInvalidDownloadOperation = 2000, // The image download operation is invalid, such as nil operation or unexpected error occur when operation initialized\n    SDWebImageErrorInvalidDownloadStatusCode = 2001, // The image download response a invalid status code. You can check the status code in error's userInfo under `SDWebImageErrorDownloadStatusCodeKey`\n    SDWebImageErrorCancelled = 2002, // The image loading operation is cancelled before finished, during either async disk cache query, or waiting before actual network request. For actual network request error, check `NSURLErrorDomain` error domain and code.\n    SDWebImageErrorInvalidDownloadResponse = 2003, // When using response modifier, the modified download response is nil and marked as failed.\n};\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageError.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Jamie Pinkham\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageError.h\"\n\nNSErrorDomain const _Nonnull SDWebImageErrorDomain = @\"SDWebImageErrorDomain\";\nNSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadStatusCodeKey = @\"SDWebImageErrorDownloadStatusCodeKey\";\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_UIKIT || SD_MAC\n\n/**\n A protocol to custom the indicator during the image loading.\n All of these methods are called from main queue.\n */\n@protocol SDWebImageIndicator <NSObject>\n\n@required\n/**\n The view associate to the indicator.\n\n @return The indicator view\n */\n@property (nonatomic, strong, readonly, nonnull) UIView *indicatorView;\n\n/**\n Start the animating for indicator.\n */\n- (void)startAnimatingIndicator;\n\n/**\n Stop the animating for indicator.\n */\n- (void)stopAnimatingIndicator;\n\n@optional\n/**\n Update the loading progress (0-1.0) for indicator. Optional\n \n @param progress The progress, value between 0 and 1.0\n */\n- (void)updateIndicatorProgress:(double)progress;\n\n@end\n\n#pragma mark - Activity Indicator\n\n/**\n Activity indicator class.\n for UIKit(macOS), it use a `UIActivityIndicatorView`.\n for AppKit(macOS), it use a `NSProgressIndicator` with the spinning style.\n */\n@interface SDWebImageActivityIndicator : NSObject <SDWebImageIndicator>\n\n#if SD_UIKIT\n@property (nonatomic, strong, readonly, nonnull) UIActivityIndicatorView *indicatorView;\n#else\n@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView;\n#endif\n\n@end\n\n/**\n Convenience way to use activity indicator.\n */\n@interface SDWebImageActivityIndicator (Conveniences)\n\n/// These indicator use the fixed color without dark mode support\n/// gray-style activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *grayIndicator;\n/// large gray-style activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *grayLargeIndicator;\n/// white-style activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *whiteIndicator;\n/// large white-style activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *whiteLargeIndicator;\n/// These indicator use the system style, supports dark mode if available (iOS 13+/macOS 10.14+)\n/// large activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *largeIndicator;\n/// medium activity indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *mediumIndicator;\n\n@end\n\n#pragma mark - Progress Indicator\n\n/**\n Progress indicator class.\n for UIKit(macOS), it use a `UIProgressView`.\n for AppKit(macOS), it use a `NSProgressIndicator` with the bar style.\n */\n@interface SDWebImageProgressIndicator : NSObject <SDWebImageIndicator>\n\n#if SD_UIKIT\n@property (nonatomic, strong, readonly, nonnull) UIProgressView *indicatorView;\n#else\n@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView;\n#endif\n\n@end\n\n/**\n Convenience way to create progress indicator. Remember to specify the indicator width or use layout constraint if need.\n */\n@interface SDWebImageProgressIndicator (Conveniences)\n\n/// default-style progress indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageProgressIndicator *defaultIndicator;\n/// bar-style progress indicator\n@property (nonatomic, class, nonnull, readonly) SDWebImageProgressIndicator *barIndicator API_UNAVAILABLE(macos, tvos);\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageIndicator.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#if SD_MAC\n#import <QuartzCore/QuartzCore.h>\n#endif\n\n#pragma mark - Activity Indicator\n\n@interface SDWebImageActivityIndicator ()\n\n#if SD_UIKIT\n@property (nonatomic, strong, readwrite, nonnull) UIActivityIndicatorView *indicatorView;\n#else\n@property (nonatomic, strong, readwrite, nonnull) NSProgressIndicator *indicatorView;\n#endif\n\n@end\n\n@implementation SDWebImageActivityIndicator\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n\n#if SD_UIKIT\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n- (void)commonInit {\n    self.indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];\n    self.indicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;\n}\n#pragma clang diagnostic pop\n#endif\n\n#if SD_MAC\n- (void)commonInit {\n    self.indicatorView = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect];\n    self.indicatorView.style = NSProgressIndicatorStyleSpinning;\n    self.indicatorView.controlSize = NSControlSizeSmall;\n    [self.indicatorView sizeToFit];\n    self.indicatorView.autoresizingMask = NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;\n}\n#endif\n\n- (void)startAnimatingIndicator {\n#if SD_UIKIT\n    [self.indicatorView startAnimating];\n#else\n    [self.indicatorView startAnimation:nil];\n#endif\n    self.indicatorView.hidden = NO;\n}\n\n- (void)stopAnimatingIndicator {\n#if SD_UIKIT\n    [self.indicatorView stopAnimating];\n#else\n    [self.indicatorView stopAnimation:nil];\n#endif\n    self.indicatorView.hidden = YES;\n}\n\n@end\n\n@implementation SDWebImageActivityIndicator (Conveniences)\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n+ (SDWebImageActivityIndicator *)grayIndicator {\n    SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new];\n#if SD_UIKIT\n#if SD_IOS\n    indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;\n#else\n    indicator.indicatorView.color = [UIColor colorWithWhite:0 alpha:0.45]; // Color from `UIActivityIndicatorViewStyleGray`\n#endif\n#else\n    indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support\n#endif\n    return indicator;\n}\n\n+ (SDWebImageActivityIndicator *)grayLargeIndicator {\n    SDWebImageActivityIndicator *indicator = SDWebImageActivityIndicator.grayIndicator;\n#if SD_UIKIT\n    UIColor *grayColor = indicator.indicatorView.color;\n    indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;\n    indicator.indicatorView.color = grayColor;\n#else\n    indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support\n    indicator.indicatorView.controlSize = NSControlSizeRegular;\n#endif\n    [indicator.indicatorView sizeToFit];\n    return indicator;\n}\n\n+ (SDWebImageActivityIndicator *)whiteIndicator {\n    SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new];\n#if SD_UIKIT\n    indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;\n#else\n    indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support\n    CIFilter *lighten = [CIFilter filterWithName:@\"CIColorControls\"];\n    [lighten setDefaults];\n    [lighten setValue:@(1) forKey:kCIInputBrightnessKey];\n    indicator.indicatorView.contentFilters = @[lighten];\n#endif\n    return indicator;\n}\n\n+ (SDWebImageActivityIndicator *)whiteLargeIndicator {\n    SDWebImageActivityIndicator *indicator = SDWebImageActivityIndicator.whiteIndicator;\n#if SD_UIKIT\n    indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;\n#else\n    indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support\n    indicator.indicatorView.controlSize = NSControlSizeRegular;\n    [indicator.indicatorView sizeToFit];\n#endif\n    return indicator;\n}\n\n+ (SDWebImageActivityIndicator *)largeIndicator {\n    SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new];\n#if SD_UIKIT\n    if (@available(iOS 13.0, tvOS 13.0, *)) {\n        indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleLarge;\n    } else {\n        indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;\n    }\n#else\n    indicator.indicatorView.controlSize = NSControlSizeRegular;\n    [indicator.indicatorView sizeToFit];\n#endif\n    return indicator;\n}\n\n+ (SDWebImageActivityIndicator *)mediumIndicator {\n    SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new];\n#if SD_UIKIT\n    if (@available(iOS 13.0, tvOS 13.0, *)) {\n        indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;\n    } else {\n        indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;\n    }\n#else\n    indicator.indicatorView.controlSize = NSControlSizeSmall;\n    [indicator.indicatorView sizeToFit];\n#endif\n    return indicator;\n}\n#pragma clang diagnostic pop\n\n@end\n\n#pragma mark - Progress Indicator\n\n@interface SDWebImageProgressIndicator ()\n\n#if SD_UIKIT\n@property (nonatomic, strong, readwrite, nonnull) UIProgressView *indicatorView;\n#else\n@property (nonatomic, strong, readwrite, nonnull) NSProgressIndicator *indicatorView;\n#endif\n\n@end\n\n@implementation SDWebImageProgressIndicator\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        [self commonInit];\n    }\n    return self;\n}\n\n#if SD_UIKIT\n- (void)commonInit {\n    self.indicatorView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];\n    self.indicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;\n}\n#endif\n\n#if SD_MAC\n- (void)commonInit {\n    self.indicatorView = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 160, 0)]; // Width from `UIProgressView` default width\n    self.indicatorView.style = NSProgressIndicatorStyleBar;\n    self.indicatorView.controlSize = NSControlSizeSmall;\n    [self.indicatorView sizeToFit];\n    self.indicatorView.autoresizingMask = NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;\n}\n#endif\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability\"\n- (void)startAnimatingIndicator {\n    self.indicatorView.hidden = NO;\n#if SD_UIKIT\n    if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) {\n        // Ignore NSProgress\n    } else {\n        self.indicatorView.progress = 0;\n    }\n#else\n    self.indicatorView.indeterminate = YES;\n    self.indicatorView.doubleValue = 0;\n    [self.indicatorView startAnimation:nil];\n#endif\n}\n\n- (void)stopAnimatingIndicator {\n    self.indicatorView.hidden = YES;\n#if SD_UIKIT\n    if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) {\n        // Ignore NSProgress\n    } else {\n        self.indicatorView.progress = 1;\n    }\n#else\n    self.indicatorView.indeterminate = NO;\n    self.indicatorView.doubleValue = 100;\n    [self.indicatorView stopAnimation:nil];\n#endif\n}\n\n- (void)updateIndicatorProgress:(double)progress {\n#if SD_UIKIT\n    if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) {\n        // Ignore NSProgress\n    } else {\n        [self.indicatorView setProgress:progress animated:YES];\n    }\n#else\n    self.indicatorView.indeterminate = progress > 0 ? NO : YES;\n    self.indicatorView.doubleValue = progress * 100;\n#endif\n}\n#pragma clang diagnostic pop\n\n@end\n\n@implementation SDWebImageProgressIndicator (Conveniences)\n\n+ (SDWebImageProgressIndicator *)defaultIndicator {\n    SDWebImageProgressIndicator *indicator = [SDWebImageProgressIndicator new];\n    return indicator;\n}\n\n#if SD_IOS\n+ (SDWebImageProgressIndicator *)barIndicator {\n    SDWebImageProgressIndicator *indicator = [SDWebImageProgressIndicator new];\n    indicator.indicatorView.progressViewStyle = UIProgressViewStyleBar;\n    return indicator;\n}\n#endif\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageOperation.h\"\n#import \"SDImageCacheDefine.h\"\n#import \"SDImageLoader.h\"\n#import \"SDImageTransformer.h\"\n#import \"SDWebImageCacheKeyFilter.h\"\n#import \"SDWebImageCacheSerializer.h\"\n#import \"SDWebImageOptionsProcessor.h\"\n\ntypedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);\n\ntypedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL);\n\n/**\n A combined operation representing the cache and loader operation. You can use it to cancel the load process.\n */\n@interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation>\n\n/**\n Cancel the current operation, including cache and loader process\n */\n- (void)cancel;\n\n/**\n The cache operation from the image cache query\n */\n@property (strong, nonatomic, nullable, readonly) id<SDWebImageOperation> cacheOperation;\n\n/**\n The loader operation from the image loader (such as download operation)\n */\n@property (strong, nonatomic, nullable, readonly) id<SDWebImageOperation> loaderOperation;\n\n@end\n\n\n@class SDWebImageManager;\n\n/**\n The manager delegate protocol.\n */\n@protocol SDWebImageManagerDelegate <NSObject>\n\n@optional\n\n/**\n * Controls which image should be downloaded when the image is not found in the cache.\n *\n * @param imageManager The current `SDWebImageManager`\n * @param imageURL     The url of the image to be downloaded\n *\n * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied.\n */\n- (BOOL)imageManager:(nonnull SDWebImageManager *)imageManager shouldDownloadImageForURL:(nonnull NSURL *)imageURL;\n\n/**\n * Controls the complicated logic to mark as failed URLs when download error occur.\n * If the delegate implement this method, we will not use the built-in way to mark URL as failed based on error code;\n @param imageManager The current `SDWebImageManager`\n @param imageURL The url of the image\n @param error The download error for the url\n @return Whether to block this url or not. Return YES to mark this URL as failed.\n */\n- (BOOL)imageManager:(nonnull SDWebImageManager *)imageManager shouldBlockFailedURL:(nonnull NSURL *)imageURL withError:(nonnull NSError *)error;\n\n@end\n\n/**\n * The SDWebImageManager is the class behind the UIImageView+WebCache category and likes.\n * It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache).\n * You can use this class directly to benefit from web image downloading with caching in another context than\n * a UIView.\n *\n * Here is a simple example of how to use SDWebImageManager:\n *\n * @code\n\nSDWebImageManager *manager = [SDWebImageManager sharedManager];\n[manager loadImageWithURL:imageURL\n                  options:0\n                 progress:nil\n                completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {\n                    if (image) {\n                        // do something with image\n                    }\n                }];\n\n * @endcode\n */\n@interface SDWebImageManager : NSObject\n\n/**\n * The delegate for manager. Defaults to nil.\n */\n@property (weak, nonatomic, nullable) id <SDWebImageManagerDelegate> delegate;\n\n/**\n * The image cache used by manager to query image cache.\n */\n@property (strong, nonatomic, readonly, nonnull) id<SDImageCache> imageCache;\n\n/**\n * The image loader used by manager to load image.\n */\n@property (strong, nonatomic, readonly, nonnull) id<SDImageLoader> imageLoader;\n\n/**\n The image transformer for manager. It's used for image transform after the image load finished and store the transformed image to cache, see `SDImageTransformer`.\n Defaults to nil, which means no transform is applied.\n @note This will affect all the load requests for this manager if you provide. However, you can pass `SDWebImageContextImageTransformer` in context arg to explicitly use that transformer instead.\n */\n@property (strong, nonatomic, nullable) id<SDImageTransformer> transformer;\n\n/**\n * The cache filter is used to convert an URL into a cache key each time SDWebImageManager need cache key to use image cache.\n *\n * The following example sets a filter in the application delegate that will remove any query-string from the\n * URL before to use it as a cache key:\n *\n * @code\n SDWebImageManager.sharedManager.cacheKeyFilter =[SDWebImageCacheKeyFilter cacheKeyFilterWithBlock:^NSString * _Nullable(NSURL * _Nonnull url) {\n    url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];\n    return [url absoluteString];\n }];\n * @endcode\n */\n@property (nonatomic, strong, nullable) id<SDWebImageCacheKeyFilter> cacheKeyFilter;\n\n/**\n * The cache serializer is used to convert the decoded image, the source downloaded data, to the actual data used for storing to the disk cache. If you return nil, means to generate the data from the image instance, see `SDImageCache`.\n * For example, if you are using WebP images and facing the slow decoding time issue when later retrieving from disk cache again. You can try to encode the decoded image to JPEG/PNG format to disk cache instead of source downloaded data.\n * @note The `image` arg is nonnull, but when you also provide an image transformer and the image is transformed, the `data` arg may be nil, take attention to this case.\n * @note This method is called from a global queue in order to not to block the main thread.\n * @code\n SDWebImageManager.sharedManager.cacheSerializer = [SDWebImageCacheSerializer cacheSerializerWithBlock:^NSData * _Nullable(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL) {\n    SDImageFormat format = [NSData sd_imageFormatForImageData:data];\n    switch (format) {\n        case SDImageFormatWebP:\n            return image.images ? data : nil;\n        default:\n            return data;\n    }\n}];\n * @endcode\n * The default value is nil. Means we just store the source downloaded data to disk cache.\n */\n@property (nonatomic, strong, nullable) id<SDWebImageCacheSerializer> cacheSerializer;\n\n/**\n The options processor is used, to have a global control for all the image request options and context option for current manager.\n @note If you use `transformer`, `cacheKeyFilter` or `cacheSerializer` property of manager, the input context option already apply those properties before passed. This options processor is a better replacement for those property in common usage.\n For example, you can control the global options, based on the URL or original context option like the below code.\n \n @code\n SDWebImageManager.sharedManager.optionsProcessor = [SDWebImageOptionsProcessor optionsProcessorWithBlock:^SDWebImageOptionsResult * _Nullable(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context) {\n     // Only do animation on `SDAnimatedImageView`\n     if (!context[SDWebImageContextAnimatedImageClass]) {\n        options |= SDWebImageDecodeFirstFrameOnly;\n     }\n     // Do not force decode for png url\n     if ([url.lastPathComponent isEqualToString:@\"png\"]) {\n        options |= SDWebImageAvoidDecodeImage;\n     }\n     // Always use screen scale factor\n     SDWebImageMutableContext *mutableContext = [NSDictionary dictionaryWithDictionary:context];\n     mutableContext[SDWebImageContextImageScaleFactor] = @(UIScreen.mainScreen.scale);\n     context = [mutableContext copy];\n \n     return [[SDWebImageOptionsResult alloc] initWithOptions:options context:context];\n }];\n @endcode\n */\n@property (nonatomic, strong, nullable) id<SDWebImageOptionsProcessor> optionsProcessor;\n\n/**\n * Check one or more operations running\n */\n@property (nonatomic, assign, readonly, getter=isRunning) BOOL running;\n\n/**\n The default image cache when the manager which is created with no arguments. Such as shared manager or init.\n Defaults to nil. Means using `SDImageCache.sharedImageCache`\n */\n@property (nonatomic, class, nullable) id<SDImageCache> defaultImageCache;\n\n/**\n The default image loader for manager which is created with no arguments. Such as shared manager or init.\n Defaults to nil. Means using `SDWebImageDownloader.sharedDownloader`\n */\n@property (nonatomic, class, nullable) id<SDImageLoader> defaultImageLoader;\n\n/**\n * Returns global shared manager instance.\n */\n@property (nonatomic, class, readonly, nonnull) SDWebImageManager *sharedManager;\n\n/**\n * Allows to specify instance of cache and image loader used with image manager.\n * @return new instance of `SDWebImageManager` with specified cache and loader.\n */\n- (nonnull instancetype)initWithCache:(nonnull id<SDImageCache>)cache loader:(nonnull id<SDImageLoader>)loader NS_DESIGNATED_INITIALIZER;\n\n/**\n * Downloads the image at the given URL if not present in cache or return the cached version otherwise.\n *\n * @param url            The URL to the image\n * @param options        A mask to specify options to use for this request\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed.\n *\n *   This parameter is required.\n * \n *   This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter.\n *   In case of error the image parameter is nil and the third parameter may contain an NSError.\n *\n *   The forth parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache\n *   or from the memory cache or from the network.\n *\n *   The fifth parameter is set to NO when the SDWebImageProgressiveLoad option is used and the image is\n *   downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the\n *   block is called a last time with the full image and the last parameter set to YES.\n *\n *   The last parameter is the original image URL\n *\n * @return Returns an instance of SDWebImageCombinedOperation, which you can cancel the loading process.\n */\n- (nullable SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url\n                                                   options:(SDWebImageOptions)options\n                                                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                                 completed:(nonnull SDInternalCompletionBlock)completedBlock;\n\n/**\n * Downloads the image at the given URL if not present in cache or return the cached version otherwise.\n *\n * @param url            The URL to the image\n * @param options        A mask to specify options to use for this request\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed.\n *\n * @return Returns an instance of SDWebImageCombinedOperation, which you can cancel the loading process.\n */\n- (nullable SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url\n                                                   options:(SDWebImageOptions)options\n                                                   context:(nullable SDWebImageContext *)context\n                                                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                                 completed:(nonnull SDInternalCompletionBlock)completedBlock;\n\n/**\n * Cancel all current operations\n */\n- (void)cancelAll;\n\n/**\n * Remove the specify URL from failed black list.\n * @param url The failed URL.\n */\n- (void)removeFailedURL:(nonnull NSURL *)url;\n\n/**\n * Remove all the URL from failed black list.\n */\n- (void)removeAllFailedURLs;\n\n/**\n * Return the cache key for a given URL, does not considerate transformer or thumbnail.\n * @note This method does not have context option, only use the url and manager level cacheKeyFilter to generate the cache key.\n */\n- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url;\n\n/**\n * Return the cache key for a given URL and context option.\n * @note The context option like `.thumbnailPixelSize` and `.imageTransformer` will effect the generated cache key, using this if you have those context associated.\n*/\n- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url context:(nullable SDWebImageContext *)context;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageManager.h\"\n#import \"SDImageCache.h\"\n#import \"SDWebImageDownloader.h\"\n#import \"UIImage+Metadata.h\"\n#import \"SDAssociatedObject.h\"\n#import \"SDWebImageError.h\"\n#import \"SDInternalMacros.h\"\n\nstatic id<SDImageCache> _defaultImageCache;\nstatic id<SDImageLoader> _defaultImageLoader;\n\n@interface SDWebImageCombinedOperation ()\n\n@property (assign, nonatomic, getter = isCancelled) BOOL cancelled;\n@property (strong, nonatomic, readwrite, nullable) id<SDWebImageOperation> loaderOperation;\n@property (strong, nonatomic, readwrite, nullable) id<SDWebImageOperation> cacheOperation;\n@property (weak, nonatomic, nullable) SDWebImageManager *manager;\n\n@end\n\n@interface SDWebImageManager () {\n    SD_LOCK_DECLARE(_failedURLsLock); // a lock to keep the access to `failedURLs` thread-safe\n    SD_LOCK_DECLARE(_runningOperationsLock); // a lock to keep the access to `runningOperations` thread-safe\n}\n\n@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache;\n@property (strong, nonatomic, readwrite, nonnull) id<SDImageLoader> imageLoader;\n@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;\n@property (strong, nonatomic, nonnull) NSMutableSet<SDWebImageCombinedOperation *> *runningOperations;\n\n@end\n\n@implementation SDWebImageManager\n\n+ (id<SDImageCache>)defaultImageCache {\n    return _defaultImageCache;\n}\n\n+ (void)setDefaultImageCache:(id<SDImageCache>)defaultImageCache {\n    if (defaultImageCache && ![defaultImageCache conformsToProtocol:@protocol(SDImageCache)]) {\n        return;\n    }\n    _defaultImageCache = defaultImageCache;\n}\n\n+ (id<SDImageLoader>)defaultImageLoader {\n    return _defaultImageLoader;\n}\n\n+ (void)setDefaultImageLoader:(id<SDImageLoader>)defaultImageLoader {\n    if (defaultImageLoader && ![defaultImageLoader conformsToProtocol:@protocol(SDImageLoader)]) {\n        return;\n    }\n    _defaultImageLoader = defaultImageLoader;\n}\n\n+ (nonnull instancetype)sharedManager {\n    static dispatch_once_t once;\n    static id instance;\n    dispatch_once(&once, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n- (nonnull instancetype)init {\n    id<SDImageCache> cache = [[self class] defaultImageCache];\n    if (!cache) {\n        cache = [SDImageCache sharedImageCache];\n    }\n    id<SDImageLoader> loader = [[self class] defaultImageLoader];\n    if (!loader) {\n        loader = [SDWebImageDownloader sharedDownloader];\n    }\n    return [self initWithCache:cache loader:loader];\n}\n\n- (nonnull instancetype)initWithCache:(nonnull id<SDImageCache>)cache loader:(nonnull id<SDImageLoader>)loader {\n    if ((self = [super init])) {\n        _imageCache = cache;\n        _imageLoader = loader;\n        _failedURLs = [NSMutableSet new];\n        SD_LOCK_INIT(_failedURLsLock);\n        _runningOperations = [NSMutableSet new];\n        SD_LOCK_INIT(_runningOperationsLock);\n    }\n    return self;\n}\n\n- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url {\n    if (!url) {\n        return @\"\";\n    }\n    \n    NSString *key;\n    // Cache Key Filter\n    id<SDWebImageCacheKeyFilter> cacheKeyFilter = self.cacheKeyFilter;\n    if (cacheKeyFilter) {\n        key = [cacheKeyFilter cacheKeyForURL:url];\n    } else {\n        key = url.absoluteString;\n    }\n    \n    return key;\n}\n\n- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url context:(nullable SDWebImageContext *)context {\n    if (!url) {\n        return @\"\";\n    }\n    \n    NSString *key;\n    // Cache Key Filter\n    id<SDWebImageCacheKeyFilter> cacheKeyFilter = self.cacheKeyFilter;\n    if (context[SDWebImageContextCacheKeyFilter]) {\n        cacheKeyFilter = context[SDWebImageContextCacheKeyFilter];\n    }\n    if (cacheKeyFilter) {\n        key = [cacheKeyFilter cacheKeyForURL:url];\n    } else {\n        key = url.absoluteString;\n    }\n    \n    // Thumbnail Key Appending\n    NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];\n    if (thumbnailSizeValue != nil) {\n        CGSize thumbnailSize = CGSizeZero;\n#if SD_MAC\n        thumbnailSize = thumbnailSizeValue.sizeValue;\n#else\n        thumbnailSize = thumbnailSizeValue.CGSizeValue;\n#endif\n        BOOL preserveAspectRatio = YES;\n        NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio];\n        if (preserveAspectRatioValue != nil) {\n            preserveAspectRatio = preserveAspectRatioValue.boolValue;\n        }\n        key = SDThumbnailedKeyForKey(key, thumbnailSize, preserveAspectRatio);\n    }\n    \n    // Transformer Key Appending\n    id<SDImageTransformer> transformer = self.transformer;\n    if (context[SDWebImageContextImageTransformer]) {\n        transformer = context[SDWebImageContextImageTransformer];\n        if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) {\n            transformer = nil;\n        }\n    }\n    if (transformer) {\n        key = SDTransformedKeyForKey(key, transformer.transformerKey);\n    }\n    \n    return key;\n}\n\n- (SDWebImageCombinedOperation *)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDInternalCompletionBlock)completedBlock {\n    return [self loadImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url\n                                          options:(SDWebImageOptions)options\n                                          context:(nullable SDWebImageContext *)context\n                                         progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                        completed:(nonnull SDInternalCompletionBlock)completedBlock {\n    // Invoking this method without a completedBlock is pointless\n    NSAssert(completedBlock != nil, @\"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead\");\n\n    // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, Xcode won't\n    // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString.\n    if ([url isKindOfClass:NSString.class]) {\n        url = [NSURL URLWithString:(NSString *)url];\n    }\n\n    // Prevents app crashing on argument type error like sending NSNull instead of NSURL\n    if (![url isKindOfClass:NSURL.class]) {\n        url = nil;\n    }\n\n    SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new];\n    operation.manager = self;\n\n    BOOL isFailedUrl = NO;\n    if (url) {\n        SD_LOCK(_failedURLsLock);\n        isFailedUrl = [self.failedURLs containsObject:url];\n        SD_UNLOCK(_failedURLsLock);\n    }\n\n    if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {\n        NSString *description = isFailedUrl ? @\"Image url is blacklisted\" : @\"Image url is nil\";\n        NSInteger code = isFailedUrl ? SDWebImageErrorBlackListed : SDWebImageErrorInvalidURL;\n        [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : description}] url:url];\n        return operation;\n    }\n\n    SD_LOCK(_runningOperationsLock);\n    [self.runningOperations addObject:operation];\n    SD_UNLOCK(_runningOperationsLock);\n    \n    // Preprocess the options and context arg to decide the final the result for manager\n    SDWebImageOptionsResult *result = [self processedResultForURL:url options:options context:context];\n    \n    // Start the entry to load image from cache\n    [self callCacheProcessForOperation:operation url:url options:result.options context:result.context progress:progressBlock completed:completedBlock];\n\n    return operation;\n}\n\n- (void)cancelAll {\n    SD_LOCK(_runningOperationsLock);\n    NSSet<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy];\n    SD_UNLOCK(_runningOperationsLock);\n    [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; // This will call `safelyRemoveOperationFromRunning:` and remove from the array\n}\n\n- (BOOL)isRunning {\n    BOOL isRunning = NO;\n    SD_LOCK(_runningOperationsLock);\n    isRunning = (self.runningOperations.count > 0);\n    SD_UNLOCK(_runningOperationsLock);\n    return isRunning;\n}\n\n- (void)removeFailedURL:(NSURL *)url {\n    if (!url) {\n        return;\n    }\n    SD_LOCK(_failedURLsLock);\n    [self.failedURLs removeObject:url];\n    SD_UNLOCK(_failedURLsLock);\n}\n\n- (void)removeAllFailedURLs {\n    SD_LOCK(_failedURLsLock);\n    [self.failedURLs removeAllObjects];\n    SD_UNLOCK(_failedURLsLock);\n}\n\n#pragma mark - Private\n\n// Query normal cache process\n- (void)callCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation\n                                 url:(nonnull NSURL *)url\n                             options:(SDWebImageOptions)options\n                             context:(nullable SDWebImageContext *)context\n                            progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                           completed:(nullable SDInternalCompletionBlock)completedBlock {\n    // Grab the image cache to use\n    id<SDImageCache> imageCache;\n    if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n        imageCache = context[SDWebImageContextImageCache];\n    } else {\n        imageCache = self.imageCache;\n    }\n    // Get the query cache type\n    SDImageCacheType queryCacheType = SDImageCacheTypeAll;\n    if (context[SDWebImageContextQueryCacheType]) {\n        queryCacheType = [context[SDWebImageContextQueryCacheType] integerValue];\n    }\n    \n    // Check whether we should query cache\n    BOOL shouldQueryCache = !SD_OPTIONS_CONTAINS(options, SDWebImageFromLoaderOnly);\n    if (shouldQueryCache) {\n        NSString *key = [self cacheKeyForURL:url context:context];\n        @weakify(operation);\n        operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) {\n            @strongify(operation);\n            if (!operation || operation.isCancelled) {\n                // Image combined operation cancelled by user\n                [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user during querying the cache\"}] url:url];\n                [self safelyRemoveOperationFromRunning:operation];\n                return;\n            } else if (context[SDWebImageContextImageTransformer] && !cachedImage) {\n                // Have a chance to query original cache instead of downloading\n                [self callOriginalCacheProcessForOperation:operation url:url options:options context:context progress:progressBlock completed:completedBlock];\n                return;\n            }\n            \n            // Continue download process\n            [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:cachedImage cachedData:cachedData cacheType:cacheType progress:progressBlock completed:completedBlock];\n        }];\n    } else {\n        // Continue download process\n        [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:SDImageCacheTypeNone progress:progressBlock completed:completedBlock];\n    }\n}\n\n// Query original cache process\n- (void)callOriginalCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation\n                                         url:(nonnull NSURL *)url\n                                     options:(SDWebImageOptions)options\n                                     context:(nullable SDWebImageContext *)context\n                                    progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                   completed:(nullable SDInternalCompletionBlock)completedBlock {\n    // Grab the image cache to use, choose standalone original cache firstly\n    id<SDImageCache> imageCache;\n    if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n        imageCache = context[SDWebImageContextOriginalImageCache];\n    } else {\n        // if no standalone cache available, use default cache\n        if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n            imageCache = context[SDWebImageContextImageCache];\n        } else {\n            imageCache = self.imageCache;\n        }\n    }\n    // Get the original query cache type\n    SDImageCacheType originalQueryCacheType = SDImageCacheTypeDisk;\n    if (context[SDWebImageContextOriginalQueryCacheType]) {\n        originalQueryCacheType = [context[SDWebImageContextOriginalQueryCacheType] integerValue];\n    }\n    \n    // Check whether we should query original cache\n    BOOL shouldQueryOriginalCache = (originalQueryCacheType != SDImageCacheTypeNone);\n    if (shouldQueryOriginalCache) {\n        // Disable transformer for original cache key generation\n        SDWebImageMutableContext *tempContext = [context mutableCopy];\n        tempContext[SDWebImageContextImageTransformer] = [NSNull null];\n        NSString *key = [self cacheKeyForURL:url context:tempContext];\n        @weakify(operation);\n        operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context cacheType:originalQueryCacheType completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) {\n            @strongify(operation);\n            if (!operation || operation.isCancelled) {\n                // Image combined operation cancelled by user\n                [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user during querying the cache\"}] url:url];\n                [self safelyRemoveOperationFromRunning:operation];\n                return;\n            } else if (context[SDWebImageContextImageTransformer] && !cachedImage) {\n                // Original image cache miss. Continue download process\n                [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:originalQueryCacheType progress:progressBlock completed:completedBlock];\n                return;\n            }\n                        \n            // Use the store cache process instead of downloading, and ignore .refreshCached option for now\n            [self callStoreCacheProcessForOperation:operation url:url options:options context:context downloadedImage:cachedImage downloadedData:cachedData finished:YES progress:progressBlock completed:completedBlock];\n            \n            [self safelyRemoveOperationFromRunning:operation];\n        }];\n    } else {\n        // Continue download process\n        [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:originalQueryCacheType progress:progressBlock completed:completedBlock];\n    }\n}\n\n// Download process\n- (void)callDownloadProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation\n                                    url:(nonnull NSURL *)url\n                                options:(SDWebImageOptions)options\n                                context:(SDWebImageContext *)context\n                            cachedImage:(nullable UIImage *)cachedImage\n                             cachedData:(nullable NSData *)cachedData\n                              cacheType:(SDImageCacheType)cacheType\n                               progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                              completed:(nullable SDInternalCompletionBlock)completedBlock {\n    // Grab the image loader to use\n    id<SDImageLoader> imageLoader;\n    if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) {\n        imageLoader = context[SDWebImageContextImageLoader];\n    } else {\n        imageLoader = self.imageLoader;\n    }\n    \n    // Check whether we should download image from network\n    BOOL shouldDownload = !SD_OPTIONS_CONTAINS(options, SDWebImageFromCacheOnly);\n    shouldDownload &= (!cachedImage || options & SDWebImageRefreshCached);\n    shouldDownload &= (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]);\n    if ([imageLoader respondsToSelector:@selector(canRequestImageForURL:options:context:)]) {\n        shouldDownload &= [imageLoader canRequestImageForURL:url options:options context:context];\n    } else {\n        shouldDownload &= [imageLoader canRequestImageForURL:url];\n    }\n    if (shouldDownload) {\n        if (cachedImage && options & SDWebImageRefreshCached) {\n            // If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image\n            // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.\n            [self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];\n            // Pass the cached image to the image loader. The image loader should check whether the remote image is equal to the cached image.\n            SDWebImageMutableContext *mutableContext;\n            if (context) {\n                mutableContext = [context mutableCopy];\n            } else {\n                mutableContext = [NSMutableDictionary dictionary];\n            }\n            mutableContext[SDWebImageContextLoaderCachedImage] = cachedImage;\n            context = [mutableContext copy];\n        }\n        \n        @weakify(operation);\n        operation.loaderOperation = [imageLoader requestImageWithURL:url options:options context:context progress:progressBlock completed:^(UIImage *downloadedImage, NSData *downloadedData, NSError *error, BOOL finished) {\n            @strongify(operation);\n            if (!operation || operation.isCancelled) {\n                // Image combined operation cancelled by user\n                [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @\"Operation cancelled by user during sending the request\"}] url:url];\n            } else if (cachedImage && options & SDWebImageRefreshCached && [error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCacheNotModified) {\n                // Image refresh hit the NSURLCache cache, do not call the completion block\n            } else if ([error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCancelled) {\n                // Download operation cancelled by user before sending the request, don't block failed URL\n                [self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url];\n            } else if (error) {\n                [self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url];\n                BOOL shouldBlockFailedURL = [self shouldBlockFailedURLWithURL:url error:error options:options context:context];\n                \n                if (shouldBlockFailedURL) {\n                    SD_LOCK(self->_failedURLsLock);\n                    [self.failedURLs addObject:url];\n                    SD_UNLOCK(self->_failedURLsLock);\n                }\n            } else {\n                if ((options & SDWebImageRetryFailed)) {\n                    SD_LOCK(self->_failedURLsLock);\n                    [self.failedURLs removeObject:url];\n                    SD_UNLOCK(self->_failedURLsLock);\n                }\n                // Continue store cache process\n                [self callStoreCacheProcessForOperation:operation url:url options:options context:context downloadedImage:downloadedImage downloadedData:downloadedData finished:finished progress:progressBlock completed:completedBlock];\n            }\n            \n            if (finished) {\n                [self safelyRemoveOperationFromRunning:operation];\n            }\n        }];\n    } else if (cachedImage) {\n        [self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];\n        [self safelyRemoveOperationFromRunning:operation];\n    } else {\n        // Image not in cache and download disallowed by delegate\n        [self callCompletionBlockForOperation:operation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES url:url];\n        [self safelyRemoveOperationFromRunning:operation];\n    }\n}\n\n// Store cache process\n- (void)callStoreCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation\n                                      url:(nonnull NSURL *)url\n                                  options:(SDWebImageOptions)options\n                                  context:(SDWebImageContext *)context\n                          downloadedImage:(nullable UIImage *)downloadedImage\n                           downloadedData:(nullable NSData *)downloadedData\n                                 finished:(BOOL)finished\n                                 progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                                completed:(nullable SDInternalCompletionBlock)completedBlock {\n    // Grab the image cache to use, choose standalone original cache firstly\n    id<SDImageCache> imageCache;\n    if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n        imageCache = context[SDWebImageContextOriginalImageCache];\n    } else {\n        // if no standalone cache available, use default cache\n        if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n            imageCache = context[SDWebImageContextImageCache];\n        } else {\n            imageCache = self.imageCache;\n        }\n    }\n    // the target image store cache type\n    SDImageCacheType storeCacheType = SDImageCacheTypeAll;\n    if (context[SDWebImageContextStoreCacheType]) {\n        storeCacheType = [context[SDWebImageContextStoreCacheType] integerValue];\n    }\n    // the original store image cache type\n    SDImageCacheType originalStoreCacheType = SDImageCacheTypeDisk;\n    if (context[SDWebImageContextOriginalStoreCacheType]) {\n        originalStoreCacheType = [context[SDWebImageContextOriginalStoreCacheType] integerValue];\n    }\n    // Disable transformer for original cache key generation\n    SDWebImageMutableContext *tempContext = [context mutableCopy];\n    tempContext[SDWebImageContextImageTransformer] = [NSNull null];\n    NSString *key = [self cacheKeyForURL:url context:tempContext];\n    id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];\n    if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) {\n        transformer = nil;\n    }\n    id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];\n    \n    BOOL shouldTransformImage = downloadedImage && transformer;\n    shouldTransformImage = shouldTransformImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage));\n    shouldTransformImage = shouldTransformImage && (!downloadedImage.sd_isVector || (options & SDWebImageTransformVectorImage));\n    BOOL shouldCacheOriginal = downloadedImage && finished;\n    \n    // if available, store original image to cache\n    if (shouldCacheOriginal) {\n        // normally use the store cache type, but if target image is transformed, use original store cache type instead\n        SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType;\n        if (cacheSerializer && (targetStoreCacheType == SDImageCacheTypeDisk || targetStoreCacheType == SDImageCacheTypeAll)) {\n            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{\n                @autoreleasepool {\n                    NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url];\n                    [self storeImage:downloadedImage imageData:cacheData forKey:key imageCache:imageCache cacheType:targetStoreCacheType options:options context:context completion:^{\n                        // Continue transform process\n                        [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock];\n                    }];\n                }\n            });\n        } else {\n            [self storeImage:downloadedImage imageData:downloadedData forKey:key imageCache:imageCache cacheType:targetStoreCacheType options:options context:context completion:^{\n                // Continue transform process\n                [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock];\n            }];\n        }\n    } else {\n        // Continue transform process\n        [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock];\n    }\n}\n\n// Transform process\n- (void)callTransformProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation\n                                     url:(nonnull NSURL *)url\n                                 options:(SDWebImageOptions)options\n                                 context:(SDWebImageContext *)context\n                           originalImage:(nullable UIImage *)originalImage\n                            originalData:(nullable NSData *)originalData\n                                finished:(BOOL)finished\n                                progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                               completed:(nullable SDInternalCompletionBlock)completedBlock {\n    // Grab the image cache to use\n    id<SDImageCache> imageCache;\n    if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {\n        imageCache = context[SDWebImageContextImageCache];\n    } else {\n        imageCache = self.imageCache;\n    }\n    // the target image store cache type\n    SDImageCacheType storeCacheType = SDImageCacheTypeAll;\n    if (context[SDWebImageContextStoreCacheType]) {\n        storeCacheType = [context[SDWebImageContextStoreCacheType] integerValue];\n    }\n    // transformed cache key\n    NSString *key = [self cacheKeyForURL:url context:context];\n    id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];\n    if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) {\n        transformer = nil;\n    }\n    id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];\n    \n    BOOL shouldTransformImage = originalImage && transformer;\n    shouldTransformImage = shouldTransformImage && (!originalImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage));\n    shouldTransformImage = shouldTransformImage && (!originalImage.sd_isVector || (options & SDWebImageTransformVectorImage));\n    // if available, store transformed image to cache\n    if (shouldTransformImage) {\n        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{\n            @autoreleasepool {\n                UIImage *transformedImage = [transformer transformedImageWithImage:originalImage forKey:key];\n                if (transformedImage && finished) {\n                    BOOL imageWasTransformed = ![transformedImage isEqual:originalImage];\n                    NSData *cacheData;\n                    // pass nil if the image was transformed, so we can recalculate the data from the image\n                    if (cacheSerializer && (storeCacheType == SDImageCacheTypeDisk || storeCacheType == SDImageCacheTypeAll)) {\n                        cacheData = [cacheSerializer cacheDataWithImage:transformedImage originalData:(imageWasTransformed ? nil : originalData) imageURL:url];\n                    } else {\n                        cacheData = (imageWasTransformed ? nil : originalData);\n                    }\n                    [self storeImage:transformedImage imageData:cacheData forKey:key imageCache:imageCache cacheType:storeCacheType options:options context:context completion:^{\n                        [self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];\n                    }];\n                } else {\n                    [self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];\n                }\n            }\n        });\n    } else {\n        [self callCompletionBlockForOperation:operation completion:completedBlock image:originalImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];\n    }\n}\n\n#pragma mark - Helper\n\n- (void)safelyRemoveOperationFromRunning:(nullable SDWebImageCombinedOperation*)operation {\n    if (!operation) {\n        return;\n    }\n    SD_LOCK(_runningOperationsLock);\n    [self.runningOperations removeObject:operation];\n    SD_UNLOCK(_runningOperationsLock);\n}\n\n- (void)storeImage:(nullable UIImage *)image\n         imageData:(nullable NSData *)data\n            forKey:(nullable NSString *)key\n        imageCache:(nonnull id<SDImageCache>)imageCache\n         cacheType:(SDImageCacheType)cacheType\n           options:(SDWebImageOptions)options\n           context:(nullable SDWebImageContext *)context\n        completion:(nullable SDWebImageNoParamsBlock)completion {\n    BOOL waitStoreCache = SD_OPTIONS_CONTAINS(options, SDWebImageWaitStoreCache);\n    // Check whether we should wait the store cache finished. If not, callback immediately\n    [imageCache storeImage:image imageData:data forKey:key cacheType:cacheType completion:^{\n        if (waitStoreCache) {\n            if (completion) {\n                completion();\n            }\n        }\n    }];\n    if (!waitStoreCache) {\n        if (completion) {\n            completion();\n        }\n    }\n}\n\n- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation\n                             completion:(nullable SDInternalCompletionBlock)completionBlock\n                                  error:(nullable NSError *)error\n                                    url:(nullable NSURL *)url {\n    [self callCompletionBlockForOperation:operation completion:completionBlock image:nil data:nil error:error cacheType:SDImageCacheTypeNone finished:YES url:url];\n}\n\n- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation\n                             completion:(nullable SDInternalCompletionBlock)completionBlock\n                                  image:(nullable UIImage *)image\n                                   data:(nullable NSData *)data\n                                  error:(nullable NSError *)error\n                              cacheType:(SDImageCacheType)cacheType\n                               finished:(BOOL)finished\n                                    url:(nullable NSURL *)url {\n    dispatch_main_async_safe(^{\n        if (completionBlock) {\n            completionBlock(image, data, error, cacheType, finished, url);\n        }\n    });\n}\n\n- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url\n                              error:(nonnull NSError *)error\n                            options:(SDWebImageOptions)options\n                            context:(nullable SDWebImageContext *)context {\n    id<SDImageLoader> imageLoader;\n    if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) {\n        imageLoader = context[SDWebImageContextImageLoader];\n    } else {\n        imageLoader = self.imageLoader;\n    }\n    // Check whether we should block failed url\n    BOOL shouldBlockFailedURL;\n    if ([self.delegate respondsToSelector:@selector(imageManager:shouldBlockFailedURL:withError:)]) {\n        shouldBlockFailedURL = [self.delegate imageManager:self shouldBlockFailedURL:url withError:error];\n    } else {\n        if ([imageLoader respondsToSelector:@selector(shouldBlockFailedURLWithURL:error:options:context:)]) {\n            shouldBlockFailedURL = [imageLoader shouldBlockFailedURLWithURL:url error:error options:options context:context];\n        } else {\n            shouldBlockFailedURL = [imageLoader shouldBlockFailedURLWithURL:url error:error];\n        }\n    }\n    \n    return shouldBlockFailedURL;\n}\n\n- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context {\n    SDWebImageOptionsResult *result;\n    SDWebImageMutableContext *mutableContext = [SDWebImageMutableContext dictionary];\n    \n    // Image Transformer from manager\n    if (!context[SDWebImageContextImageTransformer]) {\n        id<SDImageTransformer> transformer = self.transformer;\n        [mutableContext setValue:transformer forKey:SDWebImageContextImageTransformer];\n    }\n    // Cache key filter from manager\n    if (!context[SDWebImageContextCacheKeyFilter]) {\n        id<SDWebImageCacheKeyFilter> cacheKeyFilter = self.cacheKeyFilter;\n        [mutableContext setValue:cacheKeyFilter forKey:SDWebImageContextCacheKeyFilter];\n    }\n    // Cache serializer from manager\n    if (!context[SDWebImageContextCacheSerializer]) {\n        id<SDWebImageCacheSerializer> cacheSerializer = self.cacheSerializer;\n        [mutableContext setValue:cacheSerializer forKey:SDWebImageContextCacheSerializer];\n    }\n    \n    if (mutableContext.count > 0) {\n        if (context) {\n            [mutableContext addEntriesFromDictionary:context];\n        }\n        context = [mutableContext copy];\n    }\n    \n    // Apply options processor\n    if (self.optionsProcessor) {\n        result = [self.optionsProcessor processedResultForURL:url options:options context:context];\n    }\n    if (!result) {\n        // Use default options result\n        result = [[SDWebImageOptionsResult alloc] initWithOptions:options context:context];\n    }\n    \n    return result;\n}\n\n@end\n\n\n@implementation SDWebImageCombinedOperation\n\n- (void)cancel {\n    @synchronized(self) {\n        if (self.isCancelled) {\n            return;\n        }\n        self.cancelled = YES;\n        if (self.cacheOperation) {\n            [self.cacheOperation cancel];\n            self.cacheOperation = nil;\n        }\n        if (self.loaderOperation) {\n            [self.loaderOperation cancel];\n            self.loaderOperation = nil;\n        }\n        [self.manager safelyRemoveOperationFromRunning:self];\n    }\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n\n/// A protocol represents cancelable operation.\n@protocol SDWebImageOperation <NSObject>\n\n- (void)cancel;\n\n@end\n\n/// NSOperation conform to `SDWebImageOperation`.\n@interface NSOperation (SDWebImageOperation) <SDWebImageOperation>\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageOperation.h\"\n\n/// NSOperation conform to `SDWebImageOperation`.\n@implementation NSOperation (SDWebImageOperation)\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n\n@class SDWebImageOptionsResult;\n\ntypedef SDWebImageOptionsResult * _Nullable(^SDWebImageOptionsProcessorBlock)(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context);\n\n/**\n The options result contains both options and context.\n */\n@interface SDWebImageOptionsResult : NSObject\n\n/**\n WebCache options.\n */\n@property (nonatomic, assign, readonly) SDWebImageOptions options;\n\n/**\n Context options.\n */\n@property (nonatomic, copy, readonly, nullable) SDWebImageContext *context;\n\n/**\n Create a new options result.\n\n @param options options\n @param context context\n @return The options result contains both options and context.\n */\n- (nonnull instancetype)initWithOptions:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context;\n\n@end\n\n/**\n This is the protocol for options processor.\n Options processor can be used, to control the final result for individual image request's `SDWebImageOptions` and `SDWebImageContext`\n Implements the protocol to have a global control for each indivadual image request's option.\n */\n@protocol SDWebImageOptionsProcessor <NSObject>\n\n/**\n Return the processed options result for specify image URL, with its options and context\n\n @param url The URL to the image\n @param options A mask to specify options to use for this request\n @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n @return The processed result, contains both options and context\n */\n- (nullable SDWebImageOptionsResult *)processedResultForURL:(nullable NSURL *)url\n                                                    options:(SDWebImageOptions)options\n                                                    context:(nullable SDWebImageContext *)context;\n\n@end\n\n/**\n A options processor class with block.\n */\n@interface SDWebImageOptionsProcessor : NSObject<SDWebImageOptionsProcessor>\n\n- (nonnull instancetype)initWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block;\n+ (nonnull instancetype)optionsProcessorWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageOptionsProcessor.h\"\n\n@interface SDWebImageOptionsResult ()\n\n@property (nonatomic, assign) SDWebImageOptions options;\n@property (nonatomic, copy, nullable) SDWebImageContext *context;\n\n@end\n\n@implementation SDWebImageOptionsResult\n\n- (instancetype)initWithOptions:(SDWebImageOptions)options context:(SDWebImageContext *)context {\n    self = [super init];\n    if (self) {\n        self.options = options;\n        self.context = context;\n    }\n    return self;\n}\n\n@end\n\n@interface SDWebImageOptionsProcessor ()\n\n@property (nonatomic, copy, nonnull) SDWebImageOptionsProcessorBlock block;\n\n@end\n\n@implementation SDWebImageOptionsProcessor\n\n- (instancetype)initWithBlock:(SDWebImageOptionsProcessorBlock)block {\n    self = [super init];\n    if (self) {\n        self.block = block;\n    }\n    return self;\n}\n\n+ (instancetype)optionsProcessorWithBlock:(SDWebImageOptionsProcessorBlock)block {\n    SDWebImageOptionsProcessor *optionsProcessor = [[SDWebImageOptionsProcessor alloc] initWithBlock:block];\n    return optionsProcessor;\n}\n\n- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context {\n    if (!self.block) {\n        return nil;\n    }\n    return self.block(url, options, context);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageManager.h\"\n\n@class SDWebImagePrefetcher;\n\n/**\n A token represents a list of URLs, can be used to cancel the download.\n */\n@interface SDWebImagePrefetchToken : NSObject <SDWebImageOperation>\n\n/**\n * Cancel the current prefetching.\n */\n- (void)cancel;\n\n/**\n list of URLs of current prefetching.\n */\n@property (nonatomic, copy, readonly, nullable) NSArray<NSURL *> *urls;\n\n@end\n\n/**\n The prefetcher delegate protocol\n */\n@protocol SDWebImagePrefetcherDelegate <NSObject>\n\n@optional\n\n/**\n * Called when an image was prefetched. Which means it's called when one URL from any of prefetching finished.\n *\n * @param imagePrefetcher The current image prefetcher\n * @param imageURL        The image url that was prefetched\n * @param finishedCount   The total number of images that were prefetched (successful or not)\n * @param totalCount      The total number of images that were to be prefetched\n */\n- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;\n\n/**\n * Called when all images are prefetched. Which means it's called when all URLs from all of prefetching finished.\n * @param imagePrefetcher The current image prefetcher\n * @param totalCount      The total number of images that were prefetched (whether successful or not)\n * @param skippedCount    The total number of images that were skipped\n */\n- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;\n\n@end\n\ntypedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls);\ntypedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls);\n\n/**\n * Prefetch some URLs in the cache for future use. Images are downloaded in low priority.\n */\n@interface SDWebImagePrefetcher : NSObject\n\n/**\n * The web image manager used by prefetcher to prefetch images.\n * @note You can specify a standalone manager and downloader with custom configuration suitable for image prefetching. Such as `currentDownloadCount` or `downloadTimeout`.\n */\n@property (strong, nonatomic, readonly, nonnull) SDWebImageManager *manager;\n\n/**\n * Maximum number of URLs to prefetch at the same time. Defaults to 3.\n */\n@property (nonatomic, assign) NSUInteger maxConcurrentPrefetchCount;\n\n/**\n * The options for prefetcher. Defaults to SDWebImageLowPriority.\n */\n@property (nonatomic, assign) SDWebImageOptions options;\n\n/**\n * The context for prefetcher. Defaults to nil.\n */\n@property (nonatomic, copy, nullable) SDWebImageContext *context;\n\n/**\n * Queue options for prefetcher when call the progressBlock, completionBlock and delegate methods. Defaults to Main Queue.\n * @note The call is asynchronously to avoid blocking target queue.\n * @note The delegate queue should be set before any prefetching start and may not be changed during prefetching to avoid thread-safe problem.\n */\n@property (strong, nonatomic, nonnull) dispatch_queue_t delegateQueue;\n\n/**\n * The delegate for the prefetcher. Defaults to nil.\n */\n@property (weak, nonatomic, nullable) id <SDWebImagePrefetcherDelegate> delegate;\n\n/**\n * Returns the global shared image prefetcher instance. It use a standalone manager which is different from shared manager.\n */\n@property (nonatomic, class, readonly, nonnull) SDWebImagePrefetcher *sharedImagePrefetcher;\n\n/**\n * Allows you to instantiate a prefetcher with any arbitrary image manager.\n */\n- (nonnull instancetype)initWithImageManager:(nonnull SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER;\n\n/**\n * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property.\n * Prefetching is separate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls.\n * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch.\n *\n * @param urls list of URLs to prefetch\n * @return the token to cancel the current prefetching.\n */\n- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls;\n\n/**\n * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property.\n * Prefetching is separate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls.\n * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch.\n *\n * @param urls            list of URLs to prefetch\n * @param progressBlock   block to be called when progress updates; \n *                        first parameter is the number of completed (successful or not) requests, \n *                        second parameter is the total number of images originally requested to be prefetched\n * @param completionBlock block to be called when the current prefetching is completed\n *                        first param is the number of completed (successful or not) requests,\n *                        second parameter is the number of skipped requests\n * @return the token to cancel the current prefetching.\n */\n- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls\n                                          progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock\n                                         completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock;\n\n/**\n * Remove and cancel all the prefeching for the prefetcher.\n */\n- (void)cancelPrefetching;\n\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImagePrefetcher.h\"\n#import \"SDAsyncBlockOperation.h\"\n#import \"SDInternalMacros.h\"\n#import <stdatomic.h>\n\n@interface SDWebImagePrefetchToken () {\n    @public\n    // Though current implementation, `SDWebImageManager` completion block is always on main queue. But however, there is no guarantee in docs. And we may introduce config to specify custom queue in the future.\n    // These value are just used as incrementing counter, keep thread-safe using memory_order_relaxed for performance.\n    atomic_ulong _skippedCount;\n    atomic_ulong _finishedCount;\n    atomic_flag  _isAllFinished;\n    \n    unsigned long _totalCount;\n    \n    // Used to ensure NSPointerArray thread safe\n    SD_LOCK_DECLARE(_prefetchOperationsLock);\n    SD_LOCK_DECLARE(_loadOperationsLock);\n}\n\n@property (nonatomic, copy, readwrite) NSArray<NSURL *> *urls;\n@property (nonatomic, strong) NSPointerArray *loadOperations;\n@property (nonatomic, strong) NSPointerArray *prefetchOperations;\n@property (nonatomic, weak) SDWebImagePrefetcher *prefetcher;\n@property (nonatomic, copy, nullable) SDWebImagePrefetcherCompletionBlock completionBlock;\n@property (nonatomic, copy, nullable) SDWebImagePrefetcherProgressBlock progressBlock;\n\n@end\n\n@interface SDWebImagePrefetcher ()\n\n@property (strong, nonatomic, nonnull) SDWebImageManager *manager;\n@property (strong, atomic, nonnull) NSMutableSet<SDWebImagePrefetchToken *> *runningTokens;\n@property (strong, nonatomic, nonnull) NSOperationQueue *prefetchQueue;\n\n@end\n\n@implementation SDWebImagePrefetcher\n\n+ (nonnull instancetype)sharedImagePrefetcher {\n    static dispatch_once_t once;\n    static id instance;\n    dispatch_once(&once, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n- (nonnull instancetype)init {\n    return [self initWithImageManager:[SDWebImageManager new]];\n}\n\n- (nonnull instancetype)initWithImageManager:(SDWebImageManager *)manager {\n    if ((self = [super init])) {\n        _manager = manager;\n        _runningTokens = [NSMutableSet set];\n        _options = SDWebImageLowPriority;\n        _delegateQueue = dispatch_get_main_queue();\n        _prefetchQueue = [NSOperationQueue new];\n        self.maxConcurrentPrefetchCount = 3;\n    }\n    return self;\n}\n\n- (void)setMaxConcurrentPrefetchCount:(NSUInteger)maxConcurrentPrefetchCount {\n    self.prefetchQueue.maxConcurrentOperationCount = maxConcurrentPrefetchCount;\n}\n\n- (NSUInteger)maxConcurrentPrefetchCount {\n    return self.prefetchQueue.maxConcurrentOperationCount;\n}\n\n#pragma mark - Prefetch\n- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls {\n    return [self prefetchURLs:urls progress:nil completed:nil];\n}\n\n- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls\n                                          progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock\n                                         completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock {\n    if (!urls || urls.count == 0) {\n        if (completionBlock) {\n            completionBlock(0, 0);\n        }\n        return nil;\n    }\n    SDWebImagePrefetchToken *token = [SDWebImagePrefetchToken new];\n    token.prefetcher = self;\n    token.urls = urls;\n    token->_skippedCount = 0;\n    token->_finishedCount = 0;\n    token->_totalCount = token.urls.count;\n    atomic_flag_clear(&(token->_isAllFinished));\n    token.loadOperations = [NSPointerArray weakObjectsPointerArray];\n    token.prefetchOperations = [NSPointerArray weakObjectsPointerArray];\n    token.progressBlock = progressBlock;\n    token.completionBlock = completionBlock;\n    [self addRunningToken:token];\n    [self startPrefetchWithToken:token];\n    \n    return token;\n}\n\n- (void)startPrefetchWithToken:(SDWebImagePrefetchToken * _Nonnull)token {\n    for (NSURL *url in token.urls) {\n        @autoreleasepool {\n            @weakify(self);\n            SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) {\n                @strongify(self);\n                if (!self || asyncOperation.isCancelled) {\n                    return;\n                }\n                id<SDWebImageOperation> operation = [self.manager loadImageWithURL:url options:self.options context:self.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                    @strongify(self);\n                    if (!self) {\n                        return;\n                    }\n                    if (!finished) {\n                        return;\n                    }\n                    atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed);\n                    if (error) {\n                        // Add last failed\n                        atomic_fetch_add_explicit(&(token->_skippedCount), 1, memory_order_relaxed);\n                    }\n                    \n                    // Current operation finished\n                    [self callProgressBlockForToken:token imageURL:imageURL];\n                    \n                    if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) == token->_totalCount) {\n                        // All finished\n                        if (!atomic_flag_test_and_set_explicit(&(token->_isAllFinished), memory_order_relaxed)) {\n                            [self callCompletionBlockForToken:token];\n                            [self removeRunningToken:token];\n                        }\n                    }\n                    [asyncOperation complete];\n                }];\n                NSAssert(operation != nil, @\"Operation should not be nil, [SDWebImageManager loadImageWithURL:options:context:progress:completed:] break prefetch logic\");\n                SD_LOCK(token->_loadOperationsLock);\n                [token.loadOperations addPointer:(__bridge void *)operation];\n                SD_UNLOCK(token->_loadOperationsLock);\n            }];\n            SD_LOCK(token->_prefetchOperationsLock);\n            [token.prefetchOperations addPointer:(__bridge void *)prefetchOperation];\n            SD_UNLOCK(token->_prefetchOperationsLock);\n            [self.prefetchQueue addOperation:prefetchOperation];\n        }\n    }\n}\n\n#pragma mark - Cancel\n- (void)cancelPrefetching {\n    @synchronized(self.runningTokens) {\n        NSSet<SDWebImagePrefetchToken *> *copiedTokens = [self.runningTokens copy];\n        [copiedTokens makeObjectsPerformSelector:@selector(cancel)];\n        [self.runningTokens removeAllObjects];\n    }\n}\n\n- (void)callProgressBlockForToken:(SDWebImagePrefetchToken *)token imageURL:(NSURL *)url {\n    if (!token) {\n        return;\n    }\n    BOOL shouldCallDelegate = [self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)];\n    NSUInteger tokenFinishedCount = [self tokenFinishedCount];\n    NSUInteger tokenTotalCount = [self tokenTotalCount];\n    NSUInteger finishedCount = atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed);\n    NSUInteger totalCount = token->_totalCount;\n    dispatch_async(self.delegateQueue, ^{\n        if (shouldCallDelegate) {\n            [self.delegate imagePrefetcher:self didPrefetchURL:url finishedCount:tokenFinishedCount totalCount:tokenTotalCount];\n        }\n        if (token.progressBlock) {\n            token.progressBlock(finishedCount, totalCount);\n        }\n    });\n}\n\n- (void)callCompletionBlockForToken:(SDWebImagePrefetchToken *)token {\n    if (!token) {\n        return;\n    }\n    BOOL shoulCallDelegate = [self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)] && ([self countOfRunningTokens] == 1); // last one\n    NSUInteger tokenTotalCount = [self tokenTotalCount];\n    NSUInteger tokenSkippedCount = [self tokenSkippedCount];\n    NSUInteger finishedCount = atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed);\n    NSUInteger skippedCount = atomic_load_explicit(&(token->_skippedCount), memory_order_relaxed);\n    dispatch_async(self.delegateQueue, ^{\n        if (shoulCallDelegate) {\n            [self.delegate imagePrefetcher:self didFinishWithTotalCount:tokenTotalCount skippedCount:tokenSkippedCount];\n        }\n        if (token.completionBlock) {\n            token.completionBlock(finishedCount, skippedCount);\n        }\n    });\n}\n\n#pragma mark - Helper\n- (NSUInteger)tokenTotalCount {\n    NSUInteger tokenTotalCount = 0;\n    @synchronized (self.runningTokens) {\n        for (SDWebImagePrefetchToken *token in self.runningTokens) {\n            tokenTotalCount += token->_totalCount;\n        }\n    }\n    return tokenTotalCount;\n}\n\n- (NSUInteger)tokenSkippedCount {\n    NSUInteger tokenSkippedCount = 0;\n    @synchronized (self.runningTokens) {\n        for (SDWebImagePrefetchToken *token in self.runningTokens) {\n            tokenSkippedCount += atomic_load_explicit(&(token->_skippedCount), memory_order_relaxed);\n        }\n    }\n    return tokenSkippedCount;\n}\n\n- (NSUInteger)tokenFinishedCount {\n    NSUInteger tokenFinishedCount = 0;\n    @synchronized (self.runningTokens) {\n        for (SDWebImagePrefetchToken *token in self.runningTokens) {\n            tokenFinishedCount += atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed);\n        }\n    }\n    return tokenFinishedCount;\n}\n\n- (void)addRunningToken:(SDWebImagePrefetchToken *)token {\n    if (!token) {\n        return;\n    }\n    @synchronized (self.runningTokens) {\n        [self.runningTokens addObject:token];\n    }\n}\n\n- (void)removeRunningToken:(SDWebImagePrefetchToken *)token {\n    if (!token) {\n        return;\n    }\n    @synchronized (self.runningTokens) {\n        [self.runningTokens removeObject:token];\n    }\n}\n\n- (NSUInteger)countOfRunningTokens {\n    NSUInteger count = 0;\n    @synchronized (self.runningTokens) {\n        count = self.runningTokens.count;\n    }\n    return count;\n}\n\n@end\n\n@implementation SDWebImagePrefetchToken\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        SD_LOCK_INIT(_prefetchOperationsLock);\n        SD_LOCK_INIT(_loadOperationsLock);\n    }\n    return self;\n}\n\n- (void)cancel {\n    SD_LOCK(_prefetchOperationsLock);\n    [self.prefetchOperations compact];\n    for (id operation in self.prefetchOperations) {\n        id<SDWebImageOperation> strongOperation = operation;\n        if (strongOperation) {\n            [strongOperation cancel];\n        }\n    }\n    self.prefetchOperations.count = 0;\n    SD_UNLOCK(_prefetchOperationsLock);\n    \n    SD_LOCK(_loadOperationsLock);\n    [self.loadOperations compact];\n    for (id operation in self.loadOperations) {\n        id<SDWebImageOperation> strongOperation = operation;\n        if (strongOperation) {\n            [strongOperation cancel];\n        }\n    }\n    self.loadOperations.count = 0;\n    SD_UNLOCK(_loadOperationsLock);\n    \n    self.completionBlock = nil;\n    self.progressBlock = nil;\n    [self.prefetcher removeRunningToken:self];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_UIKIT || SD_MAC\n#import \"SDImageCache.h\"\n\n#if SD_UIKIT\ntypedef UIViewAnimationOptions SDWebImageAnimationOptions;\n#else\ntypedef NS_OPTIONS(NSUInteger, SDWebImageAnimationOptions) {\n    SDWebImageAnimationOptionAllowsImplicitAnimation   = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext`\n    \n    SDWebImageAnimationOptionCurveEaseInOut            = 0 << 16, // default\n    SDWebImageAnimationOptionCurveEaseIn               = 1 << 16,\n    SDWebImageAnimationOptionCurveEaseOut              = 2 << 16,\n    SDWebImageAnimationOptionCurveLinear               = 3 << 16,\n    \n    SDWebImageAnimationOptionTransitionNone            = 0 << 20, // default\n    SDWebImageAnimationOptionTransitionFlipFromLeft    = 1 << 20,\n    SDWebImageAnimationOptionTransitionFlipFromRight   = 2 << 20,\n    SDWebImageAnimationOptionTransitionCurlUp          = 3 << 20,\n    SDWebImageAnimationOptionTransitionCurlDown        = 4 << 20,\n    SDWebImageAnimationOptionTransitionCrossDissolve   = 5 << 20,\n    SDWebImageAnimationOptionTransitionFlipFromTop     = 6 << 20,\n    SDWebImageAnimationOptionTransitionFlipFromBottom  = 7 << 20,\n};\n#endif\n\ntypedef void (^SDWebImageTransitionPreparesBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL);\ntypedef void (^SDWebImageTransitionAnimationsBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image);\ntypedef void (^SDWebImageTransitionCompletionBlock)(BOOL finished);\n\n/**\n This class is used to provide a transition animation after the view category load image finished. Use this on `sd_imageTransition` in UIView+WebCache.h\n for UIKit(iOS & tvOS), we use `+[UIView transitionWithView:duration:options:animations:completion]` for transition animation.\n for AppKit(macOS), we use `+[NSAnimationContext runAnimationGroup:completionHandler:]` for transition animation. You can call `+[NSAnimationContext currentContext]` to grab the context during animations block.\n @note These transition are provided for basic usage. If you need complicated animation, consider to directly use Core Animation or use `SDWebImageAvoidAutoSetImage` and implement your own after image load finished.\n */\n@interface SDWebImageTransition : NSObject\n\n/**\n By default, we set the image to the view at the beginning of the animations. You can disable this and provide custom set image process\n */\n@property (nonatomic, assign) BOOL avoidAutoSetImage;\n/**\n The duration of the transition animation, measured in seconds. Defaults to 0.5.\n */\n@property (nonatomic, assign) NSTimeInterval duration;\n/**\n The timing function used for all animations within this transition animation (macOS).\n */\n@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction API_UNAVAILABLE(ios, tvos, watchos) API_DEPRECATED(\"Use SDWebImageAnimationOptions instead, or grab NSAnimationContext.currentContext and modify the timingFunction\", macos(10.10, 10.10));\n/**\n A mask of options indicating how you want to perform the animations.\n */\n@property (nonatomic, assign) SDWebImageAnimationOptions animationOptions;\n/**\n A block object to be executed before the animation sequence starts.\n */\n@property (nonatomic, copy, nullable) SDWebImageTransitionPreparesBlock prepares;\n/**\n A block object that contains the changes you want to make to the specified view.\n */\n@property (nonatomic, copy, nullable) SDWebImageTransitionAnimationsBlock animations;\n/**\n A block object to be executed when the animation sequence ends.\n */\n@property (nonatomic, copy, nullable) SDWebImageTransitionCompletionBlock completion;\n\n@end\n\n/**\n Convenience way to create transition. Remember to specify the duration if needed.\n for UIKit, these transition just use the correspond `animationOptions`. By default we enable `UIViewAnimationOptionAllowUserInteraction` to allow user interaction during transition.\n for AppKit, these transition use Core Animation in `animations`. So your view must be layer-backed. Set `wantsLayer = YES` before you apply it.\n */\n@interface SDWebImageTransition (Conveniences)\n\n/// Fade-in transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *fadeTransition;\n/// Flip from left transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromLeftTransition;\n/// Flip from right transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromRightTransition;\n/// Flip from top transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromTopTransition;\n/// Flip from bottom transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromBottomTransition;\n/// Curl up transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlUpTransition;\n/// Curl down transition.\n@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlDownTransition;\n\n/// Fade-in transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)fadeTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(fade(duration:));\n\n/// Flip from left  transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)flipFromLeftTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromLeft(duration:));\n\n/// Flip from right transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)flipFromRightTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromRight(duration:));\n\n/// Flip from top transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)flipFromTopTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromTop(duration:));\n\n/// Flip from bottom transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)flipFromBottomTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromBottom(duration:));\n\n///  Curl up transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)curlUpTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(curlUp(duration:));\n\n/// Curl down transition with duration.\n/// @param duration transition duration, use ease-in-out\n+ (nonnull instancetype)curlDownTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(curlDown(duration:));\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageTransition.h\"\n\n#if SD_UIKIT || SD_MAC\n\n#if SD_MAC\n#import \"SDWebImageTransitionInternal.h\"\n#import \"SDInternalMacros.h\"\n\nCAMediaTimingFunction * SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options) {\n    if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveLinear, options)) {\n        return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];\n    } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseIn, options)) {\n        return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];\n    } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseOut, options)) {\n        return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];\n    } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseInOut, options)) {\n        return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];\n    } else {\n        return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];\n    }\n}\n\nCATransition * SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options) {\n    if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCrossDissolve)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionFade;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromLeft)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionPush;\n        trans.subtype = kCATransitionFromLeft;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromRight)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionPush;\n        trans.subtype = kCATransitionFromRight;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromTop)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionPush;\n        trans.subtype = kCATransitionFromTop;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromBottom)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionPush;\n        trans.subtype = kCATransitionFromBottom;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlUp)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionReveal;\n        trans.subtype = kCATransitionFromTop;\n        return trans;\n    } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlDown)) {\n        CATransition *trans = [CATransition animation];\n        trans.type = kCATransitionReveal;\n        trans.subtype = kCATransitionFromBottom;\n        return trans;\n    } else {\n        return nil;\n    }\n}\n#endif\n\n@implementation SDWebImageTransition\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        self.duration = 0.5;\n    }\n    return self;\n}\n\n@end\n\n@implementation SDWebImageTransition (Conveniences)\n\n+ (SDWebImageTransition *)fadeTransition {\n    return [self fadeTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)fadeTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionCrossDissolve;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)flipFromLeftTransition {\n    return [self flipFromLeftTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)flipFromLeftTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromLeft;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)flipFromRightTransition {\n    return [self flipFromRightTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)flipFromRightTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromRight;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)flipFromTopTransition {\n    return [self flipFromTopTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)flipFromTopTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionFlipFromTop | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromTop;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)flipFromBottomTransition {\n    return [self flipFromBottomTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)flipFromBottomTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionFlipFromBottom | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromBottom;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)curlUpTransition {\n    return [self curlUpTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)curlUpTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionCurlUp | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionCurlUp;\n#endif\n    return transition;\n}\n\n+ (SDWebImageTransition *)curlDownTransition {\n    return [self curlDownTransitionWithDuration:0.5];\n}\n\n+ (SDWebImageTransition *)curlDownTransitionWithDuration:(NSTimeInterval)duration {\n    SDWebImageTransition *transition = [SDWebImageTransition new];\n    transition.duration = duration;\n#if SD_UIKIT\n    transition.animationOptions = UIViewAnimationOptionTransitionCurlDown | UIViewAnimationOptionAllowUserInteraction;\n#else\n    transition.animationOptions = SDWebImageAnimationOptionTransitionCurlDown;\n#endif\n    transition.duration = duration;\n    return transition;\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_UIKIT\n\n#import \"SDWebImageManager.h\"\n\n/**\n * Integrates SDWebImage async downloading and caching of remote images with UIButton.\n */\n@interface UIButton (WebCache)\n\n#pragma mark - Image\n\n/**\n * Get the current image URL.\n */\n@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentImageURL;\n\n/**\n * Get the image URL for a control state.\n * \n * @param state Which state you want to know the URL for. The values are described in UIControlState.\n */\n- (nullable NSURL *)sd_imageURLForState:(UIControlState)state;\n\n/**\n * Set the button `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url   The url for the image.\n * @param state The state that uses the specified title. The values are described in UIControlState.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @see sd_setImageWithURL:placeholderImage:options:\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the button `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n#pragma mark - Background Image\n\n/**\n * Get the current background image URL.\n */\n@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentBackgroundImageURL;\n\n/**\n * Get the background image URL for a control state.\n * \n * @param state Which state you want to know the URL for. The values are described in UIControlState.\n */\n- (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state;\n\n/**\n * Set the button `backgroundImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url   The url for the image.\n * @param state The state that uses the specified title. The values are described in UIControlState.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `backgroundImage` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @see sd_setImageWithURL:placeholderImage:options:\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param state       The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options\n                             context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the button `backgroundImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                           completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param state          The state that uses the specified title. The values are described in UIControlState.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                           completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options\n                           completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options\n                            progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                           completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the button `backgroundImage` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options\n                             context:(nullable SDWebImageContext *)context\n                            progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                           completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n#pragma mark - Cancel\n\n/**\n * Cancel the current image download\n */\n- (void)sd_cancelImageLoadForState:(UIControlState)state;\n\n/**\n * Cancel the current backgroundImage download\n */\n- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIButton+WebCache.h\"\n\n#if SD_UIKIT\n\n#import \"objc/runtime.h\"\n#import \"UIView+WebCacheOperation.h\"\n#import \"UIView+WebCache.h\"\n#import \"SDInternalMacros.h\"\n\nstatic char imageURLStorageKey;\n\ntypedef NSMutableDictionary<NSString *, NSURL *> SDStateImageURLDictionary;\n\nstatic inline NSString * imageURLKeyForState(UIControlState state) {\n    return [NSString stringWithFormat:@\"image_%lu\", (unsigned long)state];\n}\n\nstatic inline NSString * backgroundImageURLKeyForState(UIControlState state) {\n    return [NSString stringWithFormat:@\"backgroundImage_%lu\", (unsigned long)state];\n}\n\nstatic inline NSString * imageOperationKeyForState(UIControlState state) {\n    return [NSString stringWithFormat:@\"UIButtonImageOperation%lu\", (unsigned long)state];\n}\n\nstatic inline NSString * backgroundImageOperationKeyForState(UIControlState state) {\n    return [NSString stringWithFormat:@\"UIButtonBackgroundImageOperation%lu\", (unsigned long)state];\n}\n\n@implementation UIButton (WebCache)\n\n#pragma mark - Image\n\n- (nullable NSURL *)sd_currentImageURL {\n    NSURL *url = self.sd_imageURLStorage[imageURLKeyForState(self.state)];\n\n    if (!url) {\n        url = self.sd_imageURLStorage[imageURLKeyForState(UIControlStateNormal)];\n    }\n\n    return url;\n}\n\n- (nullable NSURL *)sd_imageURLForState:(UIControlState)state {\n    return self.sd_imageURLStorage[imageURLKeyForState(state)];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {\n    [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                  forState:(UIControlState)state\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock {\n    if (!url) {\n        [self.sd_imageURLStorage removeObjectForKey:imageURLKeyForState(state)];\n    } else {\n        self.sd_imageURLStorage[imageURLKeyForState(state)] = url;\n    }\n    \n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    mutableContext[SDWebImageContextSetImageOperationKey] = imageOperationKeyForState(state);\n    @weakify(self);\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:mutableContext\n                       setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {\n                           @strongify(self);\n                           [self setImage:image forState:state];\n                       }\n                            progress:progressBlock\n                           completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n#pragma mark - Background Image\n\n- (nullable NSURL *)sd_currentBackgroundImageURL {\n    NSURL *url = self.sd_imageURLStorage[backgroundImageURLKeyForState(self.state)];\n    \n    if (!url) {\n        url = self.sd_imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)];\n    }\n    \n    return url;\n}\n\n- (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state {\n    return self.sd_imageURLStorage[backgroundImageURLKeyForState(state)];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url\n                            forState:(UIControlState)state\n                    placeholderImage:(nullable UIImage *)placeholder\n                             options:(SDWebImageOptions)options\n                             context:(nullable SDWebImageContext *)context\n                            progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                           completed:(nullable SDExternalCompletionBlock)completedBlock {\n    if (!url) {\n        [self.sd_imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)];\n    } else {\n        self.sd_imageURLStorage[backgroundImageURLKeyForState(state)] = url;\n    }\n    \n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    mutableContext[SDWebImageContextSetImageOperationKey] = backgroundImageOperationKeyForState(state);\n    @weakify(self);\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:mutableContext\n                       setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {\n                           @strongify(self);\n                           [self setBackgroundImage:image forState:state];\n                       }\n                            progress:progressBlock\n                           completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n#pragma mark - Cancel\n\n- (void)sd_cancelImageLoadForState:(UIControlState)state {\n    [self sd_cancelImageLoadOperationWithKey:imageOperationKeyForState(state)];\n}\n\n- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state {\n    [self sd_cancelImageLoadOperationWithKey:backgroundImageOperationKeyForState(state)];\n}\n\n#pragma mark - Private\n\n- (SDStateImageURLDictionary *)sd_imageURLStorage {\n    SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);\n    if (!storage) {\n        storage = [NSMutableDictionary dictionary];\n        objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n    }\n\n    return storage;\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n* (c) Fabrice Aneche\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n@interface UIImage (ExtendedCacheData)\n\n/**\n Read and Write the extended object and bind it to the image. Which can hold some extra metadata like Image's scale factor, URL rich link, date, etc.\n The extended object should conforms to NSCoding, which we use `NSKeyedArchiver` and `NSKeyedUnarchiver` to archive it to data, and write to disk cache.\n @note The disk cache preserve both of the data and extended data with the same cache key. For manual query, use the `SDDiskCache` protocol method `extendedDataForKey:` instead.\n @note You can specify arbitrary object conforms to NSCoding (NSObject protocol here is used to support object using `NS_ROOT_CLASS`, which is not NSObject subclass). If you load image from disk cache, you should check the extended object class to avoid corrupted data.\n @warning This object don't need to implements NSSecureCoding (but it's recommended),  because we allows arbitrary class.\n */\n@property (nonatomic, strong, nullable) id<NSObject, NSCoding> sd_extendedObject;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n* (c) Fabrice Aneche\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"UIImage+ExtendedCacheData.h\"\n#import <objc/runtime.h>\n\n@implementation UIImage (ExtendedCacheData)\n\n- (id<NSObject, NSCoding>)sd_extendedObject {\n    return objc_getAssociatedObject(self, @selector(sd_extendedObject));\n}\n\n- (void)setSd_extendedObject:(id<NSObject, NSCoding>)sd_extendedObject {\n    objc_setAssociatedObject(self, @selector(sd_extendedObject), sd_extendedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n/**\n UIImage category about force decode feature (avoid Image/IO's lazy decoding during rendering behavior).\n */\n@interface UIImage (ForceDecode)\n\n/**\n A bool value indicating whether the image has already been decoded. This can help to avoid extra force decode.\n */\n@property (nonatomic, assign) BOOL sd_isDecoded;\n\n/**\n Decode the provided image. This is useful if you want to force decode the image before rendering to improve performance.\n\n @param image The image to be decoded\n @return The decoded image\n */\n+ (nullable UIImage *)sd_decodedImageWithImage:(nullable UIImage *)image;\n\n/**\n Decode and scale down the provided image\n\n @param image The image to be decoded\n @return The decoded and scaled down image\n */\n+ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image;\n\n/**\n Decode and scale down the provided image with limit bytes\n \n @param image The image to be decoded\n @param bytes The limit bytes size. Provide 0 to use the build-in limit.\n @return The decoded and scaled down image\n */\n+ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image limitBytes:(NSUInteger)bytes;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+ForceDecode.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"objc/runtime.h\"\n\n@implementation UIImage (ForceDecode)\n\n- (BOOL)sd_isDecoded {\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isDecoded));\n    return value.boolValue;\n}\n\n- (void)setSd_isDecoded:(BOOL)sd_isDecoded {\n    objc_setAssociatedObject(self, @selector(sd_isDecoded), @(sd_isDecoded), OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n+ (nullable UIImage *)sd_decodedImageWithImage:(nullable UIImage *)image {\n    if (!image) {\n        return nil;\n    }\n    return [SDImageCoderHelper decodedImageWithImage:image];\n}\n\n+ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image {\n    return [self sd_decodedAndScaledDownImageWithImage:image limitBytes:0];\n}\n\n+ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image limitBytes:(NSUInteger)bytes {\n    if (!image) {\n        return nil;\n    }\n    return [SDImageCoderHelper decodedAndScaledDownImageWithImage:image limitBytes:bytes];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Laurin Brandner\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n/**\n This category is just use as a convenience method. For more detail control, use methods in `UIImage+MultiFormat.h` or directly use `SDImageCoder`.\n */\n@interface UIImage (GIF)\n\n/**\n Creates an animated UIImage from an NSData.\n This will create animated image if the data is Animated GIF. And will create a static image is the data is Static GIF.\n\n @param data The GIF data\n @return The created image\n */\n+ (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Laurin Brandner\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+GIF.h\"\n#import \"SDImageGIFCoder.h\"\n\n@implementation UIImage (GIF)\n\n+ (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data {\n    if (!data) {\n        return nil;\n    }\n    return [[SDImageGIFCoder sharedCoder] decodedImageWithData:data options:0];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n/**\n UIImage category for memory cache cost.\n */\n@interface UIImage (MemoryCacheCost)\n\n/**\n The memory cache cost for specify image used by image cache. The cost function is the bytes size held in memory.\n If you set some associated object to `UIImage`, you can set the custom value to indicate the memory cost.\n \n For `UIImage`, this method return the single frame bytes size when `image.images` is nil for static image. Return full frame bytes size when `image.images` is not nil for animated image.\n For `NSImage`, this method return the single frame bytes size because `NSImage` does not store all frames in memory.\n @note Note that because of the limitations of category this property can get out of sync if you create another instance with CGImage or other methods.\n @note For custom animated class conforms to `SDAnimatedImage`, you can override this getter method in your subclass to return a more proper value instead, which representing the current frame's total bytes.\n */\n@property (assign, nonatomic) NSUInteger sd_memoryCost;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"objc/runtime.h\"\n#import \"NSImage+Compatibility.h\"\n\nFOUNDATION_STATIC_INLINE NSUInteger SDMemoryCacheCostForImage(UIImage *image) {\n    CGImageRef imageRef = image.CGImage;\n    if (!imageRef) {\n        return 0;\n    }\n    NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);\n    NSUInteger frameCount;\n#if SD_MAC\n    frameCount = 1;\n#elif SD_UIKIT || SD_WATCH\n    frameCount = image.images.count > 0 ? image.images.count : 1;\n#endif\n    NSUInteger cost = bytesPerFrame * frameCount;\n    return cost;\n}\n\n@implementation UIImage (MemoryCacheCost)\n\n- (NSUInteger)sd_memoryCost {\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_memoryCost));\n    NSUInteger memoryCost;\n    if (value != nil) {\n        memoryCost = [value unsignedIntegerValue];\n    } else {\n        memoryCost = SDMemoryCacheCostForImage(self);\n    }\n    return memoryCost;\n}\n\n- (void)setSd_memoryCost:(NSUInteger)sd_memoryCost {\n    objc_setAssociatedObject(self, @selector(sd_memoryCost), @(sd_memoryCost), OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"NSData+ImageContentType.h\"\n\n/**\n UIImage category for image metadata, including animation, loop count, format, incremental, etc.\n */\n@interface UIImage (Metadata)\n\n/**\n * UIKit:\n * For static image format, this value is always 0.\n * For animated image format, 0 means infinite looping.\n * Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.\n * AppKit:\n * NSImage currently only support animated via GIF imageRep unlike UIImage.\n * The getter of this property will get the loop count from GIF imageRep\n * The setter of this property will set the loop count from GIF imageRep\n */\n@property (nonatomic, assign) NSUInteger sd_imageLoopCount;\n\n/**\n * UIKit:\n * Check the `images` array property.\n * AppKit:\n * NSImage currently only support animated via GIF imageRep unlike UIImage. It will check the imageRep's frame count.\n */\n@property (nonatomic, assign, readonly) BOOL sd_isAnimated;\n\n/**\n * UIKit:\n * Check the `isSymbolImage` property. Also check the system PDF(iOS 11+) && SVG(iOS 13+) support.\n * AppKit:\n * NSImage supports PDF && SVG && EPS imageRep, check the imageRep class.\n */\n@property (nonatomic, assign, readonly) BOOL sd_isVector;\n\n/**\n * The image format represent the original compressed image data format.\n * If you don't manually specify a format, this information is retrieve from CGImage using `CGImageGetUTType`, which may return nil for non-CG based image. At this time it will return `SDImageFormatUndefined` as default value.\n * @note Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.\n */\n@property (nonatomic, assign) SDImageFormat sd_imageFormat;\n\n/**\n A bool value indicating whether the image is during incremental decoding and may not contains full pixels.\n */\n@property (nonatomic, assign) BOOL sd_isIncremental;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+Metadata.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDInternalMacros.h\"\n#import \"objc/runtime.h\"\n\n@implementation UIImage (Metadata)\n\n#if SD_UIKIT || SD_WATCH\n\n- (NSUInteger)sd_imageLoopCount {\n    NSUInteger imageLoopCount = 0;\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageLoopCount));\n    if ([value isKindOfClass:[NSNumber class]]) {\n        imageLoopCount = value.unsignedIntegerValue;\n    }\n    return imageLoopCount;\n}\n\n- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {\n    NSNumber *value = @(sd_imageLoopCount);\n    objc_setAssociatedObject(self, @selector(sd_imageLoopCount), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (BOOL)sd_isAnimated {\n    return (self.images != nil);\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n- (BOOL)sd_isVector {\n    if (@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {\n        // Xcode 11 supports symbol image, keep Xcode 10 compatible currently\n        SEL SymbolSelector = NSSelectorFromString(@\"isSymbolImage\");\n        if ([self respondsToSelector:SymbolSelector] && [self performSelector:SymbolSelector]) {\n            return YES;\n        }\n        // SVG\n        SEL SVGSelector = SD_SEL_SPI(CGSVGDocument);\n        if ([self respondsToSelector:SVGSelector] && [self performSelector:SVGSelector]) {\n            return YES;\n        }\n    }\n    if (@available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {\n        // PDF\n        SEL PDFSelector = SD_SEL_SPI(CGPDFPage);\n        if ([self respondsToSelector:PDFSelector] && [self performSelector:PDFSelector]) {\n            return YES;\n        }\n    }\n    return NO;\n}\n#pragma clang diagnostic pop\n\n#else\n\n- (NSUInteger)sd_imageLoopCount {\n    NSUInteger imageLoopCount = 0;\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    NSBitmapImageRep *bitmapImageRep;\n    if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {\n        bitmapImageRep = (NSBitmapImageRep *)imageRep;\n    }\n    if (bitmapImageRep) {\n        imageLoopCount = [[bitmapImageRep valueForProperty:NSImageLoopCount] unsignedIntegerValue];\n    }\n    return imageLoopCount;\n}\n\n- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    NSBitmapImageRep *bitmapImageRep;\n    if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {\n        bitmapImageRep = (NSBitmapImageRep *)imageRep;\n    }\n    if (bitmapImageRep) {\n        [bitmapImageRep setProperty:NSImageLoopCount withValue:@(sd_imageLoopCount)];\n    }\n}\n\n- (BOOL)sd_isAnimated {\n    BOOL isAnimated = NO;\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    NSBitmapImageRep *bitmapImageRep;\n    if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {\n        bitmapImageRep = (NSBitmapImageRep *)imageRep;\n    }\n    if (bitmapImageRep) {\n        NSUInteger frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];\n        isAnimated = frameCount > 1 ? YES : NO;\n    }\n    return isAnimated;\n}\n\n- (BOOL)sd_isVector {\n    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);\n    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];\n    if ([imageRep isKindOfClass:[NSPDFImageRep class]]) {\n        return YES;\n    }\n    if ([imageRep isKindOfClass:[NSEPSImageRep class]]) {\n        return YES;\n    }\n    if ([NSStringFromClass(imageRep.class) hasSuffix:@\"NSSVGImageRep\"]) {\n        return YES;\n    }\n    return NO;\n}\n\n#endif\n\n- (SDImageFormat)sd_imageFormat {\n    SDImageFormat imageFormat = SDImageFormatUndefined;\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageFormat));\n    if ([value isKindOfClass:[NSNumber class]]) {\n        imageFormat = value.integerValue;\n        return imageFormat;\n    }\n    // Check CGImage's UTType, may return nil for non-Image/IO based image\n    if (@available(iOS 9.0, tvOS 9.0, macOS 10.11, watchOS 2.0, *)) {\n        CFStringRef uttype = CGImageGetUTType(self.CGImage);\n        imageFormat = [NSData sd_imageFormatFromUTType:uttype];\n    }\n    return imageFormat;\n}\n\n- (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat {\n    objc_setAssociatedObject(self, @selector(sd_imageFormat), @(sd_imageFormat), OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (void)setSd_isIncremental:(BOOL)sd_isIncremental {\n    objc_setAssociatedObject(self, @selector(sd_isIncremental), @(sd_isIncremental), OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (BOOL)sd_isIncremental {\n    NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isIncremental));\n    return value.boolValue;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"NSData+ImageContentType.h\"\n\n/**\n UIImage category for convenient image format decoding/encoding.\n */\n@interface UIImage (MultiFormat)\n#pragma mark - Decode\n/**\n Create and decode a image with the specify image data\n\n @param data The image data\n @return The created image\n */\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data;\n\n/**\n Create and decode a image with the specify image data and scale\n \n @param data The image data\n @param scale The image scale factor. Should be greater than or equal to 1.0.\n @return The created image\n */\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale;\n\n/**\n Create and decode a image with the specify image data and scale, allow specify animate/static control\n \n @param data The image data\n @param scale The image scale factor. Should be greater than or equal to 1.0.\n @param firstFrameOnly Even if the image data is animated image format, decode the first frame only as static image.\n @return The created image\n */\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly;\n\n#pragma mark - Encode\n/**\n Encode the current image to the data, the image format is unspecified\n\n @note If the receiver is `SDAnimatedImage`, this will return the animated image data if available. No more extra encoding process.\n @return The encoded data. If can't encode, return nil\n */\n- (nullable NSData *)sd_imageData;\n\n/**\n Encode the current image to data with the specify image format\n\n @param imageFormat The specify image format\n @return The encoded data. If can't encode, return nil\n */\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat NS_SWIFT_NAME(sd_imageData(as:));\n\n/**\n Encode the current image to data with the specify image format and compression quality\n\n @param imageFormat The specify image format\n @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality.\n @return The encoded data. If can't encode, return nil\n */\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality NS_SWIFT_NAME(sd_imageData(as:compressionQuality:));\n\n/**\n Encode the current image to data with the specify image format and compression quality, allow specify animate/static control\n \n @param imageFormat The specify image format\n @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality.\n @param firstFrameOnly Even if the image is animated image, encode the first frame only as static image.\n @return The encoded data. If can't encode, return nil\n */\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly NS_SWIFT_NAME(sd_imageData(as:compressionQuality:firstFrameOnly:));\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+MultiFormat.h\"\n#import \"SDImageCodersManager.h\"\n\n@implementation UIImage (MultiFormat)\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {\n    return [self sd_imageWithData:data scale:1];\n}\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale {\n    return [self sd_imageWithData:data scale:scale firstFrameOnly:NO];\n}\n\n+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly {\n    if (!data) {\n        return nil;\n    }\n    SDImageCoderOptions *options = @{SDImageCoderDecodeScaleFactor : @(MAX(scale, 1)), SDImageCoderDecodeFirstFrameOnly : @(firstFrameOnly)};\n    return [[SDImageCodersManager sharedManager] decodedImageWithData:data options:options];\n}\n\n- (nullable NSData *)sd_imageData {\n    return [self sd_imageDataAsFormat:SDImageFormatUndefined];\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat {\n    return [self sd_imageDataAsFormat:imageFormat compressionQuality:1];\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality {\n    return [self sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:NO];\n}\n\n- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly {\n    SDImageCoderOptions *options = @{SDImageCoderEncodeCompressionQuality : @(compressionQuality), SDImageCoderEncodeFirstFrameOnly : @(firstFrameOnly)};\n    return [[SDImageCodersManager sharedManager] encodedDataWithImage:self format:imageFormat options:options];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\ntypedef NS_ENUM(NSUInteger, SDImageScaleMode) {\n    SDImageScaleModeFill = 0,\n    SDImageScaleModeAspectFit = 1,\n    SDImageScaleModeAspectFill = 2\n};\n\n#if SD_UIKIT || SD_WATCH\ntypedef UIRectCorner SDRectCorner;\n#else\ntypedef NS_OPTIONS(NSUInteger, SDRectCorner) {\n    SDRectCornerTopLeft     = 1 << 0,\n    SDRectCornerTopRight    = 1 << 1,\n    SDRectCornerBottomLeft  = 1 << 2,\n    SDRectCornerBottomRight = 1 << 3,\n    SDRectCornerAllCorners  = ~0UL\n};\n#endif\n\n/**\n Provide some common method for `UIImage`.\n Image process is based on Core Graphics and vImage.\n */\n@interface UIImage (Transform)\n\n#pragma mark - Image Geometry\n\n/**\n Returns a new image which is resized from this image.\n You can specify a larger or smaller size than the image size. The image content will be changed with the scale mode.\n \n @param size        The new size to be resized, values should be positive.\n @param scaleMode   The scale mode for image content.\n @return The new image with the given size.\n */\n- (nullable UIImage *)sd_resizedImageWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode;\n\n/**\n Returns a new image which is cropped from this image.\n \n @param rect     Image's inner rect.\n @return         The new image with the cropping rect.\n */\n- (nullable UIImage *)sd_croppedImageWithRect:(CGRect)rect;\n\n/**\n Rounds a new image with a given corner radius and corners.\n \n @param cornerRadius The radius of each corner oval. Values larger than half the\n rectangle's width or height are clamped appropriately to\n half the width or height.\n @param corners      A bitmask value that identifies the corners that you want\n rounded. You can use this parameter to round only a subset\n of the corners of the rectangle.\n @param borderWidth  The inset border line width. Values larger than half the rectangle's\n width or height are clamped appropriately to half the width\n or height.\n @param borderColor  The border stroke color. nil means clear color.\n @return The new image with the round corner.\n */\n- (nullable UIImage *)sd_roundedCornerImageWithRadius:(CGFloat)cornerRadius\n                                              corners:(SDRectCorner)corners\n                                          borderWidth:(CGFloat)borderWidth\n                                          borderColor:(nullable UIColor *)borderColor;\n\n/**\n Returns a new rotated image (relative to the center).\n \n @param angle     Rotated radians in counterclockwise.⟲\n @param fitSize   YES: new image's size is extend to fit all content.\n                  NO: image's size will not change, content may be clipped.\n @return The new image with the rotation.\n */\n- (nullable UIImage *)sd_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;\n\n/**\n Returns a new horizontally(vertically) flipped image.\n \n @param horizontal YES to flip the image horizontally. ⇋\n @param vertical YES to flip the image vertically. ⥯\n @return The new image with the flipping.\n */\n- (nullable UIImage *)sd_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;\n\n#pragma mark - Image Blending\n\n/**\n Return a tinted image with the given color. This actually use alpha blending of current image and the tint color.\n \n @param tintColor  The tint color.\n @return The new image with the tint color.\n */\n- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor;\n\n/**\n Return the pixel color at specify position. The point is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based.\n @note The point's x/y should not be smaller than 0, or greater than or equal to width/height.\n @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself.\n\n @param point The position of pixel\n @return The color for specify pixel, or nil if any error occur\n */\n- (nullable UIColor *)sd_colorAtPoint:(CGPoint)point;\n\n/**\n Return the pixel color array with specify rectangle. The rect is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based.\n @note The rect's width/height should not be smaller than or equal to 0. The minX/minY should not be smaller than 0. The maxX/maxY should not be greater than width/height. Attention this limit is different from `sd_colorAtPoint:` (point: (0, 0) like rect: (0, 0, 1, 1))\n @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself.\n\n @param rect The rectangle of pixels\n @return The color array for specify pixels, or nil if any error occur\n */\n- (nullable NSArray<UIColor *> *)sd_colorsWithRect:(CGRect)rect;\n\n#pragma mark - Image Effect\n\n/**\n Return a new image applied a blur effect.\n \n @param blurRadius     The radius of the blur in points, 0 means no blur effect.\n \n @return               The new image with blur effect, or nil if an error occurs (e.g. no enough memory).\n */\n- (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius;\n\n#if SD_UIKIT || SD_MAC\n/**\n Return a new image applied a CIFilter.\n\n @param filter The CIFilter to be applied to the image.\n @return The new image with the CIFilter, or nil if an error occurs (e.g. no\n enough memory).\n */\n- (nullable UIImage *)sd_filteredImageWithFilter:(nonnull CIFilter *)filter;\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImage+Transform.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDImageGraphics.h\"\n#import \"SDGraphicsImageRenderer.h\"\n#import \"NSBezierPath+SDRoundedCorners.h\"\n#import <Accelerate/Accelerate.h>\n#if SD_UIKIT || SD_MAC\n#import <CoreImage/CoreImage.h>\n#endif\n\nstatic inline CGRect SDCGRectFitWithScaleMode(CGRect rect, CGSize size, SDImageScaleMode scaleMode) {\n    rect = CGRectStandardize(rect);\n    size.width = size.width < 0 ? -size.width : size.width;\n    size.height = size.height < 0 ? -size.height : size.height;\n    CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));\n    switch (scaleMode) {\n        case SDImageScaleModeAspectFit:\n        case SDImageScaleModeAspectFill: {\n            if (rect.size.width < 0.01 || rect.size.height < 0.01 ||\n                size.width < 0.01 || size.height < 0.01) {\n                rect.origin = center;\n                rect.size = CGSizeZero;\n            } else {\n                CGFloat scale;\n                if (scaleMode == SDImageScaleModeAspectFit) {\n                    if (size.width / size.height < rect.size.width / rect.size.height) {\n                        scale = rect.size.height / size.height;\n                    } else {\n                        scale = rect.size.width / size.width;\n                    }\n                } else {\n                    if (size.width / size.height < rect.size.width / rect.size.height) {\n                        scale = rect.size.width / size.width;\n                    } else {\n                        scale = rect.size.height / size.height;\n                    }\n                }\n                size.width *= scale;\n                size.height *= scale;\n                rect.size = size;\n                rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5);\n            }\n        } break;\n        case SDImageScaleModeFill:\n        default: {\n            rect = rect;\n        }\n    }\n    return rect;\n}\n\nstatic inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitmapInfo) {\n    // Get alpha info, byteOrder info\n    CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;\n    CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask;\n    CGFloat r = 0, g = 0, b = 0, a = 1;\n    \n    BOOL byteOrderNormal = NO;\n    switch (byteOrderInfo) {\n        case kCGBitmapByteOrderDefault: {\n            byteOrderNormal = YES;\n        } break;\n        case kCGBitmapByteOrder32Little: {\n        } break;\n        case kCGBitmapByteOrder32Big: {\n            byteOrderNormal = YES;\n        } break;\n        default: break;\n    }\n    switch (alphaInfo) {\n        case kCGImageAlphaPremultipliedFirst:\n        case kCGImageAlphaFirst: {\n            if (byteOrderNormal) {\n                // ARGB8888\n                a = pixel[0] / 255.0;\n                r = pixel[1] / 255.0;\n                g = pixel[2] / 255.0;\n                b = pixel[3] / 255.0;\n            } else {\n                // BGRA8888\n                b = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                r = pixel[2] / 255.0;\n                a = pixel[3] / 255.0;\n            }\n        }\n            break;\n        case kCGImageAlphaPremultipliedLast:\n        case kCGImageAlphaLast: {\n            if (byteOrderNormal) {\n                // RGBA8888\n                r = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                b = pixel[2] / 255.0;\n                a = pixel[3] / 255.0;\n            } else {\n                // ABGR8888\n                a = pixel[0] / 255.0;\n                b = pixel[1] / 255.0;\n                g = pixel[2] / 255.0;\n                r = pixel[3] / 255.0;\n            }\n        }\n            break;\n        case kCGImageAlphaNone: {\n            if (byteOrderNormal) {\n                // RGB\n                r = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                b = pixel[2] / 255.0;\n            } else {\n                // BGR\n                b = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                r = pixel[2] / 255.0;\n            }\n        }\n            break;\n        case kCGImageAlphaNoneSkipLast: {\n            if (byteOrderNormal) {\n                // RGBX\n                r = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                b = pixel[2] / 255.0;\n            } else {\n                // XBGR\n                b = pixel[1] / 255.0;\n                g = pixel[2] / 255.0;\n                r = pixel[3] / 255.0;\n            }\n        }\n            break;\n        case kCGImageAlphaNoneSkipFirst: {\n            if (byteOrderNormal) {\n                // XRGB\n                r = pixel[1] / 255.0;\n                g = pixel[2] / 255.0;\n                b = pixel[3] / 255.0;\n            } else {\n                // BGRX\n                b = pixel[0] / 255.0;\n                g = pixel[1] / 255.0;\n                r = pixel[2] / 255.0;\n            }\n        }\n            break;\n        case kCGImageAlphaOnly: {\n            // A\n            a = pixel[0] / 255.0;\n        }\n            break;\n        default:\n            break;\n    }\n    \n    return [UIColor colorWithRed:r green:g blue:b alpha:a];\n}\n\n#if SD_UIKIT || SD_MAC\n// Create-Rule, caller should call CGImageRelease\nstatic inline CGImageRef _Nullable SDCreateCGImageFromCIImage(CIImage * _Nonnull ciImage) {\n    CGImageRef imageRef = NULL;\n    if (@available(iOS 10, macOS 10.12, tvOS 10, *)) {\n        imageRef = ciImage.CGImage;\n    }\n    if (!imageRef) {\n        CIContext *context = [CIContext context];\n        imageRef = [context createCGImage:ciImage fromRect:ciImage.extent];\n    } else {\n        CGImageRetain(imageRef);\n    }\n    return imageRef;\n}\n#endif\n\n@implementation UIImage (Transform)\n\n- (void)sd_drawInRect:(CGRect)rect context:(CGContextRef)context scaleMode:(SDImageScaleMode)scaleMode clipsToBounds:(BOOL)clips {\n    CGRect drawRect = SDCGRectFitWithScaleMode(rect, self.size, scaleMode);\n    if (drawRect.size.width == 0 || drawRect.size.height == 0) return;\n    if (clips) {\n        if (context) {\n            CGContextSaveGState(context);\n            CGContextAddRect(context, rect);\n            CGContextClip(context);\n            [self drawInRect:drawRect];\n            CGContextRestoreGState(context);\n        }\n    } else {\n        [self drawInRect:drawRect];\n    }\n}\n\n- (nullable UIImage *)sd_resizedImageWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode {\n    if (size.width <= 0 || size.height <= 0) return nil;\n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init];\n    format.scale = self.scale;\n    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:size format:format];\n    UIImage *image = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {\n        [self sd_drawInRect:CGRectMake(0, 0, size.width, size.height) context:context scaleMode:scaleMode clipsToBounds:NO];\n    }];\n    return image;\n}\n\n- (nullable UIImage *)sd_croppedImageWithRect:(CGRect)rect {\n    rect.origin.x *= self.scale;\n    rect.origin.y *= self.scale;\n    rect.size.width *= self.scale;\n    rect.size.height *= self.scale;\n    if (rect.size.width <= 0 || rect.size.height <= 0) return nil;\n    \n#if SD_UIKIT || SD_MAC\n    // CIImage shortcut\n    if (self.CIImage) {\n        CGRect croppingRect = CGRectMake(rect.origin.x, self.size.height - CGRectGetMaxY(rect), rect.size.width, rect.size.height);\n        CIImage *ciImage = [self.CIImage imageByCroppingToRect:croppingRect];\n#if SD_UIKIT\n        UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation];\n#else\n        UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n        return image;\n    }\n#endif\n    \n    CGImageRef imageRef = self.CGImage;\n    if (!imageRef) {\n        return nil;\n    }\n    \n    CGImageRef croppedImageRef = CGImageCreateWithImageInRect(imageRef, rect);\n    if (!croppedImageRef) {\n        return nil;\n    }\n#if SD_UIKIT || SD_WATCH\n    UIImage *image = [UIImage imageWithCGImage:croppedImageRef scale:self.scale orientation:self.imageOrientation];\n#else\n    UIImage *image = [[UIImage alloc] initWithCGImage:croppedImageRef scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n    CGImageRelease(croppedImageRef);\n    return image;\n}\n\n- (nullable UIImage *)sd_roundedCornerImageWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor {\n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init];\n    format.scale = self.scale;\n    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:self.size format:format];\n    UIImage *image = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {\n        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);\n        \n        CGFloat minSize = MIN(self.size.width, self.size.height);\n        if (borderWidth < minSize / 2) {\n#if SD_UIKIT || SD_WATCH\n            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];\n#else\n            NSBezierPath *path = [NSBezierPath sd_bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadius:cornerRadius];\n#endif\n            [path closePath];\n            \n            CGContextSaveGState(context);\n            [path addClip];\n            [self drawInRect:rect];\n            CGContextRestoreGState(context);\n        }\n        \n        if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) {\n            CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale;\n            CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset);\n            CGFloat strokeRadius = cornerRadius > self.scale / 2 ? cornerRadius - self.scale / 2 : 0;\n#if SD_UIKIT || SD_WATCH\n            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, strokeRadius)];\n#else\n            NSBezierPath *path = [NSBezierPath sd_bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadius:strokeRadius];\n#endif\n            [path closePath];\n            \n            path.lineWidth = borderWidth;\n            [borderColor setStroke];\n            [path stroke];\n        }\n    }];\n    return image;\n}\n\n- (nullable UIImage *)sd_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize {\n    size_t width = self.size.width;\n    size_t height = self.size.height;\n    CGRect newRect = CGRectApplyAffineTransform(CGRectMake(0, 0, width, height),\n                                                fitSize ? CGAffineTransformMakeRotation(angle) : CGAffineTransformIdentity);\n\n#if SD_UIKIT || SD_MAC\n    // CIImage shortcut\n    if (self.CIImage) {\n        CIImage *ciImage = self.CIImage;\n        if (fitSize) {\n            CGAffineTransform transform = CGAffineTransformMakeRotation(angle);\n            ciImage = [ciImage imageByApplyingTransform:transform];\n        } else {\n            CIFilter *filter = [CIFilter filterWithName:@\"CIStraightenFilter\"];\n            [filter setValue:ciImage forKey:kCIInputImageKey];\n            [filter setValue:@(angle) forKey:kCIInputAngleKey];\n            ciImage = filter.outputImage;\n        }\n#if SD_UIKIT || SD_WATCH\n        UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation];\n#else\n        UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n        return image;\n    }\n#endif\n    \n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init];\n    format.scale = self.scale;\n    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:newRect.size format:format];\n    UIImage *image = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {\n        CGContextSetShouldAntialias(context, true);\n        CGContextSetAllowsAntialiasing(context, true);\n        CGContextSetInterpolationQuality(context, kCGInterpolationHigh);\n        CGContextTranslateCTM(context, +(newRect.size.width * 0.5), +(newRect.size.height * 0.5));\n#if SD_UIKIT || SD_WATCH\n        // Use UIKit coordinate system counterclockwise (⟲)\n        CGContextRotateCTM(context, -angle);\n#else\n        CGContextRotateCTM(context, angle);\n#endif\n        \n        [self drawInRect:CGRectMake(-(width * 0.5), -(height * 0.5), width, height)];\n    }];\n    return image;\n}\n\n- (nullable UIImage *)sd_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {\n    size_t width = self.size.width;\n    size_t height = self.size.height;\n\n#if SD_UIKIT || SD_MAC\n    // CIImage shortcut\n    if (self.CIImage) {\n        CGAffineTransform transform = CGAffineTransformIdentity;\n        // Use UIKit coordinate system\n        if (horizontal) {\n            CGAffineTransform flipHorizontal = CGAffineTransformMake(-1, 0, 0, 1, width, 0);\n            transform = CGAffineTransformConcat(transform, flipHorizontal);\n        }\n        if (vertical) {\n            CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, height);\n            transform = CGAffineTransformConcat(transform, flipVertical);\n        }\n        CIImage *ciImage = [self.CIImage imageByApplyingTransform:transform];\n#if SD_UIKIT\n        UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation];\n#else\n        UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n        return image;\n    }\n#endif\n    \n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init];\n    format.scale = self.scale;\n    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:self.size format:format];\n    UIImage *image = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {\n        // Use UIKit coordinate system\n        if (horizontal) {\n            CGAffineTransform flipHorizontal = CGAffineTransformMake(-1, 0, 0, 1, width, 0);\n            CGContextConcatCTM(context, flipHorizontal);\n        }\n        if (vertical) {\n            CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, height);\n            CGContextConcatCTM(context, flipVertical);\n        }\n        [self drawInRect:CGRectMake(0, 0, width, height)];\n    }];\n    return image;\n}\n\n#pragma mark - Image Blending\n\n- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor {\n    BOOL hasTint = CGColorGetAlpha(tintColor.CGColor) > __FLT_EPSILON__;\n    if (!hasTint) {\n        return self;\n    }\n    \n#if SD_UIKIT || SD_MAC\n    // CIImage shortcut\n    if (self.CIImage) {\n        CIImage *ciImage = self.CIImage;\n        CIImage *colorImage = [CIImage imageWithColor:[[CIColor alloc] initWithColor:tintColor]];\n        colorImage = [colorImage imageByCroppingToRect:ciImage.extent];\n        CIFilter *filter = [CIFilter filterWithName:@\"CISourceAtopCompositing\"];\n        [filter setValue:colorImage forKey:kCIInputImageKey];\n        [filter setValue:ciImage forKey:kCIInputBackgroundImageKey];\n        ciImage = filter.outputImage;\n#if SD_UIKIT\n        UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation];\n#else\n        UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n        return image;\n    }\n#endif\n    \n    CGSize size = self.size;\n    CGRect rect = { CGPointZero, size };\n    CGFloat scale = self.scale;\n    \n    // blend mode, see https://en.wikipedia.org/wiki/Alpha_compositing\n    CGBlendMode blendMode = kCGBlendModeSourceAtop;\n    \n    SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init];\n    format.scale = scale;\n    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:size format:format];\n    UIImage *image = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {\n        [self drawInRect:rect];\n        CGContextSetBlendMode(context, blendMode);\n        CGContextSetFillColorWithColor(context, tintColor.CGColor);\n        CGContextFillRect(context, rect);\n    }];\n    return image;\n}\n\n- (nullable UIColor *)sd_colorAtPoint:(CGPoint)point {\n    CGImageRef imageRef = NULL;\n    // CIImage compatible\n#if SD_UIKIT || SD_MAC\n    if (self.CIImage) {\n        imageRef = SDCreateCGImageFromCIImage(self.CIImage);\n    }\n#endif\n    if (!imageRef) {\n        imageRef = self.CGImage;\n        CGImageRetain(imageRef);\n    }\n    if (!imageRef) {\n        return nil;\n    }\n    \n    // Check point\n    CGFloat width = CGImageGetWidth(imageRef);\n    CGFloat height = CGImageGetHeight(imageRef);\n    if (point.x < 0 || point.y < 0 || point.x >= width || point.y >= height) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    \n    // Get pixels\n    CGDataProviderRef provider = CGImageGetDataProvider(imageRef);\n    if (!provider) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    CFDataRef data = CGDataProviderCopyData(provider);\n    if (!data) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    \n    // Get pixel at point\n    size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);\n    size_t components = CGImageGetBitsPerPixel(imageRef) / CGImageGetBitsPerComponent(imageRef);\n    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);\n    \n    CFRange range = CFRangeMake(bytesPerRow * point.y + components * point.x, 4);\n    if (CFDataGetLength(data) < range.location + range.length) {\n        CFRelease(data);\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    Pixel_8888 pixel = {0};\n    CFDataGetBytes(data, range, pixel);\n    CFRelease(data);\n    CGImageRelease(imageRef);\n    // Convert to color\n    return SDGetColorFromPixel(pixel, bitmapInfo);\n}\n\n- (nullable NSArray<UIColor *> *)sd_colorsWithRect:(CGRect)rect {\n    CGImageRef imageRef = NULL;\n    // CIImage compatible\n#if SD_UIKIT || SD_MAC\n    if (self.CIImage) {\n        imageRef = SDCreateCGImageFromCIImage(self.CIImage);\n    }\n#endif\n    if (!imageRef) {\n        imageRef = self.CGImage;\n        CGImageRetain(imageRef);\n    }\n    if (!imageRef) {\n        return nil;\n    }\n    \n    // Check rect\n    CGFloat width = CGImageGetWidth(imageRef);\n    CGFloat height = CGImageGetHeight(imageRef);\n    if (CGRectGetWidth(rect) <= 0 || CGRectGetHeight(rect) <= 0 || CGRectGetMinX(rect) < 0 || CGRectGetMinY(rect) < 0 || CGRectGetMaxX(rect) > width || CGRectGetMaxY(rect) > height) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    \n    // Get pixels\n    CGDataProviderRef provider = CGImageGetDataProvider(imageRef);\n    if (!provider) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    CFDataRef data = CGDataProviderCopyData(provider);\n    if (!data) {\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    \n    // Get pixels with rect\n    size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);\n    size_t components = CGImageGetBitsPerPixel(imageRef) / CGImageGetBitsPerComponent(imageRef);\n    \n    size_t start = bytesPerRow * CGRectGetMinY(rect) + components * CGRectGetMinX(rect);\n    size_t end = bytesPerRow * (CGRectGetMaxY(rect) - 1) + components * CGRectGetMaxX(rect);\n    if (CFDataGetLength(data) < (CFIndex)end) {\n        CFRelease(data);\n        CGImageRelease(imageRef);\n        return nil;\n    }\n    \n    const UInt8 *pixels = CFDataGetBytePtr(data);\n    size_t row = CGRectGetMinY(rect);\n    size_t col = CGRectGetMaxX(rect);\n    \n    // Convert to color\n    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);\n    NSMutableArray<UIColor *> *colors = [NSMutableArray arrayWithCapacity:CGRectGetWidth(rect) * CGRectGetHeight(rect)];\n    for (size_t index = start; index < end; index += 4) {\n        if (index >= row * bytesPerRow + col * components) {\n            // Index beyond the end of current row, go next row\n            row++;\n            index = row * bytesPerRow + CGRectGetMinX(rect) * components;\n            index -= 4;\n            continue;\n        }\n        Pixel_8888 pixel = {pixels[index], pixels[index+1], pixels[index+2], pixels[index+3]};\n        UIColor *color = SDGetColorFromPixel(pixel, bitmapInfo);\n        [colors addObject:color];\n    }\n    CFRelease(data);\n    CGImageRelease(imageRef);\n    \n    return [colors copy];\n}\n\n#pragma mark - Image Effect\n\n// We use vImage to do box convolve for performance and support for watchOS. However, you can just use `CIFilter.CIGaussianBlur`. For other blur effect, use any filter in `CICategoryBlur`\n- (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius {\n    if (self.size.width < 1 || self.size.height < 1) {\n        return nil;\n    }\n    BOOL hasBlur = blurRadius > __FLT_EPSILON__;\n    if (!hasBlur) {\n        return self;\n    }\n    \n    CGFloat scale = self.scale;\n    CGFloat inputRadius = blurRadius * scale;\n#if SD_UIKIT || SD_MAC\n    if (self.CIImage) {\n        CIFilter *filter = [CIFilter filterWithName:@\"CIGaussianBlur\"];\n        [filter setValue:self.CIImage forKey:kCIInputImageKey];\n        [filter setValue:@(inputRadius) forKey:kCIInputRadiusKey];\n        CIImage *ciImage = filter.outputImage;\n        ciImage = [ciImage imageByCroppingToRect:CGRectMake(0, 0, self.size.width, self.size.height)];\n#if SD_UIKIT\n        UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation];\n#else\n        UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n        return image;\n    }\n#endif\n    \n    CGImageRef imageRef = self.CGImage;\n    \n    //convert to BGRA if it isn't\n    if (CGImageGetBitsPerPixel(imageRef) != 32 ||\n        CGImageGetBitsPerComponent(imageRef) != 8 ||\n        !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) {\n        SDGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);\n        [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];\n        imageRef = SDGraphicsGetImageFromCurrentImageContext().CGImage;\n        SDGraphicsEndImageContext();\n    }\n    \n    vImage_Buffer effect = {}, scratch = {};\n    vImage_Buffer *input = NULL, *output = NULL;\n    \n    vImage_CGImageFormat format = {\n        .bitsPerComponent = 8,\n        .bitsPerPixel = 32,\n        .colorSpace = NULL,\n        .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, //requests a BGRA buffer.\n        .version = 0,\n        .decode = NULL,\n        .renderingIntent = kCGRenderingIntentDefault\n    };\n    \n    vImage_Error err;\n    err = vImageBuffer_InitWithCGImage(&effect, &format, NULL, imageRef, kvImageNoFlags);\n    if (err != kvImageNoError) {\n        NSLog(@\"UIImage+Transform error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@\", err, self);\n        return nil;\n    }\n    err = vImageBuffer_Init(&scratch, effect.height, effect.width, format.bitsPerPixel, kvImageNoFlags);\n    if (err != kvImageNoError) {\n        NSLog(@\"UIImage+Transform error: vImageBuffer_Init returned error code %zi for inputImage: %@\", err, self);\n        return nil;\n    }\n    \n    input = &effect;\n    output = &scratch;\n    \n    if (hasBlur) {\n        // A description of how to compute the box kernel width from the Gaussian\n        // radius (aka standard deviation) appears in the SVG spec:\n        // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement\n        //\n        // For larger values of 's' (s >= 2.0), an approximation can be used: Three\n        // successive box-blurs build a piece-wise quadratic convolution kernel, which\n        // approximates the Gaussian kernel to within roughly 3%.\n        //\n        // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)\n        //\n        // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.\n        //\n        if (inputRadius - 2.0 < __FLT_EPSILON__) inputRadius = 2.0;\n        uint32_t radius = floor(inputRadius * 3.0 * sqrt(2 * M_PI) / 4 + 0.5);\n        radius |= 1; // force radius to be odd so that the three box-blur methodology works.\n        int iterations;\n        if (blurRadius * scale < 0.5) iterations = 1;\n        else if (blurRadius * scale < 1.5) iterations = 2;\n        else iterations = 3;\n        NSInteger tempSize = vImageBoxConvolve_ARGB8888(input, output, NULL, 0, 0, radius, radius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend);\n        void *temp = malloc(tempSize);\n        for (int i = 0; i < iterations; i++) {\n            vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);\n            vImage_Buffer *tmp = input;\n            input = output;\n            output = tmp;\n        }\n        free(temp);\n    }\n    \n    CGImageRef effectCGImage = NULL;\n    effectCGImage = vImageCreateCGImageFromBuffer(input, &format, NULL, NULL, kvImageNoAllocate, NULL);\n    if (effectCGImage == NULL) {\n        effectCGImage = vImageCreateCGImageFromBuffer(input, &format, NULL, NULL, kvImageNoFlags, NULL);\n        free(input->data);\n    }\n    free(output->data);\n#if SD_UIKIT || SD_WATCH\n    UIImage *outputImage = [UIImage imageWithCGImage:effectCGImage scale:self.scale orientation:self.imageOrientation];\n#else\n    UIImage *outputImage = [[UIImage alloc] initWithCGImage:effectCGImage scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n    CGImageRelease(effectCGImage);\n    \n    return outputImage;\n}\n\n#if SD_UIKIT || SD_MAC\n- (nullable UIImage *)sd_filteredImageWithFilter:(nonnull CIFilter *)filter {\n    CIImage *inputImage;\n    if (self.CIImage) {\n        inputImage = self.CIImage;\n    } else {\n        CGImageRef imageRef = self.CGImage;\n        if (!imageRef) {\n            return nil;\n        }\n        inputImage = [CIImage imageWithCGImage:imageRef];\n    }\n    if (!inputImage) return nil;\n    \n    CIContext *context = [CIContext context];\n    [filter setValue:inputImage forKey:kCIInputImageKey];\n    CIImage *outputImage = filter.outputImage;\n    if (!outputImage) return nil;\n    \n    CGImageRef imageRef = [context createCGImage:outputImage fromRect:outputImage.extent];\n    if (!imageRef) return nil;\n    \n#if SD_UIKIT\n    UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];\n#else\n    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:self.scale orientation:kCGImagePropertyOrientationUp];\n#endif\n    CGImageRelease(imageRef);\n    \n    return image;\n}\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_UIKIT\n\n#import \"SDWebImageManager.h\"\n\n/**\n * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state.\n */\n@interface UIImageView (HighlightedWebCache)\n\n/**\n * Set the imageView `highlightedImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url The url for the image.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `highlightedImage` with an `url` and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url     The url for the image.\n * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `highlightedImage` with an `url`, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url     The url for the image.\n * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options\n                              context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the imageView `highlightedImage` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                            completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `highlightedImage` with an `url` and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options\n                            completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `highlightedImage` with an `url` and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options\n                             progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                            completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `highlightedImage` with an `url`, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options\n                              context:(nullable SDWebImageContext *)context\n                             progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                            completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImageView+HighlightedWebCache.h\"\n\n#if SD_UIKIT\n\n#import \"UIView+WebCacheOperation.h\"\n#import \"UIView+WebCache.h\"\n#import \"SDInternalMacros.h\"\n\nstatic NSString * const SDHighlightedImageOperationKey = @\"UIImageViewImageOperationHighlighted\";\n\n@implementation UIImageView (HighlightedWebCache)\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url {\n    [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options {\n    [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];\n}\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setHighlightedImageWithURL:url options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setHighlightedImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url\n                              options:(SDWebImageOptions)options\n                              context:(nullable SDWebImageContext *)context\n                             progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                            completed:(nullable SDExternalCompletionBlock)completedBlock {\n    @weakify(self);\n    SDWebImageMutableContext *mutableContext;\n    if (context) {\n        mutableContext = [context mutableCopy];\n    } else {\n        mutableContext = [NSMutableDictionary dictionary];\n    }\n    mutableContext[SDWebImageContextSetImageOperationKey] = SDHighlightedImageOperationKey;\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:nil\n                             options:options\n                             context:mutableContext\n                       setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {\n                           @strongify(self);\n                           self.highlightedImage = image;\n                       }\n                            progress:progressBlock\n                           completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageManager.h\"\n\n/**\n * Usage with a UITableViewCell sub-class:\n *\n * @code\n\n#import <SDWebImage/UIImageView+WebCache.h>\n\n...\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    static NSString *MyIdentifier = @\"MyIdentifier\";\n \n    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];\n \n    if (cell == nil) {\n        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];\n    }\n \n    // Here we use the provided sd_setImageWithURL:placeholderImage: method to load the web image\n    // Ensure you use a placeholder image otherwise cells will be initialized with no image\n    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@\"http://example.com/image.jpg\"]\n                      placeholderImage:[UIImage imageNamed:@\"placeholder\"]];\n \n    cell.textLabel.text = @\"My Text\";\n    return cell;\n}\n\n * @endcode\n */\n\n/**\n * Integrates SDWebImage async downloading and caching of remote images with UIImageView.\n */\n@interface UIImageView (WebCache)\n\n/**\n * Set the imageView `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url The url for the image.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url` and a placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @see sd_setImageWithURL:placeholderImage:options:\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url         The url for the image.\n * @param placeholder The image to be set initially, until the image request finishes.\n * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context;\n\n/**\n * Set the imageView `image` with an `url`.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder and custom options.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n/**\n * Set the imageView `image` with an `url`, placeholder, custom options and context.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed. This block has no return value\n *                       and takes the requested UIImage as first parameter. In case of error the image parameter\n *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean\n *                       indicating if the image was retrieved from the local cache or from the network.\n *                       The fourth parameter is the original image url.\n */\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIImageView+WebCache.h\"\n#import \"objc/runtime.h\"\n#import \"UIView+WebCacheOperation.h\"\n#import \"UIView+WebCache.h\"\n\n@implementation UIImageView (WebCache)\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock];\n}\n\n- (void)sd_setImageWithURL:(nullable NSURL *)url\n          placeholderImage:(nullable UIImage *)placeholder\n                   options:(SDWebImageOptions)options\n                   context:(nullable SDWebImageContext *)context\n                  progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                 completed:(nullable SDExternalCompletionBlock)completedBlock {\n    [self sd_internalSetImageWithURL:url\n                    placeholderImage:placeholder\n                             options:options\n                             context:context\n                       setImageBlock:nil\n                            progress:progressBlock\n                           completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {\n                               if (completedBlock) {\n                                   completedBlock(image, error, cacheType, imageURL);\n                               }\n                           }];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n#import \"SDWebImageManager.h\"\n#import \"SDWebImageTransition.h\"\n#import \"SDWebImageIndicator.h\"\n\n/**\n The value specify that the image progress unit count cannot be determined because the progressBlock is not been called.\n */\nFOUNDATION_EXPORT const int64_t SDWebImageProgressUnitCountUnknown; /* 1LL */\n\ntypedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL);\n\n/**\n Integrates SDWebImage async downloading and caching of remote images with UIView subclass.\n */\n@interface UIView (WebCache)\n\n/**\n * Get the current image URL.\n *\n * @note Note that because of the limitations of categories this property can get out of sync if you use setImage: directly.\n */\n@property (nonatomic, strong, readonly, nullable) NSURL *sd_imageURL;\n\n/**\n * Get the current image operation key. Operation key is used to identify the different queries for one view instance (like UIButton).\n * See more about this in `SDWebImageContextSetImageOperationKey`.\n * If you cancel current image load, the key will be set to nil.\n * @note You can use method `UIView+WebCacheOperation` to investigate different queries' operation.\n */\n@property (nonatomic, strong, readonly, nullable) NSString *sd_latestOperationKey;\n\n/**\n * The current image loading progress associated to the view. The unit count is the received size and excepted size of download.\n * The `totalUnitCount` and `completedUnitCount` will be reset to 0 after a new image loading start (change from current queue). And they will be set to `SDWebImageProgressUnitCountUnknown` if the progressBlock not been called but the image loading success to mark the progress finished (change from main queue).\n * @note You can use Key-Value Observing on the progress, but you should take care that the change to progress is from a background queue during download(the same as progressBlock). If you want to using KVO and update the UI, make sure to dispatch on the main queue. And it's recommend to use some KVO libs like KVOController because it's more safe and easy to use.\n * @note The getter will create a progress instance if the value is nil. But by default, we don't create one. If you need to use Key-Value Observing, you must trigger the getter or set a custom progress instance before the loading start. The default value is nil.\n * @note Note that because of the limitations of categories this property can get out of sync if you update the progress directly.\n */\n@property (nonatomic, strong, null_resettable) NSProgress *sd_imageProgress;\n\n/**\n * Set the imageView `image` with an `url` and optionally a placeholder image.\n *\n * The download is asynchronous and cached.\n *\n * @param url            The url for the image.\n * @param placeholder    The image to be set initially, until the image request finishes.\n * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.\n * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.\n * @param setImageBlock  Block used for custom set image code. If not provide, use the built-in set image code (supports `UIImageView/NSImageView` and `UIButton/NSButton` currently)\n * @param progressBlock  A block called while image is downloading\n *                       @note the progress block is executed on a background queue\n * @param completedBlock A block called when operation has been completed.\n *   This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter.\n *   In case of error the image parameter is nil and the third parameter may contain an NSError.\n *\n *   The forth parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache\n *   or from the memory cache or from the network.\n *\n *   The fifth parameter normally is always YES. However, if you provide SDWebImageAvoidAutoSetImage with SDWebImageProgressiveLoad options to enable progressive downloading and set the image yourself. This block is thus called repeatedly with a partial image. When image is fully downloaded, the\n *   block is called a last time with the full image and the last parameter set to YES.\n *\n *   The last parameter is the original image URL\n */\n- (void)sd_internalSetImageWithURL:(nullable NSURL *)url\n                  placeholderImage:(nullable UIImage *)placeholder\n                           options:(SDWebImageOptions)options\n                           context:(nullable SDWebImageContext *)context\n                     setImageBlock:(nullable SDSetImageBlock)setImageBlock\n                          progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                         completed:(nullable SDInternalCompletionBlock)completedBlock;\n\n/**\n * Cancel the current image load\n */\n- (void)sd_cancelCurrentImageLoad;\n\n#if SD_UIKIT || SD_MAC\n\n#pragma mark - Image Transition\n\n/**\n The image transition when image load finished. See `SDWebImageTransition`.\n If you specify nil, do not do transition. Defaults to nil.\n */\n@property (nonatomic, strong, nullable) SDWebImageTransition *sd_imageTransition;\n\n#pragma mark - Image Indicator\n\n/**\n The image indicator during the image loading. If you do not need indicator, specify nil. Defaults to nil\n The setter will remove the old indicator view and add new indicator view to current view's subview.\n @note Because this is UI related, you should access only from the main queue.\n */\n@property (nonatomic, strong, nullable) id<SDWebImageIndicator> sd_imageIndicator;\n\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIView+WebCache.h\"\n#import \"objc/runtime.h\"\n#import \"UIView+WebCacheOperation.h\"\n#import \"SDWebImageError.h\"\n#import \"SDInternalMacros.h\"\n#import \"SDWebImageTransitionInternal.h\"\n\nconst int64_t SDWebImageProgressUnitCountUnknown = 1LL;\n\n@implementation UIView (WebCache)\n\n- (nullable NSURL *)sd_imageURL {\n    return objc_getAssociatedObject(self, @selector(sd_imageURL));\n}\n\n- (void)setSd_imageURL:(NSURL * _Nullable)sd_imageURL {\n    objc_setAssociatedObject(self, @selector(sd_imageURL), sd_imageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (nullable NSString *)sd_latestOperationKey {\n    return objc_getAssociatedObject(self, @selector(sd_latestOperationKey));\n}\n\n- (void)setSd_latestOperationKey:(NSString * _Nullable)sd_latestOperationKey {\n    objc_setAssociatedObject(self, @selector(sd_latestOperationKey), sd_latestOperationKey, OBJC_ASSOCIATION_COPY_NONATOMIC);\n}\n\n- (NSProgress *)sd_imageProgress {\n    NSProgress *progress = objc_getAssociatedObject(self, @selector(sd_imageProgress));\n    if (!progress) {\n        progress = [[NSProgress alloc] initWithParent:nil userInfo:nil];\n        self.sd_imageProgress = progress;\n    }\n    return progress;\n}\n\n- (void)setSd_imageProgress:(NSProgress *)sd_imageProgress {\n    objc_setAssociatedObject(self, @selector(sd_imageProgress), sd_imageProgress, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (void)sd_internalSetImageWithURL:(nullable NSURL *)url\n                  placeholderImage:(nullable UIImage *)placeholder\n                           options:(SDWebImageOptions)options\n                           context:(nullable SDWebImageContext *)context\n                     setImageBlock:(nullable SDSetImageBlock)setImageBlock\n                          progress:(nullable SDImageLoaderProgressBlock)progressBlock\n                         completed:(nullable SDInternalCompletionBlock)completedBlock {\n    if (context) {\n        // copy to avoid mutable object\n        context = [context copy];\n    } else {\n        context = [NSDictionary dictionary];\n    }\n    NSString *validOperationKey = context[SDWebImageContextSetImageOperationKey];\n    if (!validOperationKey) {\n        // pass through the operation key to downstream, which can used for tracing operation or image view class\n        validOperationKey = NSStringFromClass([self class]);\n        SDWebImageMutableContext *mutableContext = [context mutableCopy];\n        mutableContext[SDWebImageContextSetImageOperationKey] = validOperationKey;\n        context = [mutableContext copy];\n    }\n    self.sd_latestOperationKey = validOperationKey;\n    [self sd_cancelImageLoadOperationWithKey:validOperationKey];\n    self.sd_imageURL = url;\n    \n    if (!(options & SDWebImageDelayPlaceholder)) {\n        dispatch_main_async_safe(^{\n            [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:SDImageCacheTypeNone imageURL:url];\n        });\n    }\n    \n    if (url) {\n        // reset the progress\n        NSProgress *imageProgress = objc_getAssociatedObject(self, @selector(sd_imageProgress));\n        if (imageProgress) {\n            imageProgress.totalUnitCount = 0;\n            imageProgress.completedUnitCount = 0;\n        }\n        \n#if SD_UIKIT || SD_MAC\n        // check and start image indicator\n        [self sd_startImageIndicator];\n        id<SDWebImageIndicator> imageIndicator = self.sd_imageIndicator;\n#endif\n        SDWebImageManager *manager = context[SDWebImageContextCustomManager];\n        if (!manager) {\n            manager = [SDWebImageManager sharedManager];\n        } else {\n            // remove this manager to avoid retain cycle (manger -> loader -> operation -> context -> manager)\n            SDWebImageMutableContext *mutableContext = [context mutableCopy];\n            mutableContext[SDWebImageContextCustomManager] = nil;\n            context = [mutableContext copy];\n        }\n        \n        SDImageLoaderProgressBlock combinedProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {\n            if (imageProgress) {\n                imageProgress.totalUnitCount = expectedSize;\n                imageProgress.completedUnitCount = receivedSize;\n            }\n#if SD_UIKIT || SD_MAC\n            if ([imageIndicator respondsToSelector:@selector(updateIndicatorProgress:)]) {\n                double progress = 0;\n                if (expectedSize != 0) {\n                    progress = (double)receivedSize / expectedSize;\n                }\n                progress = MAX(MIN(progress, 1), 0); // 0.0 - 1.0\n                dispatch_async(dispatch_get_main_queue(), ^{\n                    [imageIndicator updateIndicatorProgress:progress];\n                });\n            }\n#endif\n            if (progressBlock) {\n                progressBlock(receivedSize, expectedSize, targetURL);\n            }\n        };\n        @weakify(self);\n        id <SDWebImageOperation> operation = [manager loadImageWithURL:url options:options context:context progress:combinedProgressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {\n            @strongify(self);\n            if (!self) { return; }\n            // if the progress not been updated, mark it to complete state\n            if (imageProgress && finished && !error && imageProgress.totalUnitCount == 0 && imageProgress.completedUnitCount == 0) {\n                imageProgress.totalUnitCount = SDWebImageProgressUnitCountUnknown;\n                imageProgress.completedUnitCount = SDWebImageProgressUnitCountUnknown;\n            }\n            \n#if SD_UIKIT || SD_MAC\n            // check and stop image indicator\n            if (finished) {\n                [self sd_stopImageIndicator];\n            }\n#endif\n            \n            BOOL shouldCallCompletedBlock = finished || (options & SDWebImageAvoidAutoSetImage);\n            BOOL shouldNotSetImage = ((image && (options & SDWebImageAvoidAutoSetImage)) ||\n                                      (!image && !(options & SDWebImageDelayPlaceholder)));\n            SDWebImageNoParamsBlock callCompletedBlockClosure = ^{\n                if (!self) { return; }\n                if (!shouldNotSetImage) {\n                    [self sd_setNeedsLayout];\n                }\n                if (completedBlock && shouldCallCompletedBlock) {\n                    completedBlock(image, data, error, cacheType, finished, url);\n                }\n            };\n            \n            // case 1a: we got an image, but the SDWebImageAvoidAutoSetImage flag is set\n            // OR\n            // case 1b: we got no image and the SDWebImageDelayPlaceholder is not set\n            if (shouldNotSetImage) {\n                dispatch_main_async_safe(callCompletedBlockClosure);\n                return;\n            }\n            \n            UIImage *targetImage = nil;\n            NSData *targetData = nil;\n            if (image) {\n                // case 2a: we got an image and the SDWebImageAvoidAutoSetImage is not set\n                targetImage = image;\n                targetData = data;\n            } else if (options & SDWebImageDelayPlaceholder) {\n                // case 2b: we got no image and the SDWebImageDelayPlaceholder flag is set\n                targetImage = placeholder;\n                targetData = nil;\n            }\n            \n#if SD_UIKIT || SD_MAC\n            // check whether we should use the image transition\n            SDWebImageTransition *transition = nil;\n            BOOL shouldUseTransition = NO;\n            if (options & SDWebImageForceTransition) {\n                // Always\n                shouldUseTransition = YES;\n            } else if (cacheType == SDImageCacheTypeNone) {\n                // From network\n                shouldUseTransition = YES;\n            } else {\n                // From disk (and, user don't use sync query)\n                if (cacheType == SDImageCacheTypeMemory) {\n                    shouldUseTransition = NO;\n                } else if (cacheType == SDImageCacheTypeDisk) {\n                    if (options & SDWebImageQueryMemoryDataSync || options & SDWebImageQueryDiskDataSync) {\n                        shouldUseTransition = NO;\n                    } else {\n                        shouldUseTransition = YES;\n                    }\n                } else {\n                    // Not valid cache type, fallback\n                    shouldUseTransition = NO;\n                }\n            }\n            if (finished && shouldUseTransition) {\n                transition = self.sd_imageTransition;\n            }\n#endif\n            dispatch_main_async_safe(^{\n#if SD_UIKIT || SD_MAC\n                [self sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];\n#else\n                [self sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:cacheType imageURL:imageURL];\n#endif\n                callCompletedBlockClosure();\n            });\n        }];\n        [self sd_setImageLoadOperation:operation forKey:validOperationKey];\n    } else {\n#if SD_UIKIT || SD_MAC\n        [self sd_stopImageIndicator];\n#endif\n        dispatch_main_async_safe(^{\n            if (completedBlock) {\n                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @\"Image url is nil\"}];\n                completedBlock(nil, nil, error, SDImageCacheTypeNone, YES, url);\n            }\n        });\n    }\n}\n\n- (void)sd_cancelCurrentImageLoad {\n    [self sd_cancelImageLoadOperationWithKey:self.sd_latestOperationKey];\n    self.sd_latestOperationKey = nil;\n}\n\n- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {\n#if SD_UIKIT || SD_MAC\n    [self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:cacheType imageURL:imageURL];\n#else\n    // watchOS does not support view transition. Simplify the logic\n    if (setImageBlock) {\n        setImageBlock(image, imageData, cacheType, imageURL);\n    } else if ([self isKindOfClass:[UIImageView class]]) {\n        UIImageView *imageView = (UIImageView *)self;\n        [imageView setImage:image];\n    }\n#endif\n}\n\n#if SD_UIKIT || SD_MAC\n- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {\n    UIView *view = self;\n    SDSetImageBlock finalSetImageBlock;\n    if (setImageBlock) {\n        finalSetImageBlock = setImageBlock;\n    } else if ([view isKindOfClass:[UIImageView class]]) {\n        UIImageView *imageView = (UIImageView *)view;\n        finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) {\n            imageView.image = setImage;\n        };\n    }\n#if SD_UIKIT\n    else if ([view isKindOfClass:[UIButton class]]) {\n        UIButton *button = (UIButton *)view;\n        finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) {\n            [button setImage:setImage forState:UIControlStateNormal];\n        };\n    }\n#endif\n#if SD_MAC\n    else if ([view isKindOfClass:[NSButton class]]) {\n        NSButton *button = (NSButton *)view;\n        finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) {\n            button.image = setImage;\n        };\n    }\n#endif\n    \n    if (transition) {\n        NSString *originalOperationKey = view.sd_latestOperationKey;\n\n#if SD_UIKIT\n        [UIView transitionWithView:view duration:0 options:0 animations:^{\n            if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                return;\n            }\n            // 0 duration to let UIKit render placeholder and prepares block\n            if (transition.prepares) {\n                transition.prepares(view, image, imageData, cacheType, imageURL);\n            }\n        } completion:^(BOOL finished) {\n            [UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{\n                if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                    return;\n                }\n                if (finalSetImageBlock && !transition.avoidAutoSetImage) {\n                    finalSetImageBlock(image, imageData, cacheType, imageURL);\n                }\n                if (transition.animations) {\n                    transition.animations(view, image);\n                }\n            } completion:^(BOOL finished) {\n                if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                    return;\n                }\n                if (transition.completion) {\n                    transition.completion(finished);\n                }\n            }];\n        }];\n#elif SD_MAC\n        [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull prepareContext) {\n            if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                return;\n            }\n            // 0 duration to let AppKit render placeholder and prepares block\n            prepareContext.duration = 0;\n            if (transition.prepares) {\n                transition.prepares(view, image, imageData, cacheType, imageURL);\n            }\n        } completionHandler:^{\n            [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {\n                if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                    return;\n                }\n                context.duration = transition.duration;\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n                CAMediaTimingFunction *timingFunction = transition.timingFunction;\n#pragma clang diagnostic pop\n                if (!timingFunction) {\n                    timingFunction = SDTimingFunctionFromAnimationOptions(transition.animationOptions);\n                }\n                context.timingFunction = timingFunction;\n                context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation);\n                if (finalSetImageBlock && !transition.avoidAutoSetImage) {\n                    finalSetImageBlock(image, imageData, cacheType, imageURL);\n                }\n                CATransition *trans = SDTransitionFromAnimationOptions(transition.animationOptions);\n                if (trans) {\n                    [view.layer addAnimation:trans forKey:kCATransition];\n                }\n                if (transition.animations) {\n                    transition.animations(view, image);\n                }\n            } completionHandler:^{\n                if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) {\n                    return;\n                }\n                if (transition.completion) {\n                    transition.completion(YES);\n                }\n            }];\n        }];\n#endif\n    } else {\n        if (finalSetImageBlock) {\n            finalSetImageBlock(image, imageData, cacheType, imageURL);\n        }\n    }\n}\n#endif\n\n- (void)sd_setNeedsLayout {\n#if SD_UIKIT\n    [self setNeedsLayout];\n#elif SD_MAC\n    [self setNeedsLayout:YES];\n#elif SD_WATCH\n    // Do nothing because WatchKit automatically layout the view after property change\n#endif\n}\n\n#if SD_UIKIT || SD_MAC\n\n#pragma mark - Image Transition\n- (SDWebImageTransition *)sd_imageTransition {\n    return objc_getAssociatedObject(self, @selector(sd_imageTransition));\n}\n\n- (void)setSd_imageTransition:(SDWebImageTransition *)sd_imageTransition {\n    objc_setAssociatedObject(self, @selector(sd_imageTransition), sd_imageTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n#pragma mark - Indicator\n- (id<SDWebImageIndicator>)sd_imageIndicator {\n    return objc_getAssociatedObject(self, @selector(sd_imageIndicator));\n}\n\n- (void)setSd_imageIndicator:(id<SDWebImageIndicator>)sd_imageIndicator {\n    // Remove the old indicator view\n    id<SDWebImageIndicator> previousIndicator = self.sd_imageIndicator;\n    [previousIndicator.indicatorView removeFromSuperview];\n    \n    objc_setAssociatedObject(self, @selector(sd_imageIndicator), sd_imageIndicator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n    \n    // Add the new indicator view\n    UIView *view = sd_imageIndicator.indicatorView;\n    if (CGRectEqualToRect(view.frame, CGRectZero)) {\n        view.frame = self.bounds;\n    }\n    // Center the indicator view\n#if SD_MAC\n    [view setFrameOrigin:CGPointMake(round((NSWidth(self.bounds) - NSWidth(view.frame)) / 2), round((NSHeight(self.bounds) - NSHeight(view.frame)) / 2))];\n#else\n    view.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));\n#endif\n    view.hidden = NO;\n    [self addSubview:view];\n}\n\n- (void)sd_startImageIndicator {\n    id<SDWebImageIndicator> imageIndicator = self.sd_imageIndicator;\n    if (!imageIndicator) {\n        return;\n    }\n    dispatch_main_async_safe(^{\n        [imageIndicator startAnimatingIndicator];\n    });\n}\n\n- (void)sd_stopImageIndicator {\n    id<SDWebImageIndicator> imageIndicator = self.sd_imageIndicator;\n    if (!imageIndicator) {\n        return;\n    }\n    dispatch_main_async_safe(^{\n        [imageIndicator stopAnimatingIndicator];\n    });\n}\n\n#endif\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageOperation.h\"\n\n/**\n These methods are used to support canceling for UIView image loading, it's designed to be used internal but not external.\n All the stored operations are weak, so it will be dealloced after image loading finished. If you need to store operations, use your own class to keep a strong reference for them.\n */\n@interface UIView (WebCacheOperation)\n\n/**\n *  Get the image load operation for key\n *\n *  @param key key for identifying the operations\n *  @return the image load operation\n */\n- (nullable id<SDWebImageOperation>)sd_imageLoadOperationForKey:(nullable NSString *)key;\n\n/**\n *  Set the image load operation (storage in a UIView based weak map table)\n *\n *  @param operation the operation\n *  @param key       key for storing the operation\n */\n- (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key;\n\n/**\n *  Cancel all operations for the current UIView and key\n *\n *  @param key key for identifying the operations\n */\n- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key;\n\n/**\n *  Just remove the operations corresponding to the current UIView and key without cancelling them\n *\n *  @param key key for identifying the operations\n */\n- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIView+WebCacheOperation.h\"\n#import \"objc/runtime.h\"\n\nstatic char loadOperationKey;\n\n// key is strong, value is weak because operation instance is retained by SDWebImageManager's runningOperations property\n// we should use lock to keep thread-safe because these method may not be accessed from main queue\ntypedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;\n\n@implementation UIView (WebCacheOperation)\n\n- (SDOperationsDictionary *)sd_operationDictionary {\n    @synchronized(self) {\n        SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);\n        if (operations) {\n            return operations;\n        }\n        operations = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];\n        objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n        return operations;\n    }\n}\n\n- (nullable id<SDWebImageOperation>)sd_imageLoadOperationForKey:(nullable NSString *)key  {\n    id<SDWebImageOperation> operation;\n    if (key) {\n        SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];\n        @synchronized (self) {\n            operation = [operationDictionary objectForKey:key];\n        }\n    }\n    return operation;\n}\n\n- (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key {\n    if (key) {\n        [self sd_cancelImageLoadOperationWithKey:key];\n        if (operation) {\n            SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];\n            @synchronized (self) {\n                [operationDictionary setObject:operation forKey:key];\n            }\n        }\n    }\n}\n\n- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key {\n    if (key) {\n        // Cancel in progress downloader from queue\n        SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];\n        id<SDWebImageOperation> operation;\n        \n        @synchronized (self) {\n            operation = [operationDictionary objectForKey:key];\n        }\n        if (operation) {\n            if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {\n                [operation cancel];\n            }\n            @synchronized (self) {\n                [operationDictionary removeObjectForKey:key];\n            }\n        }\n    }\n}\n\n- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key {\n    if (key) {\n        SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];\n        @synchronized (self) {\n            [operationDictionary removeObjectForKey:key];\n        }\n    }\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_MAC\n\n#import \"UIImage+Transform.h\"\n\n@interface NSBezierPath (SDRoundedCorners)\n\n/**\n Convenience way to create a bezier path with the specify rounding corners on macOS. Same as the one on `UIBezierPath`.\n */\n+ (nonnull instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius;\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"NSBezierPath+SDRoundedCorners.h\"\n\n#if SD_MAC\n\n@implementation NSBezierPath (SDRoundedCorners)\n\n+ (instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius {\n    NSBezierPath *path = [NSBezierPath bezierPath];\n    \n    CGFloat maxCorner = MIN(NSWidth(rect), NSHeight(rect)) / 2;\n    \n    CGFloat topLeftRadius = MIN(maxCorner, (corners & SDRectCornerTopLeft) ? cornerRadius : 0);\n    CGFloat topRightRadius = MIN(maxCorner, (corners & SDRectCornerTopRight) ? cornerRadius : 0);\n    CGFloat bottomLeftRadius = MIN(maxCorner, (corners & SDRectCornerBottomLeft) ? cornerRadius : 0);\n    CGFloat bottomRightRadius = MIN(maxCorner, (corners & SDRectCornerBottomRight) ? cornerRadius : 0);\n    \n    NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));\n    NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));\n    NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect));\n    NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));\n    \n    [path moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];\n    [path appendBezierPathWithArcFromPoint:topLeft toPoint:bottomLeft radius:topLeftRadius];\n    [path appendBezierPathWithArcFromPoint:bottomLeft toPoint:bottomRight radius:bottomLeftRadius];\n    [path appendBezierPathWithArcFromPoint:bottomRight toPoint:topRight radius:bottomRightRadius];\n    [path appendBezierPathWithArcFromPoint:topRight toPoint:topLeft radius:topRightRadius];\n    [path closePath];\n    \n    return path;\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDWebImageCompat.h\"\n\n/// Copy the associated object from source image to target image. The associated object including all the category read/write properties.\n/// @param source source\n/// @param target target\nFOUNDATION_EXPORT void SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable target);\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDAssociatedObject.h\"\n#import \"UIImage+Metadata.h\"\n#import \"UIImage+ExtendedCacheData.h\"\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"UIImage+ForceDecode.h\"\n\nvoid SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable target) {\n    if (!source || !target) {\n        return;\n    }\n    // Image Metadata\n    target.sd_isIncremental = source.sd_isIncremental;\n    target.sd_imageLoopCount = source.sd_imageLoopCount;\n    target.sd_imageFormat = source.sd_imageFormat;\n    // Force Decode\n    target.sd_isDecoded = source.sd_isDecoded;\n    // Extended Cache Data\n    target.sd_extendedObject = source.sd_extendedObject;\n}\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n@class SDAsyncBlockOperation;\ntypedef void (^SDAsyncBlock)(SDAsyncBlockOperation * __nonnull asyncOperation);\n\n/// A async block operation, success after you call `completer` (not like `NSBlockOperation` which is for sync block, success on return)\n@interface SDAsyncBlockOperation : NSOperation\n\n- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block;\n+ (nonnull instancetype)blockOperationWithBlock:(nonnull SDAsyncBlock)block;\n- (void)complete;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDAsyncBlockOperation.h\"\n\n@interface SDAsyncBlockOperation ()\n\n@property (assign, nonatomic, getter = isExecuting) BOOL executing;\n@property (assign, nonatomic, getter = isFinished) BOOL finished;\n@property (nonatomic, copy, nonnull) SDAsyncBlock executionBlock;\n\n@end\n\n@implementation SDAsyncBlockOperation\n\n@synthesize executing = _executing;\n@synthesize finished = _finished;\n\n- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block {\n    self = [super init];\n    if (self) {\n        self.executionBlock = block;\n    }\n    return self;\n}\n\n+ (nonnull instancetype)blockOperationWithBlock:(nonnull SDAsyncBlock)block {\n    SDAsyncBlockOperation *operation = [[SDAsyncBlockOperation alloc] initWithBlock:block];\n    return operation;\n}\n\n- (void)start {\n    @synchronized (self) {\n        if (self.isCancelled) {\n            self.finished = YES;\n            return;\n        }\n        \n        self.finished = NO;\n        self.executing = YES;\n        \n        if (self.executionBlock) {\n            self.executionBlock(self);\n        } else {\n            self.executing = NO;\n            self.finished = YES;\n        }\n    }\n}\n\n- (void)cancel {\n    @synchronized (self) {\n        [super cancel];\n        if (self.isExecuting) {\n            self.executing = NO;\n            self.finished = YES;\n        }\n    }\n}\n\n \n- (void)complete {\n    @synchronized (self) {\n        if (self.isExecuting) {\n            self.finished = YES;\n            self.executing = NO;\n        }\n    }\n }\n\n- (void)setFinished:(BOOL)finished {\n    [self willChangeValueForKey:@\"isFinished\"];\n    _finished = finished;\n    [self didChangeValueForKey:@\"isFinished\"];\n}\n\n- (void)setExecuting:(BOOL)executing {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    _executing = executing;\n    [self didChangeValueForKey:@\"isExecuting\"];\n}\n\n- (BOOL)isConcurrent {\n    return YES;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// Device information helper methods\n@interface SDDeviceHelper : NSObject\n\n+ (NSUInteger)totalMemory;\n+ (NSUInteger)freeMemory;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDDeviceHelper.h\"\n#import <mach/mach.h>\n\n@implementation SDDeviceHelper\n\n+ (NSUInteger)totalMemory {\n    return (NSUInteger)[[NSProcessInfo processInfo] physicalMemory];\n}\n\n+ (NSUInteger)freeMemory {\n    mach_port_t host_port = mach_host_self();\n    mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);\n    vm_size_t page_size;\n    vm_statistics_data_t vm_stat;\n    kern_return_t kern;\n    \n    kern = host_page_size(host_port, &page_size);\n    if (kern != KERN_SUCCESS) return 0;\n    kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);\n    if (kern != KERN_SUCCESS) return 0;\n    return vm_stat.free_count * page_size;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// Cross-platform display link wrapper. Do not retain the target\n/// Use `CADisplayLink` on iOS/tvOS, `CVDisplayLink` on macOS, `NSTimer` on watchOS\n@interface SDDisplayLink : NSObject\n\n@property (readonly, nonatomic, weak, nullable) id target;\n@property (readonly, nonatomic, assign, nonnull) SEL selector;\n@property (readonly, nonatomic) CFTimeInterval duration;\n@property (readonly, nonatomic) BOOL isRunning;\n\n+ (nonnull instancetype)displayLinkWithTarget:(nonnull id)target selector:(nonnull SEL)sel;\n\n- (void)addToRunLoop:(nonnull NSRunLoop *)runloop forMode:(nonnull NSRunLoopMode)mode;\n- (void)removeFromRunLoop:(nonnull NSRunLoop *)runloop forMode:(nonnull NSRunLoopMode)mode;\n\n- (void)start;\n- (void)stop;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.m",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDDisplayLink.h\"\n#import \"SDWeakProxy.h\"\n#if SD_MAC\n#import <CoreVideo/CoreVideo.h>\n#elif SD_IOS || SD_TV\n#import <QuartzCore/QuartzCore.h>\n#endif\n\n#if SD_MAC\nstatic CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext);\n#endif\n\n#define kSDDisplayLinkInterval 1.0 / 60\n\n@interface SDDisplayLink ()\n\n#if SD_MAC\n@property (nonatomic, assign) CVDisplayLinkRef displayLink;\n@property (nonatomic, assign) CVTimeStamp outputTime;\n@property (nonatomic, copy) NSRunLoopMode runloopMode;\n#elif SD_IOS || SD_TV\n@property (nonatomic, strong) CADisplayLink *displayLink;\n#else\n@property (nonatomic, strong) NSTimer *displayLink;\n@property (nonatomic, strong) NSRunLoop *runloop;\n@property (nonatomic, copy) NSRunLoopMode runloopMode;\n@property (nonatomic, assign) NSTimeInterval currentFireDate;\n#endif\n\n@end\n\n@implementation SDDisplayLink\n\n- (void)dealloc {\n#if SD_MAC\n    if (_displayLink) {\n        CVDisplayLinkRelease(_displayLink);\n        _displayLink = NULL;\n    }\n#elif SD_IOS || SD_TV\n    [_displayLink invalidate];\n    _displayLink = nil;\n#else\n    [_displayLink invalidate];\n    _displayLink = nil;\n#endif\n}\n\n- (instancetype)initWithTarget:(id)target selector:(SEL)sel {\n    self = [super init];\n    if (self) {\n        _target = target;\n        _selector = sel;\n#if SD_MAC\n        CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);\n        CVDisplayLinkSetOutputCallback(_displayLink, DisplayLinkCallback, (__bridge void *)self);\n#elif SD_IOS || SD_TV\n        SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];\n        _displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayLinkDidRefresh:)];\n#else\n        SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];\n        _displayLink = [NSTimer timerWithTimeInterval:kSDDisplayLinkInterval target:weakProxy selector:@selector(displayLinkDidRefresh:) userInfo:nil repeats:YES];\n#endif\n    }\n    return self;\n}\n\n+ (instancetype)displayLinkWithTarget:(id)target selector:(SEL)sel {\n    SDDisplayLink *displayLink = [[SDDisplayLink alloc] initWithTarget:target selector:sel];\n    return displayLink;\n}\n\n- (CFTimeInterval)duration {\n#if SD_MAC\n    CVTimeStamp outputTime = self.outputTime;\n    NSTimeInterval duration = 0;\n    double periodPerSecond = (double)outputTime.videoTimeScale * outputTime.rateScalar;\n    if (periodPerSecond > 0) {\n        duration = (double)outputTime.videoRefreshPeriod / periodPerSecond;\n    }\n#elif SD_IOS || SD_TV\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    NSTimeInterval duration = self.displayLink.duration * self.displayLink.frameInterval;\n#pragma clang diagnostic pop\n#else\n    NSTimeInterval duration = 0;\n    if (self.displayLink.isValid && self.currentFireDate != 0) {\n        NSTimeInterval nextFireDate = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink);\n        duration = nextFireDate - self.currentFireDate;\n    }\n#endif\n    if (duration == 0) {\n        duration = kSDDisplayLinkInterval;\n    }\n    return duration;\n}\n\n- (BOOL)isRunning {\n#if SD_MAC\n    return CVDisplayLinkIsRunning(self.displayLink);\n#elif SD_IOS || SD_TV\n    return !self.displayLink.isPaused;\n#else\n    return self.displayLink.isValid;\n#endif\n}\n\n- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode {\n    if  (!runloop || !mode) {\n        return;\n    }\n#if SD_MAC\n    self.runloopMode = mode;\n#elif SD_IOS || SD_TV\n    [self.displayLink addToRunLoop:runloop forMode:mode];\n#else\n    self.runloop = runloop;\n    self.runloopMode = mode;\n    CFRunLoopMode cfMode;\n    if ([mode isEqualToString:NSDefaultRunLoopMode]) {\n        cfMode = kCFRunLoopDefaultMode;\n    } else if ([mode isEqualToString:NSRunLoopCommonModes]) {\n        cfMode = kCFRunLoopCommonModes;\n    } else {\n        cfMode = (__bridge CFStringRef)mode;\n    }\n    CFRunLoopAddTimer(runloop.getCFRunLoop, (__bridge CFRunLoopTimerRef)self.displayLink, cfMode);\n#endif\n}\n\n- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode {\n    if  (!runloop || !mode) {\n        return;\n    }\n#if SD_MAC\n    self.runloopMode = nil;\n#elif SD_IOS || SD_TV\n    [self.displayLink removeFromRunLoop:runloop forMode:mode];\n#else\n    self.runloop = nil;\n    self.runloopMode = nil;\n    CFRunLoopMode cfMode;\n    if ([mode isEqualToString:NSDefaultRunLoopMode]) {\n        cfMode = kCFRunLoopDefaultMode;\n    } else if ([mode isEqualToString:NSRunLoopCommonModes]) {\n        cfMode = kCFRunLoopCommonModes;\n    } else {\n        cfMode = (__bridge CFStringRef)mode;\n    }\n    CFRunLoopRemoveTimer(runloop.getCFRunLoop, (__bridge CFRunLoopTimerRef)self.displayLink, cfMode);\n#endif\n}\n\n- (void)start {\n#if SD_MAC\n    CVDisplayLinkStart(self.displayLink);\n#elif SD_IOS || SD_TV\n    self.displayLink.paused = NO;\n#else\n    if (self.displayLink.isValid) {\n        [self.displayLink fire];\n    } else {\n        SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self];\n        self.displayLink = [NSTimer timerWithTimeInterval:kSDDisplayLinkInterval target:weakProxy selector:@selector(displayLinkDidRefresh:) userInfo:nil repeats:YES];\n        [self addToRunLoop:self.runloop forMode:self.runloopMode];\n    }\n#endif\n}\n\n- (void)stop {\n#if SD_MAC\n    CVDisplayLinkStop(self.displayLink);\n#elif SD_IOS || SD_TV\n    self.displayLink.paused = YES;\n#else\n    [self.displayLink invalidate];\n#endif\n}\n\n- (void)displayLinkDidRefresh:(id)displayLink {\n#if SD_MAC\n    // CVDisplayLink does not use runloop, but we can provide similar behavior for modes\n    // May use `default` runloop to avoid extra callback when in `eventTracking` (mouse drag, scroll) or `modalPanel` (modal panel)\n    NSString *runloopMode = self.runloopMode;\n    if (![runloopMode isEqualToString:NSRunLoopCommonModes] && ![runloopMode isEqualToString:NSRunLoop.mainRunLoop.currentMode]) {\n        return;\n    }\n#endif\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [_target performSelector:_selector withObject:self];\n#pragma clang diagnostic pop\n#if SD_WATCH\n    self.currentFireDate = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink);\n#endif\n}\n\n@end\n\n#if SD_MAC\nstatic CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {\n    // CVDisplayLink callback is not on main queue\n    SDDisplayLink *object = (__bridge SDDisplayLink *)displayLinkContext;\n    if (inOutputTime) {\n        object.outputTime = *inOutputTime;\n    }\n    __weak SDDisplayLink *weakObject = object;\n    dispatch_async(dispatch_get_main_queue(), ^{\n        [weakObject displayLinkDidRefresh:(__bridge id)(displayLink)];\n    });\n    return kCVReturnSuccess;\n}\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.h",
    "content": "//\n//  This file is from https://gist.github.com/zydeco/6292773\n//\n//  Created by Jesús A. Álvarez on 2008-12-17.\n//  Copyright 2008-2009 namedfork.net. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/// File Extended Attribute (xattr) helper methods\n@interface SDFileAttributeHelper : NSObject\n\n+ (nullable NSArray<NSString *> *)extendedAttributeNamesAtPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err;\n+ (BOOL)hasExtendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err;\n+ (nullable NSData *)extendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err;\n+ (BOOL)setExtendedAttribute:(nonnull NSString *)name value:(nonnull NSData *)value atPath:(nonnull NSString *)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError * _Nullable * _Nullable)err;\n+ (BOOL)removeExtendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.m",
    "content": "//\n//  This file is from https://gist.github.com/zydeco/6292773\n//\n//  Created by Jesús A. Álvarez on 2008-12-17.\n//  Copyright 2008-2009 namedfork.net. All rights reserved.\n//\n\n#import \"SDFileAttributeHelper.h\"\n#import <sys/xattr.h>\n\n@implementation SDFileAttributeHelper\n\n+ (NSArray*)extendedAttributeNamesAtPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err {\n    int flags = follow? 0 : XATTR_NOFOLLOW;\n    \n    // get size of name list\n    ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags);\n    if (nameBuffLen == -1) {\n        if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:\n                         @{\n                             @\"error\": [NSString stringWithUTF8String:strerror(errno)],\n                             @\"function\": @\"listxattr\",\n                             @\":path\": path,\n                             @\":traverseLink\": @(follow)\n                         }\n                         ];\n        return nil;\n    } else if (nameBuffLen == 0) return @[];\n    \n    // get name list\n    NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen];\n    listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags);\n    \n    // convert to array\n    NSMutableArray * names = [NSMutableArray arrayWithCapacity:5];\n    char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen;\n    for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName))\n        [names addObject:[NSString stringWithUTF8String:nextName]];\n    return names.copy;\n}\n\n+ (BOOL)hasExtendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err {\n    int flags = follow? 0 : XATTR_NOFOLLOW;\n    \n    // get size of name list\n    ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags);\n    if (nameBuffLen == -1) {\n        if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:\n                         @{\n                             @\"error\": [NSString stringWithUTF8String:strerror(errno)],\n                             @\"function\": @\"listxattr\",\n                             @\":path\": path,\n                             @\":traverseLink\": @(follow)\n                         }\n                         ];\n        return NO;\n    } else if (nameBuffLen == 0) return NO;\n    \n    // get name list\n    NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen];\n    listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags);\n    \n    // find our name\n    char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen;\n    for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName))\n        if (strcmp(nextName, [name UTF8String]) == 0) return YES;\n    return NO;\n}\n\n+ (NSData *)extendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err {\n    int flags = follow? 0 : XATTR_NOFOLLOW;\n    // get length\n    ssize_t attrLen = getxattr([path fileSystemRepresentation], [name UTF8String], NULL, 0, 0, flags);\n    if (attrLen == -1) {\n        if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:\n                         @{\n                             @\"error\": [NSString stringWithUTF8String:strerror(errno)],\n                             @\"function\": @\"getxattr\",\n                             @\":name\": name,\n                             @\":path\": path,\n                             @\":traverseLink\": @(follow)\n                         }\n                         ];\n        return nil;\n    }\n    \n    // get attribute data\n    NSMutableData *attrData = [NSMutableData dataWithLength:attrLen];\n    getxattr([path fileSystemRepresentation], [name UTF8String], [attrData mutableBytes], attrLen, 0, flags);\n    return attrData;\n}\n\n+ (BOOL)setExtendedAttribute:(NSString *)name value:(NSData *)value atPath:(NSString *)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError **)err {\n    int flags = (follow? 0 : XATTR_NOFOLLOW) | (overwrite? 0 : XATTR_CREATE);\n    if (0 == setxattr([path fileSystemRepresentation], [name UTF8String], [value bytes], [value length], 0, flags)) return YES;\n    // error\n    if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:\n                     @{\n                         @\"error\": [NSString stringWithUTF8String:strerror(errno)],\n                         @\"function\": @\"setxattr\",\n                         @\":name\": name,\n                         @\":value.length\": @(value.length),\n                         @\":path\": path,\n                         @\":traverseLink\": @(follow),\n                         @\":overwrite\": @(overwrite)\n                     }\n                     ];\n    return NO;\n}\n\n+ (BOOL)removeExtendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err {\n    int flags = (follow? 0 : XATTR_NOFOLLOW);\n    if (0 == removexattr([path fileSystemRepresentation], [name UTF8String], flags)) return YES;\n    // error\n    if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:\n                     @{\n                         @\"error\": [NSString stringWithUTF8String:strerror(errno)],\n                         @\"function\": @\"removexattr\",\n                         @\":name\": name,\n                         @\":path\": path,\n                         @\":traverseLink\": @(follow)\n                     }\n                     ];\n    return NO;\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// A Image-Asset manager to work like UIKit/AppKit's image cache behavior\n/// Apple parse the Asset Catalog compiled file(`Assets.car`) by CoreUI.framework, however it's a private framework and there are no other ways to directly get the data. So we just process the normal bundle files :)\n@interface SDImageAssetManager : NSObject\n\n@property (nonatomic, strong, nonnull) NSMapTable<NSString *, UIImage *> *imageTable;\n\n+ (nonnull instancetype)sharedAssetManager;\n- (nullable NSString *)getPathForName:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle preferredScale:(nonnull CGFloat *)scale;\n- (nullable UIImage *)imageForName:(nonnull NSString *)name;\n- (void)storeImage:(nonnull UIImage *)image forName:(nonnull NSString *)name;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageAssetManager.h\"\n#import \"SDInternalMacros.h\"\n\nstatic NSArray *SDBundlePreferredScales() {\n    static NSArray *scales;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n#if SD_WATCH\n        CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale;\n#elif SD_UIKIT\n        CGFloat screenScale = [UIScreen mainScreen].scale;\n#elif SD_MAC\n        CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor;\n#endif\n        if (screenScale <= 1) {\n            scales = @[@1,@2,@3];\n        } else if (screenScale <= 2) {\n            scales = @[@2,@3,@1];\n        } else {\n            scales = @[@3,@2,@1];\n        }\n    });\n    return scales;\n}\n\n@implementation SDImageAssetManager {\n    SD_LOCK_DECLARE(_lock);\n}\n\n+ (instancetype)sharedAssetManager {\n    static dispatch_once_t onceToken;\n    static SDImageAssetManager *assetManager;\n    dispatch_once(&onceToken, ^{\n        assetManager = [[SDImageAssetManager alloc] init];\n    });\n    return assetManager;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        NSPointerFunctionsOptions valueOptions;\n#if SD_MAC\n        // Apple says that NSImage use a weak reference to value\n        valueOptions = NSPointerFunctionsWeakMemory;\n#else\n        // Apple says that UIImage use a strong reference to value\n        valueOptions = NSPointerFunctionsStrongMemory;\n#endif\n        _imageTable = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsCopyIn valueOptions:valueOptions];\n        SD_LOCK_INIT(_lock);\n#if SD_UIKIT\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n    }\n    return self;\n}\n\n- (void)dealloc {\n#if SD_UIKIT\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n#endif\n}\n\n- (void)didReceiveMemoryWarning:(NSNotification *)notification {\n    SD_LOCK(_lock);\n    [self.imageTable removeAllObjects];\n    SD_UNLOCK(_lock);\n}\n\n- (NSString *)getPathForName:(NSString *)name bundle:(NSBundle *)bundle preferredScale:(CGFloat *)scale {\n    NSParameterAssert(name);\n    NSParameterAssert(bundle);\n    NSString *path;\n    if (name.length == 0) {\n        return path;\n    }\n    if ([name hasSuffix:@\"/\"]) {\n        return path;\n    }\n    NSString *extension = name.pathExtension;\n    if (extension.length == 0) {\n        // If no extension, follow Apple's doc, check PNG format\n        extension = @\"png\";\n    }\n    name = [name stringByDeletingPathExtension];\n    \n    CGFloat providedScale = *scale;\n    NSArray *scales = SDBundlePreferredScales();\n    \n    // Check if file name contains scale\n    for (size_t i = 0; i < scales.count; i++) {\n        NSNumber *scaleValue = scales[i];\n        if ([name hasSuffix:[NSString stringWithFormat:@\"@%@x\", scaleValue]]) {\n            path = [bundle pathForResource:name ofType:extension];\n            if (path) {\n                *scale = scaleValue.doubleValue; // override\n                return path;\n            }\n        }\n    }\n    \n    // Search with provided scale first\n    if (providedScale != 0) {\n        NSString *scaledName = [name stringByAppendingFormat:@\"@%@x\", @(providedScale)];\n        path = [bundle pathForResource:scaledName ofType:extension];\n        if (path) {\n            return path;\n        }\n    }\n    \n    // Search with preferred scale\n    for (size_t i = 0; i < scales.count; i++) {\n        NSNumber *scaleValue = scales[i];\n        if (scaleValue.doubleValue == providedScale) {\n            // Ignore provided scale\n            continue;\n        }\n        NSString *scaledName = [name stringByAppendingFormat:@\"@%@x\", scaleValue];\n        path = [bundle pathForResource:scaledName ofType:extension];\n        if (path) {\n            *scale = scaleValue.doubleValue; // override\n            return path;\n        }\n    }\n    \n    // Search without scale\n    path = [bundle pathForResource:name ofType:extension];\n    \n    return path;\n}\n\n- (UIImage *)imageForName:(NSString *)name {\n    NSParameterAssert(name);\n    UIImage *image;\n    SD_LOCK(_lock);\n    image = [self.imageTable objectForKey:name];\n    SD_UNLOCK(_lock);\n    return image;\n}\n\n- (void)storeImage:(UIImage *)image forName:(NSString *)name {\n    NSParameterAssert(image);\n    NSParameterAssert(name);\n    SD_LOCK(_lock);\n    [self.imageTable setObject:image forKey:name];\n    SD_UNLOCK(_lock);\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// This is used for operation management, but not for operation queue execute\n@interface SDImageCachesManagerOperation : NSOperation\n\n@property (nonatomic, assign, readonly) NSUInteger pendingCount;\n\n- (void)beginWithTotalCount:(NSUInteger)totalCount;\n- (void)completeOne;\n- (void)done;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDImageCachesManagerOperation.h\"\n#import \"SDInternalMacros.h\"\n\n@implementation SDImageCachesManagerOperation {\n    SD_LOCK_DECLARE(_pendingCountLock);\n}\n\n@synthesize executing = _executing;\n@synthesize finished = _finished;\n@synthesize cancelled = _cancelled;\n@synthesize pendingCount = _pendingCount;\n\n- (instancetype)init {\n    if (self = [super init]) {\n        SD_LOCK_INIT(_pendingCountLock);\n        _pendingCount = 0;\n    }\n    return self;\n}\n\n- (void)beginWithTotalCount:(NSUInteger)totalCount {\n    self.executing = YES;\n    self.finished = NO;\n    _pendingCount = totalCount;\n}\n\n- (NSUInteger)pendingCount {\n    SD_LOCK(_pendingCountLock);\n    NSUInteger pendingCount = _pendingCount;\n    SD_UNLOCK(_pendingCountLock);\n    return pendingCount;\n}\n\n- (void)completeOne {\n    SD_LOCK(_pendingCountLock);\n    _pendingCount = _pendingCount > 0 ? _pendingCount - 1 : 0;\n    SD_UNLOCK(_pendingCountLock);\n}\n\n- (void)cancel {\n    self.cancelled = YES;\n    [self reset];\n}\n\n- (void)done {\n    self.finished = YES;\n    self.executing = NO;\n    [self reset];\n}\n\n- (void)reset {\n    SD_LOCK(_pendingCountLock);\n    _pendingCount = 0;\n    SD_UNLOCK(_pendingCountLock);\n}\n\n- (void)setFinished:(BOOL)finished {\n    [self willChangeValueForKey:@\"isFinished\"];\n    _finished = finished;\n    [self didChangeValueForKey:@\"isFinished\"];\n}\n\n- (void)setExecuting:(BOOL)executing {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    _executing = executing;\n    [self didChangeValueForKey:@\"isExecuting\"];\n}\n\n- (void)setCancelled:(BOOL)cancelled {\n    [self willChangeValueForKey:@\"isCancelled\"];\n    _cancelled = cancelled;\n    [self didChangeValueForKey:@\"isCancelled\"];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDImageIOAnimatedCoderInternal.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import <Foundation/Foundation.h>\n#import \"SDImageIOAnimatedCoder.h\"\n\n// AVFileTypeHEIC/AVFileTypeHEIF is defined in AVFoundation via iOS 11, we use this without import AVFoundation\n#define kSDUTTypeHEIC ((__bridge CFStringRef)@\"public.heic\")\n#define kSDUTTypeHEIF ((__bridge CFStringRef)@\"public.heif\")\n// HEIC Sequence (Animated Image)\n#define kSDUTTypeHEICS ((__bridge CFStringRef)@\"public.heics\")\n// kUTTypeWebP seems not defined in public UTI framework, Apple use the hardcode string, we define them :)\n#define kSDUTTypeWebP ((__bridge CFStringRef)@\"org.webmproject.webp\")\n\n@interface SDImageIOAnimatedCoder ()\n\n+ (NSTimeInterval)frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source;\n+ (NSUInteger)imageLoopCountWithSource:(nonnull CGImageSourceRef)source;\n+ (nullable UIImage *)createFrameAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(nullable NSDictionary *)options;\n+ (BOOL)canEncodeToFormat:(SDImageFormat)format;\n+ (BOOL)canDecodeFromFormat:(SDImageFormat)format;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import <os/lock.h>\n#import <libkern/OSAtomic.h>\n#import \"SDmetamacros.h\"\n\n#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\\\n    (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\\\n    (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\\\n    (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\\\n    (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)\n\n#ifndef SD_LOCK_DECLARE\n#if SD_USE_OS_UNFAIR_LOCK\n#define SD_LOCK_DECLARE(lock) os_unfair_lock lock\n#else\n#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \\\nOSSpinLock lock##_deprecated;\n#endif\n#endif\n\n#ifndef SD_LOCK_DECLARE_STATIC\n#if SD_USE_OS_UNFAIR_LOCK\n#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock\n#else\n#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \\\nstatic OSSpinLock lock##_deprecated;\n#endif\n#endif\n\n#ifndef SD_LOCK_INIT\n#if SD_USE_OS_UNFAIR_LOCK\n#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT\n#else\n#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \\\nelse lock##_deprecated = OS_SPINLOCK_INIT;\n#endif\n#endif\n\n#ifndef SD_LOCK\n#if SD_USE_OS_UNFAIR_LOCK\n#define SD_LOCK(lock) os_unfair_lock_lock(&lock)\n#else\n#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \\\nelse OSSpinLockLock(&lock##_deprecated);\n#endif\n#endif\n\n#ifndef SD_UNLOCK\n#if SD_USE_OS_UNFAIR_LOCK\n#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock)\n#else\n#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \\\nelse OSSpinLockUnlock(&lock##_deprecated);\n#endif\n#endif\n\n#ifndef SD_OPTIONS_CONTAINS\n#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value))\n#endif\n\n#ifndef SD_CSTRING\n#define SD_CSTRING(str) #str\n#endif\n\n#ifndef SD_NSSTRING\n#define SD_NSSTRING(str) @(SD_CSTRING(str))\n#endif\n\n#ifndef SD_SEL_SPI\n#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@\"_%@\", SD_NSSTRING(name)])\n#endif\n\n#ifndef weakify\n#define weakify(...) \\\nsd_keywordify \\\nmetamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__)\n#endif\n\n#ifndef strongify\n#define strongify(...) \\\nsd_keywordify \\\n_Pragma(\"clang diagnostic push\") \\\n_Pragma(\"clang diagnostic ignored \\\"-Wshadow\\\"\") \\\nmetamacro_foreach(sd_strongify_,, __VA_ARGS__) \\\n_Pragma(\"clang diagnostic pop\")\n#endif\n\n#define sd_weakify_(INDEX, CONTEXT, VAR) \\\nCONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);\n\n#define sd_strongify_(INDEX, VAR) \\\n__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);\n\n#if DEBUG\n#define sd_keywordify autoreleasepool {}\n#else\n#define sd_keywordify try {} @catch (...) {}\n#endif\n\n#ifndef onExit\n#define onExit \\\nsd_keywordify \\\n__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^\n#endif\n\ntypedef void (^sd_cleanupBlock_t)(void);\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n    void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block);\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDInternalMacros.h\"\n\nvoid sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block) {\n    (*block)();\n}\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SDWebImageCompat.h\"\n\n/// A weak proxy which forward all the message to the target\n@interface SDWeakProxy : NSProxy\n\n@property (nonatomic, weak, readonly, nullable) id target;\n\n- (nonnull instancetype)initWithTarget:(nonnull id)target;\n+ (nonnull instancetype)proxyWithTarget:(nonnull id)target;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWeakProxy.h\"\n\n@implementation SDWeakProxy\n\n- (instancetype)initWithTarget:(id)target {\n    _target = target;\n    return self;\n}\n\n+ (instancetype)proxyWithTarget:(id)target {\n    return [[SDWeakProxy alloc] initWithTarget:target];\n}\n\n- (id)forwardingTargetForSelector:(SEL)selector {\n    return _target;\n}\n\n- (void)forwardInvocation:(NSInvocation *)invocation {\n    void *null = NULL;\n    [invocation setReturnValue:&null];\n}\n\n- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {\n    return [NSObject instanceMethodSignatureForSelector:@selector(init)];\n}\n\n- (BOOL)respondsToSelector:(SEL)aSelector {\n    return [_target respondsToSelector:aSelector];\n}\n\n- (BOOL)isEqual:(id)object {\n    return [_target isEqual:object];\n}\n\n- (NSUInteger)hash {\n    return [_target hash];\n}\n\n- (Class)superclass {\n    return [_target superclass];\n}\n\n- (Class)class {\n    return [_target class];\n}\n\n- (BOOL)isKindOfClass:(Class)aClass {\n    return [_target isKindOfClass:aClass];\n}\n\n- (BOOL)isMemberOfClass:(Class)aClass {\n    return [_target isMemberOfClass:aClass];\n}\n\n- (BOOL)conformsToProtocol:(Protocol *)aProtocol {\n    return [_target conformsToProtocol:aProtocol];\n}\n\n- (BOOL)isProxy {\n    return YES;\n}\n\n- (NSString *)description {\n    return [_target description];\n}\n\n- (NSString *)debugDescription {\n    return [_target debugDescription];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDWebImageTransitionInternal.h",
    "content": "/*\n* This file is part of the SDWebImage package.\n* (c) Olivier Poitrey <rs@dailymotion.com>\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n\n#import \"SDWebImageCompat.h\"\n\n#if SD_MAC\n\n#import <QuartzCore/QuartzCore.h>\n\n/// Helper method for Core Animation transition\nFOUNDATION_EXPORT CAMediaTimingFunction * _Nullable SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options);\nFOUNDATION_EXPORT CATransition * _Nullable SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options);\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/SDmetamacros.h",
    "content": "/**\n * Macros for metaprogramming\n * ExtendedC\n *\n * Copyright (C) 2012 Justin Spahr-Summers\n * Released under the MIT license\n */\n\n#ifndef EXTC_METAMACROS_H\n#define EXTC_METAMACROS_H\n\n\n/**\n * Executes one or more expressions (which may have a void type, such as a call\n * to a function that returns no value) and always returns true.\n */\n#define metamacro_exprify(...) \\\n    ((__VA_ARGS__), true)\n\n/**\n * Returns a string representation of VALUE after full macro expansion.\n */\n#define metamacro_stringify(VALUE) \\\n        metamacro_stringify_(VALUE)\n\n/**\n * Returns A and B concatenated after full macro expansion.\n */\n#define metamacro_concat(A, B) \\\n        metamacro_concat_(A, B)\n\n/**\n * Returns the Nth variadic argument (starting from zero). At least\n * N + 1 variadic arguments must be given. N must be between zero and twenty,\n * inclusive.\n */\n#define metamacro_at(N, ...) \\\n        metamacro_concat(metamacro_at, N)(__VA_ARGS__)\n\n/**\n * Returns the number of arguments (up to twenty) provided to the macro. At\n * least one argument must be provided.\n *\n * Inspired by P99: http://p99.gforge.inria.fr\n */\n#define metamacro_argcount(...) \\\n        metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n\n/**\n * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is\n * given. Only the index and current argument will thus be passed to MACRO.\n */\n#define metamacro_foreach(MACRO, SEP, ...) \\\n        metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)\n\n/**\n * For each consecutive variadic argument (up to twenty), MACRO is passed the\n * zero-based index of the current argument, CONTEXT, and then the argument\n * itself. The results of adjoining invocations of MACRO are then separated by\n * SEP.\n *\n * Inspired by P99: http://p99.gforge.inria.fr\n */\n#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \\\n        metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)\n\n/**\n * Identical to #metamacro_foreach_cxt. This can be used when the former would\n * fail due to recursive macro expansion.\n */\n#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \\\n        metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)\n\n/**\n * In consecutive order, appends each variadic argument (up to twenty) onto\n * BASE. The resulting concatenations are then separated by SEP.\n *\n * This is primarily useful to manipulate a list of macro invocations into instead\n * invoking a different, possibly related macro.\n */\n#define metamacro_foreach_concat(BASE, SEP, ...) \\\n        metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)\n\n/**\n * Iterates COUNT times, each time invoking MACRO with the current index\n * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO\n * are then separated by SEP.\n *\n * COUNT must be an integer between zero and twenty, inclusive.\n */\n#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \\\n        metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)\n\n/**\n * Returns the first argument given. At least one argument must be provided.\n *\n * This is useful when implementing a variadic macro, where you may have only\n * one variadic argument, but no way to retrieve it (for example, because \\c ...\n * always needs to match at least one argument).\n *\n * @code\n\n#define varmacro(...) \\\n    metamacro_head(__VA_ARGS__)\n\n * @endcode\n */\n#define metamacro_head(...) \\\n        metamacro_head_(__VA_ARGS__, 0)\n\n/**\n * Returns every argument except the first. At least two arguments must be\n * provided.\n */\n#define metamacro_tail(...) \\\n        metamacro_tail_(__VA_ARGS__)\n\n/**\n * Returns the first N (up to twenty) variadic arguments as a new argument list.\n * At least N variadic arguments must be provided.\n */\n#define metamacro_take(N, ...) \\\n        metamacro_concat(metamacro_take, N)(__VA_ARGS__)\n\n/**\n * Removes the first N (up to twenty) variadic arguments from the given argument\n * list. At least N variadic arguments must be provided.\n */\n#define metamacro_drop(N, ...) \\\n        metamacro_concat(metamacro_drop, N)(__VA_ARGS__)\n\n/**\n * Decrements VAL, which must be a number between zero and twenty, inclusive.\n *\n * This is primarily useful when dealing with indexes and counts in\n * metaprogramming.\n */\n#define metamacro_dec(VAL) \\\n        metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)\n\n/**\n * Increments VAL, which must be a number between zero and twenty, inclusive.\n *\n * This is primarily useful when dealing with indexes and counts in\n * metaprogramming.\n */\n#define metamacro_inc(VAL) \\\n        metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)\n\n/**\n * If A is equal to B, the next argument list is expanded; otherwise, the\n * argument list after that is expanded. A and B must be numbers between zero\n * and twenty, inclusive. Additionally, B must be greater than or equal to A.\n *\n * @code\n\n// expands to true\nmetamacro_if_eq(0, 0)(true)(false)\n\n// expands to false\nmetamacro_if_eq(0, 1)(true)(false)\n\n * @endcode\n *\n * This is primarily useful when dealing with indexes and counts in\n * metaprogramming.\n */\n#define metamacro_if_eq(A, B) \\\n        metamacro_concat(metamacro_if_eq, A)(B)\n\n/**\n * Identical to #metamacro_if_eq. This can be used when the former would fail\n * due to recursive macro expansion.\n */\n#define metamacro_if_eq_recursive(A, B) \\\n        metamacro_concat(metamacro_if_eq_recursive, A)(B)\n\n/**\n * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and\n * twenty, inclusive.\n *\n * For the purposes of this test, zero is considered even.\n */\n#define metamacro_is_even(N) \\\n        metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)\n\n/**\n * Returns the logical NOT of B, which must be the number zero or one.\n */\n#define metamacro_not(B) \\\n        metamacro_at(B, 1, 0)\n\n// IMPLEMENTATION DETAILS FOLLOW!\n// Do not write code that depends on anything below this line.\n#define metamacro_stringify_(VALUE) # VALUE\n#define metamacro_concat_(A, B) A ## B\n#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)\n#define metamacro_head_(FIRST, ...) FIRST\n#define metamacro_tail_(FIRST, ...) __VA_ARGS__\n#define metamacro_consume_(...)\n#define metamacro_expand_(...) __VA_ARGS__\n\n// implemented from scratch so that metamacro_concat() doesn't end up nesting\n#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)\n#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG\n\n// metamacro_at expansions\n#define metamacro_at0(...) metamacro_head(__VA_ARGS__)\n#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__)\n#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)\n\n// metamacro_foreach_cxt expansions\n#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)\n#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)\n\n#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \\\n    metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \\\n    SEP \\\n    MACRO(1, CONTEXT, _1)\n\n#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \\\n    metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \\\n    SEP \\\n    MACRO(2, CONTEXT, _2)\n\n#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \\\n    metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \\\n    SEP \\\n    MACRO(3, CONTEXT, _3)\n\n#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \\\n    metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \\\n    SEP \\\n    MACRO(4, CONTEXT, _4)\n\n#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \\\n    metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \\\n    SEP \\\n    MACRO(5, CONTEXT, _5)\n\n#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \\\n    metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \\\n    SEP \\\n    MACRO(6, CONTEXT, _6)\n\n#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \\\n    metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \\\n    SEP \\\n    MACRO(7, CONTEXT, _7)\n\n#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \\\n    metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \\\n    SEP \\\n    MACRO(8, CONTEXT, _8)\n\n#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \\\n    metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \\\n    SEP \\\n    MACRO(9, CONTEXT, _9)\n\n#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \\\n    metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \\\n    SEP \\\n    MACRO(10, CONTEXT, _10)\n\n#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \\\n    metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \\\n    SEP \\\n    MACRO(11, CONTEXT, _11)\n\n#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \\\n    metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \\\n    SEP \\\n    MACRO(12, CONTEXT, _12)\n\n#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \\\n    metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \\\n    SEP \\\n    MACRO(13, CONTEXT, _13)\n\n#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \\\n    metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \\\n    SEP \\\n    MACRO(14, CONTEXT, _14)\n\n#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \\\n    metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \\\n    SEP \\\n    MACRO(15, CONTEXT, _15)\n\n#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \\\n    metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \\\n    SEP \\\n    MACRO(16, CONTEXT, _16)\n\n#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \\\n    metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \\\n    SEP \\\n    MACRO(17, CONTEXT, _17)\n\n#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \\\n    metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \\\n    SEP \\\n    MACRO(18, CONTEXT, _18)\n\n#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \\\n    metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \\\n    SEP \\\n    MACRO(19, CONTEXT, _19)\n\n// metamacro_foreach_cxt_recursive expansions\n#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)\n#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)\n\n#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \\\n    metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \\\n    SEP \\\n    MACRO(1, CONTEXT, _1)\n\n#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \\\n    metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \\\n    SEP \\\n    MACRO(2, CONTEXT, _2)\n\n#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \\\n    metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \\\n    SEP \\\n    MACRO(3, CONTEXT, _3)\n\n#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \\\n    metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \\\n    SEP \\\n    MACRO(4, CONTEXT, _4)\n\n#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \\\n    metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \\\n    SEP \\\n    MACRO(5, CONTEXT, _5)\n\n#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \\\n    metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \\\n    SEP \\\n    MACRO(6, CONTEXT, _6)\n\n#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \\\n    metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \\\n    SEP \\\n    MACRO(7, CONTEXT, _7)\n\n#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \\\n    metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \\\n    SEP \\\n    MACRO(8, CONTEXT, _8)\n\n#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \\\n    metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \\\n    SEP \\\n    MACRO(9, CONTEXT, _9)\n\n#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \\\n    metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \\\n    SEP \\\n    MACRO(10, CONTEXT, _10)\n\n#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \\\n    metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \\\n    SEP \\\n    MACRO(11, CONTEXT, _11)\n\n#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \\\n    metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \\\n    SEP \\\n    MACRO(12, CONTEXT, _12)\n\n#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \\\n    metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \\\n    SEP \\\n    MACRO(13, CONTEXT, _13)\n\n#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \\\n    metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \\\n    SEP \\\n    MACRO(14, CONTEXT, _14)\n\n#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \\\n    metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \\\n    SEP \\\n    MACRO(15, CONTEXT, _15)\n\n#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \\\n    metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \\\n    SEP \\\n    MACRO(16, CONTEXT, _16)\n\n#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \\\n    metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \\\n    SEP \\\n    MACRO(17, CONTEXT, _17)\n\n#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \\\n    metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \\\n    SEP \\\n    MACRO(18, CONTEXT, _18)\n\n#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \\\n    metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \\\n    SEP \\\n    MACRO(19, CONTEXT, _19)\n\n// metamacro_for_cxt expansions\n#define metamacro_for_cxt0(MACRO, SEP, CONTEXT)\n#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)\n\n#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt1(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(1, CONTEXT)\n\n#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt2(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(2, CONTEXT)\n\n#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt3(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(3, CONTEXT)\n\n#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt4(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(4, CONTEXT)\n\n#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt5(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(5, CONTEXT)\n\n#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt6(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(6, CONTEXT)\n\n#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt7(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(7, CONTEXT)\n\n#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt8(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(8, CONTEXT)\n\n#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt9(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(9, CONTEXT)\n\n#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt10(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(10, CONTEXT)\n\n#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt11(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(11, CONTEXT)\n\n#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt12(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(12, CONTEXT)\n\n#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt13(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(13, CONTEXT)\n\n#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt14(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(14, CONTEXT)\n\n#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt15(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(15, CONTEXT)\n\n#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt16(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(16, CONTEXT)\n\n#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt17(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(17, CONTEXT)\n\n#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt18(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(18, CONTEXT)\n\n#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \\\n    metamacro_for_cxt19(MACRO, SEP, CONTEXT) \\\n    SEP \\\n    MACRO(19, CONTEXT)\n\n// metamacro_if_eq expansions\n#define metamacro_if_eq0(VALUE) \\\n    metamacro_concat(metamacro_if_eq0_, VALUE)\n\n#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_\n#define metamacro_if_eq0_1(...) metamacro_expand_\n#define metamacro_if_eq0_2(...) metamacro_expand_\n#define metamacro_if_eq0_3(...) metamacro_expand_\n#define metamacro_if_eq0_4(...) metamacro_expand_\n#define metamacro_if_eq0_5(...) metamacro_expand_\n#define metamacro_if_eq0_6(...) metamacro_expand_\n#define metamacro_if_eq0_7(...) metamacro_expand_\n#define metamacro_if_eq0_8(...) metamacro_expand_\n#define metamacro_if_eq0_9(...) metamacro_expand_\n#define metamacro_if_eq0_10(...) metamacro_expand_\n#define metamacro_if_eq0_11(...) metamacro_expand_\n#define metamacro_if_eq0_12(...) metamacro_expand_\n#define metamacro_if_eq0_13(...) metamacro_expand_\n#define metamacro_if_eq0_14(...) metamacro_expand_\n#define metamacro_if_eq0_15(...) metamacro_expand_\n#define metamacro_if_eq0_16(...) metamacro_expand_\n#define metamacro_if_eq0_17(...) metamacro_expand_\n#define metamacro_if_eq0_18(...) metamacro_expand_\n#define metamacro_if_eq0_19(...) metamacro_expand_\n#define metamacro_if_eq0_20(...) metamacro_expand_\n\n#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))\n#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))\n#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))\n#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))\n#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))\n#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))\n#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))\n#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))\n#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))\n#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))\n#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))\n#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))\n#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))\n#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))\n#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))\n#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))\n#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))\n#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))\n#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))\n#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))\n\n// metamacro_if_eq_recursive expansions\n#define metamacro_if_eq_recursive0(VALUE) \\\n    metamacro_concat(metamacro_if_eq_recursive0_, VALUE)\n\n#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_\n#define metamacro_if_eq_recursive0_1(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_2(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_3(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_4(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_5(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_6(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_7(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_8(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_9(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_10(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_11(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_12(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_13(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_14(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_15(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_16(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_17(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_18(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_19(...) metamacro_expand_\n#define metamacro_if_eq_recursive0_20(...) metamacro_expand_\n\n#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))\n#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))\n\n// metamacro_take expansions\n#define metamacro_take0(...)\n#define metamacro_take1(...) metamacro_head(__VA_ARGS__)\n#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))\n#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))\n#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))\n#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))\n#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))\n#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))\n#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))\n#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))\n#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))\n#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))\n#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))\n#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))\n#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))\n#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))\n#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))\n#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))\n#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))\n#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))\n#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))\n\n// metamacro_drop expansions\n#define metamacro_drop0(...) __VA_ARGS__\n#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)\n#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))\n#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))\n\n#endif\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"SDWebImageCompat.h\"\n\n@interface UIColor (SDHexString)\n\n/**\n Convenience way to get hex string from color. The output should always be 32-bit RGBA hex string like `#00000000`.\n */\n@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString;\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.m",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import \"UIColor+SDHexString.h\"\n\n@implementation UIColor (SDHexString)\n\n- (NSString *)sd_hexString {\n    CGFloat red, green, blue, alpha;\n#if SD_UIKIT\n    if (![self getRed:&red green:&green blue:&blue alpha:&alpha]) {\n        [self getWhite:&red alpha:&alpha];\n        green = red;\n        blue = red;\n    }\n#else\n    @try {\n        [self getRed:&red green:&green blue:&blue alpha:&alpha];\n    }\n    @catch (NSException *exception) {\n        [self getWhite:&red alpha:&alpha];\n        green = red;\n        blue = red;\n    }\n#endif\n    \n    red = roundf(red * 255.f);\n    green = roundf(green * 255.f);\n    blue = roundf(blue * 255.f);\n    alpha = roundf(alpha * 255.f);\n    \n    uint hex = ((uint)alpha << 24) | ((uint)red << 16) | ((uint)green << 8) | ((uint)blue);\n    \n    return [NSString stringWithFormat:@\"#%08x\", hex];\n}\n\n@end\n"
  },
  {
    "path": "Pods/SDWebImage/WebImage/SDWebImage.h",
    "content": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Florent Vilmart\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n#import <SDWebImage/SDWebImageCompat.h>\n\n//! Project version number for SDWebImage.\nFOUNDATION_EXPORT double SDWebImageVersionNumber;\n\n//! Project version string for SDWebImage.\nFOUNDATION_EXPORT const unsigned char SDWebImageVersionString[];\n\n// In this header, you should import all the public headers of your framework using statements like #import <SDWebImage/PublicHeader.h>\n\n#import <SDWebImage/SDWebImageManager.h>\n#import <SDWebImage/SDWebImageCacheKeyFilter.h>\n#import <SDWebImage/SDWebImageCacheSerializer.h>\n#import <SDWebImage/SDImageCacheConfig.h>\n#import <SDWebImage/SDImageCache.h>\n#import <SDWebImage/SDMemoryCache.h>\n#import <SDWebImage/SDDiskCache.h>\n#import <SDWebImage/SDImageCacheDefine.h>\n#import <SDWebImage/SDImageCachesManager.h>\n#import <SDWebImage/UIView+WebCache.h>\n#import <SDWebImage/UIImageView+WebCache.h>\n#import <SDWebImage/UIImageView+HighlightedWebCache.h>\n#import <SDWebImage/SDWebImageDownloaderConfig.h>\n#import <SDWebImage/SDWebImageDownloaderOperation.h>\n#import <SDWebImage/SDWebImageDownloaderRequestModifier.h>\n#import <SDWebImage/SDWebImageDownloaderResponseModifier.h>\n#import <SDWebImage/SDWebImageDownloaderDecryptor.h>\n#import <SDWebImage/SDImageLoader.h>\n#import <SDWebImage/SDImageLoadersManager.h>\n#import <SDWebImage/UIButton+WebCache.h>\n#import <SDWebImage/SDWebImagePrefetcher.h>\n#import <SDWebImage/UIView+WebCacheOperation.h>\n#import <SDWebImage/UIImage+Metadata.h>\n#import <SDWebImage/UIImage+MultiFormat.h>\n#import <SDWebImage/UIImage+MemoryCacheCost.h>\n#import <SDWebImage/UIImage+ExtendedCacheData.h>\n#import <SDWebImage/SDWebImageOperation.h>\n#import <SDWebImage/SDWebImageDownloader.h>\n#import <SDWebImage/SDWebImageTransition.h>\n#import <SDWebImage/SDWebImageIndicator.h>\n#import <SDWebImage/SDImageTransformer.h>\n#import <SDWebImage/UIImage+Transform.h>\n#import <SDWebImage/SDAnimatedImage.h>\n#import <SDWebImage/SDAnimatedImageView.h>\n#import <SDWebImage/SDAnimatedImageView+WebCache.h>\n#import <SDWebImage/SDAnimatedImagePlayer.h>\n#import <SDWebImage/SDImageCodersManager.h>\n#import <SDWebImage/SDImageCoder.h>\n#import <SDWebImage/SDImageAPNGCoder.h>\n#import <SDWebImage/SDImageGIFCoder.h>\n#import <SDWebImage/SDImageIOCoder.h>\n#import <SDWebImage/SDImageFrame.h>\n#import <SDWebImage/SDImageCoderHelper.h>\n#import <SDWebImage/SDImageGraphics.h>\n#import <SDWebImage/SDGraphicsImageRenderer.h>\n#import <SDWebImage/UIImage+GIF.h>\n#import <SDWebImage/UIImage+ForceDecode.h>\n#import <SDWebImage/NSData+ImageContentType.h>\n#import <SDWebImage/SDWebImageDefine.h>\n#import <SDWebImage/SDWebImageError.h>\n#import <SDWebImage/SDWebImageOptionsProcessor.h>\n#import <SDWebImage/SDImageIOAnimatedCoder.h>\n#import <SDWebImage/SDImageHEICCoder.h>\n#import <SDWebImage/SDImageAWebPCoder.h>\n\n// Mac\n#if __has_include(<SDWebImage/NSImage+Compatibility.h>)\n#import <SDWebImage/NSImage+Compatibility.h>\n#endif\n#if __has_include(<SDWebImage/NSButton+WebCache.h>)\n#import <SDWebImage/NSButton+WebCache.h>\n#endif\n#if __has_include(<SDWebImage/SDAnimatedImageRep.h>)\n#import <SDWebImage/SDAnimatedImageRep.h>\n#endif\n\n// MapKit\n#if __has_include(<SDWebImage/MKAnnotationView+WebCache.h>)\n#import <SDWebImage/MKAnnotationView+WebCache.h>\n#endif\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>2.3.1</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_Appirater : NSObject\n@end\n@implementation PodsDummy_Appirater\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater-prefix.pch",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"Appirater.h\"\n#import \"AppiraterDelegate.h\"\n\nFOUNDATION_EXPORT double AppiraterVersionNumber;\nFOUNDATION_EXPORT const unsigned char AppiraterVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Appirater\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -framework \"CFNetwork\" -framework \"SystemConfiguration\" -weak_framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/Appirater\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater.modulemap",
    "content": "framework module Appirater {\n  umbrella header \"Appirater-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/Appirater.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Appirater\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -framework \"CFNetwork\" -framework \"SystemConfiguration\" -weak_framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/Appirater\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/Appirater/ResourceBundle-Appirater-Appirater-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>BNDL</string>\n  <key>CFBundleShortVersionString</key>\n  <string>2.3.1</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>1</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/Firebase/Firebase.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_ROOT}/Headers/Private\" \"${PODS_ROOT}/Headers/Private/Firebase\" \"${PODS_ROOT}/Headers/Public\"\nOTHER_LDFLAGS = $(inherited) -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/Firebase\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/Firebase/Firebase.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_ROOT}/Headers/Private\" \"${PODS_ROOT}/Headers/Private/Firebase\" \"${PODS_ROOT}/Headers/Public\"\nOTHER_LDFLAGS = $(inherited) -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/Firebase\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist",
    "content": "${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh\n${PODS_ROOT}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework"
  },
  {
    "path": "Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist",
    "content": "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport/FirebaseAnalytics.framework"
  },
  {
    "path": "Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh",
    "content": "#!/bin/sh\nset -e\nset -u\nset -o pipefail\n\nfunction on_error {\n  echo \"$(realpath -mq \"${0}\"):$1: error: Unexpected failure\"\n}\ntrap 'on_error $LINENO' ERR\n\n\n# This protects against multiple targets copying the same framework dependency at the same time. The solution\n# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html\nRSYNC_PROTECT_TMP_FILES=(--filter \"P .*.??????\")\n\n\ncopy_dir()\n{\n  local source=\"$1\"\n  local destination=\"$2\"\n\n  # Use filter instead of exclude so missing patterns don't throw errors.\n  echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \\\"- CVS/\\\" --filter \\\"- .svn/\\\" --filter \\\"- .git/\\\" --filter \\\"- .hg/\\\" \\\"${source}*\\\" \\\"${destination}\\\"\"\n  rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}\"/* \"${destination}\"\n}\n\nSELECT_SLICE_RETVAL=\"\"\n\nselect_slice() {\n  local paths=(\"$@\")\n  # Locate the correct slice of the .xcframework for the current architectures\n  local target_path=\"\"\n\n  # Split archs on space so we can find a slice that has all the needed archs\n  local target_archs=$(echo $ARCHS | tr \" \" \"\\n\")\n\n  local target_variant=\"\"\n  if [[ \"$PLATFORM_NAME\" == *\"simulator\" ]]; then\n    target_variant=\"simulator\"\n  fi\n  if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && \"$EFFECTIVE_PLATFORM_NAME\" == *\"maccatalyst\" ]]; then\n    target_variant=\"maccatalyst\"\n  fi\n  for i in ${!paths[@]}; do\n    local matched_all_archs=\"1\"\n    for target_arch in $target_archs\n    do\n      if ! [[ \"${paths[$i]}\" == *\"$target_variant\"* ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n\n      # Verifies that the path contains the variant string (simulator or maccatalyst) if the variant is set.\n      if [[ -z \"$target_variant\" && (\"${paths[$i]}\" == *\"simulator\"* || \"${paths[$i]}\" == *\"maccatalyst\"*) ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n\n      # This regex matches all possible variants of the arch in the folder name:\n      # Let's say the folder name is: ios-armv7_armv7s_arm64_arm64e/CoconutLib.framework\n      # We match the following: -armv7_, _armv7s_, _arm64_ and _arm64e/.\n      # If we have a specific variant: ios-i386_x86_64-simulator/CoconutLib.framework\n      # We match the following: -i386_ and _x86_64-\n      # When the .xcframework wraps a static library, the folder name does not include\n      # any .framework. In that case, the folder name can be: ios-arm64_armv7\n      # We also match _armv7$ to handle that case.\n      local target_arch_regex=\"[_\\-]${target_arch}([\\/_\\-]|$)\"\n      if ! [[ \"${paths[$i]}\" =~ $target_arch_regex ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n    done\n\n    if [[ \"$matched_all_archs\" == \"1\" ]]; then\n      # Found a matching slice\n      echo \"Selected xcframework slice ${paths[$i]}\"\n      SELECT_SLICE_RETVAL=${paths[$i]}\n      break\n    fi\n  done\n}\n\ninstall_xcframework() {\n  local basepath=\"$1\"\n  local name=\"$2\"\n  local package_type=\"$3\"\n  local paths=(\"${@:4}\")\n\n  # Locate the correct slice of the .xcframework for the current architectures\n  select_slice \"${paths[@]}\"\n  local target_path=\"$SELECT_SLICE_RETVAL\"\n  if [[ -z \"$target_path\" ]]; then\n    echo \"warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS).\"\n    return\n  fi\n  local source=\"$basepath/$target_path\"\n\n  local destination=\"${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}\"\n\n  if [ ! -d \"$destination\" ]; then\n    mkdir -p \"$destination\"\n  fi\n\n  copy_dir \"$source/\" \"$destination\"\n  echo \"Copied $source to $destination\"\n}\n\ninstall_xcframework \"${PODS_ROOT}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework\" \"FirebaseAnalytics/AdIdSupport\" \"framework\" \"ios-arm64_armv7\" \"ios-arm64_i386_x86_64-simulator\"\n\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>8.6.1</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_FirebaseCore : NSObject\n@end\n@implementation PodsDummy_FirebaseCore\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"FIRApp.h\"\n#import \"FIRConfiguration.h\"\n#import \"FirebaseCore.h\"\n#import \"FIRLoggerLevel.h\"\n#import \"FIROptions.h\"\n#import \"FIRVersion.h\"\n\nFOUNDATION_EXPORT double FirebaseCoreVersionNumber;\nFOUNDATION_EXPORT const unsigned char FirebaseCoreVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 Firebase_VERSION=8.6.1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_CFLAGS = $(inherited) -fno-autolink\nOTHER_LDFLAGS = $(inherited) -framework \"FirebaseCoreDiagnostics\" -framework \"Foundation\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"UIKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCore\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap",
    "content": "framework module FirebaseCore {\n  umbrella header \"FirebaseCore-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCore/FirebaseCore.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 Firebase_VERSION=8.6.1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_CFLAGS = $(inherited) -fno-autolink\nOTHER_LDFLAGS = $(inherited) -framework \"FirebaseCoreDiagnostics\" -framework \"Foundation\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"UIKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCore\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>8.6.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_FirebaseCoreDiagnostics : NSObject\n@end\n@implementation PodsDummy_FirebaseCoreDiagnostics\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"FIRCoreDiagnostics.h\"\n\nFOUNDATION_EXPORT double FirebaseCoreDiagnosticsVersionNumber;\nFOUNDATION_EXPORT const unsigned char FirebaseCoreDiagnosticsVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.debug.xcconfig",
    "content": "CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES\nCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nGCC_TREAT_WARNINGS_AS_ERRORS = YES\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -framework \"CoreTelephony\" -framework \"Foundation\" -framework \"GoogleDataTransport\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"nanopb\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCoreDiagnostics\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.modulemap",
    "content": "framework module FirebaseCoreDiagnostics {\n  umbrella header \"FirebaseCoreDiagnostics-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.release.xcconfig",
    "content": "CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES\nCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nGCC_TREAT_WARNINGS_AS_ERRORS = YES\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -framework \"CoreTelephony\" -framework \"Foundation\" -framework \"GoogleDataTransport\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"nanopb\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCoreDiagnostics\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>8.6.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_FirebaseInstallations : NSObject\n@end\n@implementation PodsDummy_FirebaseInstallations\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"FirebaseInstallations.h\"\n#import \"FIRInstallations.h\"\n#import \"FIRInstallationsAuthTokenResult.h\"\n#import \"FIRInstallationsErrors.h\"\n\nFOUNDATION_EXPORT double FirebaseInstallationsVersionNumber;\nFOUNDATION_EXPORT const unsigned char FirebaseInstallationsVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -framework \"FBLPromises\" -framework \"FirebaseCore\" -framework \"Foundation\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"UIKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseInstallations\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap",
    "content": "framework module FirebaseInstallations {\n  umbrella header \"FirebaseInstallations-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -framework \"FBLPromises\" -framework \"FirebaseCore\" -framework \"Foundation\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"UIKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseInstallations\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist",
    "content": "${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh\n${PODS_ROOT}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework"
  },
  {
    "path": "Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist",
    "content": "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport/GoogleAppMeasurement.framework"
  },
  {
    "path": "Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh",
    "content": "#!/bin/sh\nset -e\nset -u\nset -o pipefail\n\nfunction on_error {\n  echo \"$(realpath -mq \"${0}\"):$1: error: Unexpected failure\"\n}\ntrap 'on_error $LINENO' ERR\n\n\n# This protects against multiple targets copying the same framework dependency at the same time. The solution\n# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html\nRSYNC_PROTECT_TMP_FILES=(--filter \"P .*.??????\")\n\n\ncopy_dir()\n{\n  local source=\"$1\"\n  local destination=\"$2\"\n\n  # Use filter instead of exclude so missing patterns don't throw errors.\n  echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \\\"- CVS/\\\" --filter \\\"- .svn/\\\" --filter \\\"- .git/\\\" --filter \\\"- .hg/\\\" \\\"${source}*\\\" \\\"${destination}\\\"\"\n  rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}\"/* \"${destination}\"\n}\n\nSELECT_SLICE_RETVAL=\"\"\n\nselect_slice() {\n  local paths=(\"$@\")\n  # Locate the correct slice of the .xcframework for the current architectures\n  local target_path=\"\"\n\n  # Split archs on space so we can find a slice that has all the needed archs\n  local target_archs=$(echo $ARCHS | tr \" \" \"\\n\")\n\n  local target_variant=\"\"\n  if [[ \"$PLATFORM_NAME\" == *\"simulator\" ]]; then\n    target_variant=\"simulator\"\n  fi\n  if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && \"$EFFECTIVE_PLATFORM_NAME\" == *\"maccatalyst\" ]]; then\n    target_variant=\"maccatalyst\"\n  fi\n  for i in ${!paths[@]}; do\n    local matched_all_archs=\"1\"\n    for target_arch in $target_archs\n    do\n      if ! [[ \"${paths[$i]}\" == *\"$target_variant\"* ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n\n      # Verifies that the path contains the variant string (simulator or maccatalyst) if the variant is set.\n      if [[ -z \"$target_variant\" && (\"${paths[$i]}\" == *\"simulator\"* || \"${paths[$i]}\" == *\"maccatalyst\"*) ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n\n      # This regex matches all possible variants of the arch in the folder name:\n      # Let's say the folder name is: ios-armv7_armv7s_arm64_arm64e/CoconutLib.framework\n      # We match the following: -armv7_, _armv7s_, _arm64_ and _arm64e/.\n      # If we have a specific variant: ios-i386_x86_64-simulator/CoconutLib.framework\n      # We match the following: -i386_ and _x86_64-\n      # When the .xcframework wraps a static library, the folder name does not include\n      # any .framework. In that case, the folder name can be: ios-arm64_armv7\n      # We also match _armv7$ to handle that case.\n      local target_arch_regex=\"[_\\-]${target_arch}([\\/_\\-]|$)\"\n      if ! [[ \"${paths[$i]}\" =~ $target_arch_regex ]]; then\n        matched_all_archs=\"0\"\n        break\n      fi\n    done\n\n    if [[ \"$matched_all_archs\" == \"1\" ]]; then\n      # Found a matching slice\n      echo \"Selected xcframework slice ${paths[$i]}\"\n      SELECT_SLICE_RETVAL=${paths[$i]}\n      break\n    fi\n  done\n}\n\ninstall_xcframework() {\n  local basepath=\"$1\"\n  local name=\"$2\"\n  local package_type=\"$3\"\n  local paths=(\"${@:4}\")\n\n  # Locate the correct slice of the .xcframework for the current architectures\n  select_slice \"${paths[@]}\"\n  local target_path=\"$SELECT_SLICE_RETVAL\"\n  if [[ -z \"$target_path\" ]]; then\n    echo \"warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS).\"\n    return\n  fi\n  local source=\"$basepath/$target_path\"\n\n  local destination=\"${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}\"\n\n  if [ ! -d \"$destination\" ]; then\n    mkdir -p \"$destination\"\n  fi\n\n  copy_dir \"$source/\" \"$destination\"\n  echo \"Copied $source to $destination\"\n}\n\ninstall_xcframework \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework\" \"GoogleAppMeasurement/AdIdSupport\" \"framework\" \"ios-arm64_armv7\" \"ios-arm64_i386_x86_64-simulator\"\n\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAppMeasurement\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAppMeasurement\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAppMeasurement\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAppMeasurement\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>9.1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_GoogleDataTransport : NSObject\n@end\n@implementation PodsDummy_GoogleDataTransport\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"GDTCORClock.h\"\n#import \"GDTCORConsoleLogger.h\"\n#import \"GDTCOREndpoints.h\"\n#import \"GDTCOREvent.h\"\n#import \"GDTCOREventDataObject.h\"\n#import \"GDTCOREventTransformer.h\"\n#import \"GDTCORTargets.h\"\n#import \"GDTCORTransport.h\"\n#import \"GoogleDataTransport.h\"\n\nFOUNDATION_EXPORT double GoogleDataTransportVersionNumber;\nFOUNDATION_EXPORT const unsigned char GoogleDataTransportVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport.debug.xcconfig",
    "content": "CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES\nCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 GDTCOR_VERSION=9.1.0\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}/\"\nOTHER_LDFLAGS = $(inherited) -l\"z\" -framework \"CoreTelephony\" -framework \"FBLPromises\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"nanopb\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleDataTransport\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport.modulemap",
    "content": "framework module GoogleDataTransport {\n  umbrella header \"GoogleDataTransport-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleDataTransport/GoogleDataTransport.release.xcconfig",
    "content": "CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES\nCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 GDTCOR_VERSION=9.1.0\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}/\"\nOTHER_LDFLAGS = $(inherited) -l\"z\" -framework \"CoreTelephony\" -framework \"FBLPromises\" -framework \"GoogleUtilities\" -framework \"Security\" -framework \"SystemConfiguration\" -framework \"nanopb\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleDataTransport\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>7.5.1</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_GoogleUtilities : NSObject\n@end\n@implementation PodsDummy_GoogleUtilities\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"GULAppDelegateSwizzler.h\"\n#import \"GULApplication.h\"\n#import \"GULSceneDelegateSwizzler.h\"\n#import \"GULAppEnvironmentUtil.h\"\n#import \"GULHeartbeatDateStorable.h\"\n#import \"GULHeartbeatDateStorage.h\"\n#import \"GULHeartbeatDateStorageUserDefaults.h\"\n#import \"GULKeychainStorage.h\"\n#import \"GULKeychainUtils.h\"\n#import \"GULSecureCoding.h\"\n#import \"GULURLSessionDataResponse.h\"\n#import \"NSURLSession+GULPromises.h\"\n#import \"GULLogger.h\"\n#import \"GULLoggerLevel.h\"\n#import \"GULOriginalIMPConvenienceMacros.h\"\n#import \"GULSwizzler.h\"\n#import \"GULNSData+zlib.h\"\n#import \"GULMutableDictionary.h\"\n#import \"GULNetwork.h\"\n#import \"GULNetworkConstants.h\"\n#import \"GULNetworkLoggerProtocol.h\"\n#import \"GULNetworkMessageCode.h\"\n#import \"GULNetworkURLSession.h\"\n#import \"GULReachabilityChecker.h\"\n#import \"GULUserDefaults.h\"\n\nFOUNDATION_EXPORT double GoogleUtilitiesVersionNumber;\nFOUNDATION_EXPORT const unsigned char GoogleUtilitiesVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -l\"z\" -framework \"FBLPromises\" -framework \"Security\" -framework \"SystemConfiguration\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleUtilities\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap",
    "content": "framework module GoogleUtilities {\n  umbrella header \"GoogleUtilities-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/GoogleUtilities/GoogleUtilities.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"\nGCC_C_LANGUAGE_STANDARD = c99\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}\"\nOTHER_LDFLAGS = $(inherited) -l\"z\" -framework \"FBLPromises\" -framework \"Security\" -framework \"SystemConfiguration\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleUtilities\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-acknowledgements.markdown",
    "content": "# Acknowledgements\nThis application makes use of the following third party libraries:\n\n## Appirater\n\nCopyright 2017. Arash Payan. This library is distributed under the terms of the MIT/X11.\n\n## Firebase\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## FirebaseAnalytics\n\nCopyright 2021 Google\n\n## FirebaseCore\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## FirebaseCoreDiagnostics\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## FirebaseInstallations\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## GoogleAppMeasurement\n\nCopyright 2021 Google\n\n## GoogleDataTransport\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## GoogleUtilities\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n================================================================================\n\nThe following copyright from Landon J. Fuller applies to the isAppEncrypted\nfunction in Environment/third_party/GULAppEnvironmentUtil.m.\n\nCopyright (c) 2017 Landon J. Fuller <landon@landonf.org>\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nComment from\n<a href=\"http://iphonedevwiki.net/index.php/Crack_prevention\">iPhone Dev Wiki\nCrack Prevention</a>: App Store binaries are signed by both their developer\nand Apple. This encrypts the binary so that decryption keys are needed in order\nto make the binary readable. When iOS executes the binary, the decryption keys\nare used to decrypt the binary into a readable state where it is then loaded\ninto memory and executed. iOS can tell the encryption status of a binary via the\ncryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is\na non-zero value then the binary is encrypted.\n\n'Cracking' works by letting the kernel decrypt the binary then siphoning the\ndecrypted data into a new binary file, resigning, and repackaging. This will\nonly work on jailbroken devices as codesignature validation has been removed.\nResigning takes place because while the codesignature doesn't have to be valid\nthanks to the jailbreak, it does have to be in place unless you have AppSync or\nsimilar to disable codesignature checks.\n\nMore information at <a href=\"http://landonf.org/2009/02/index.html\">Landon\nFuller's blog</a>\n\n\n## PromisesObjC\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n## SDWebImage\n\nCopyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com\n \nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n \nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n \nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n\n\n## nanopb\n\nCopyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi>\n\nThis software is provided 'as-is', without any express or \nimplied warranty. In no event will the authors be held liable \nfor any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any \npurpose, including commercial applications, and to alter it and \nredistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you \n   must not claim that you wrote the original software. If you use \n   this software in a product, an acknowledgment in the product \n   documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and \n   must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source \n   distribution.\n\nGenerated by CocoaPods - https://cocoapods.org\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-acknowledgements.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>PreferenceSpecifiers</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>This application makes use of the following third party libraries:</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>Acknowledgements</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Copyright 2017. Arash Payan. This library is distributed under the terms of the MIT/X11.</string>\n\t\t\t<key>License</key>\n\t\t\t<string>MIT</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>Appirater</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>Firebase</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Copyright 2021 Google</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Copyright</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>FirebaseAnalytics</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>FirebaseCore</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>FirebaseCoreDiagnostics</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>FirebaseInstallations</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Copyright 2021 Google</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Copyright</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>GoogleAppMeasurement</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>GoogleDataTransport</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n================================================================================\n\nThe following copyright from Landon J. Fuller applies to the isAppEncrypted\nfunction in Environment/third_party/GULAppEnvironmentUtil.m.\n\nCopyright (c) 2017 Landon J. Fuller &lt;landon@landonf.org&gt;\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nComment from\n&lt;a href=\"http://iphonedevwiki.net/index.php/Crack_prevention\"&gt;iPhone Dev Wiki\nCrack Prevention&lt;/a&gt;: App Store binaries are signed by both their developer\nand Apple. This encrypts the binary so that decryption keys are needed in order\nto make the binary readable. When iOS executes the binary, the decryption keys\nare used to decrypt the binary into a readable state where it is then loaded\ninto memory and executed. iOS can tell the encryption status of a binary via the\ncryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is\na non-zero value then the binary is encrypted.\n\n'Cracking' works by letting the kernel decrypt the binary then siphoning the\ndecrypted data into a new binary file, resigning, and repackaging. This will\nonly work on jailbroken devices as codesignature validation has been removed.\nResigning takes place because while the codesignature doesn't have to be valid\nthanks to the jailbreak, it does have to be in place unless you have AppSync or\nsimilar to disable codesignature checks.\n\nMore information at &lt;a href=\"http://landonf.org/2009/02/index.html\"&gt;Landon\nFuller's blog&lt;/a&gt;\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>GoogleUtilities</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>Apache</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>PromisesObjC</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com\n \nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n \nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n \nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>MIT</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>SDWebImage</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Copyright (c) 2011 Petteri Aimonen &lt;jpa at nanopb.mail.kapsi.fi&gt;\n\nThis software is provided 'as-is', without any express or \nimplied warranty. In no event will the authors be held liable \nfor any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any \npurpose, including commercial applications, and to alter it and \nredistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you \n   must not claim that you wrote the original software. If you use \n   this software in a product, an acknowledgment in the product \n   documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and \n   must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source \n   distribution.\n</string>\n\t\t\t<key>License</key>\n\t\t\t<string>zlib</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>nanopb</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Generated by CocoaPods - https://cocoapods.org</string>\n\t\t\t<key>Title</key>\n\t\t\t<string></string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t</array>\n\t<key>StringsTable</key>\n\t<string>Acknowledgements</string>\n\t<key>Title</key>\n\t<string>Acknowledgements</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_Pods_Spotify : NSObject\n@end\n@implementation PodsDummy_Pods_Spotify\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-Debug-input-files.xcfilelist",
    "content": "${PODS_ROOT}/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks.sh\n${BUILT_PRODUCTS_DIR}/Appirater/Appirater.framework\n${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework\n${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework\n${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework\n${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework\n${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework\n${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework\n${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework\n${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-Debug-output-files.xcfilelist",
    "content": "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Appirater.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-Release-input-files.xcfilelist",
    "content": "${PODS_ROOT}/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks.sh\n${BUILT_PRODUCTS_DIR}/Appirater/Appirater.framework\n${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework\n${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework\n${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework\n${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework\n${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework\n${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework\n${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework\n${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-Release-output-files.xcfilelist",
    "content": "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Appirater.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework\n${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks.sh",
    "content": "#!/bin/sh\nset -e\nset -u\nset -o pipefail\n\nfunction on_error {\n  echo \"$(realpath -mq \"${0}\"):$1: error: Unexpected failure\"\n}\ntrap 'on_error $LINENO' ERR\n\nif [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then\n  # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy\n  # frameworks to, so exit 0 (signalling the script phase was successful).\n  exit 0\nfi\n\necho \"mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\nmkdir -p \"${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\nCOCOAPODS_PARALLEL_CODE_SIGN=\"${COCOAPODS_PARALLEL_CODE_SIGN:-false}\"\nSWIFT_STDLIB_PATH=\"${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"\nBCSYMBOLMAP_DIR=\"BCSymbolMaps\"\n\n\n# This protects against multiple targets copying the same framework dependency at the same time. The solution\n# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html\nRSYNC_PROTECT_TMP_FILES=(--filter \"P .*.??????\")\n\n# Copies and strips a vendored framework\ninstall_framework()\n{\n  if [ -r \"${BUILT_PRODUCTS_DIR}/$1\" ]; then\n    local source=\"${BUILT_PRODUCTS_DIR}/$1\"\n  elif [ -r \"${BUILT_PRODUCTS_DIR}/$(basename \"$1\")\" ]; then\n    local source=\"${BUILT_PRODUCTS_DIR}/$(basename \"$1\")\"\n  elif [ -r \"$1\" ]; then\n    local source=\"$1\"\n  fi\n\n  local destination=\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\n  if [ -L \"${source}\" ]; then\n    echo \"Symlinked...\"\n    source=\"$(readlink \"${source}\")\"\n  fi\n\n  if [ -d \"${source}/${BCSYMBOLMAP_DIR}\" ]; then\n    # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied\n    find \"${source}/${BCSYMBOLMAP_DIR}\" -name \"*.bcsymbolmap\"|while read f; do\n      echo \"Installing $f\"\n      install_bcsymbolmap \"$f\" \"$destination\"\n      rm \"$f\"\n    done\n    rmdir \"${source}/${BCSYMBOLMAP_DIR}\"\n  fi\n\n  # Use filter instead of exclude so missing patterns don't throw errors.\n  echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \\\"- CVS/\\\" --filter \\\"- .svn/\\\" --filter \\\"- .git/\\\" --filter \\\"- .hg/\\\" --filter \\\"- Headers\\\" --filter \\\"- PrivateHeaders\\\" --filter \\\"- Modules\\\" \\\"${source}\\\" \\\"${destination}\\\"\"\n  rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"\n\n  local basename\n  basename=\"$(basename -s .framework \"$1\")\"\n  binary=\"${destination}/${basename}.framework/${basename}\"\n\n  if ! [ -r \"$binary\" ]; then\n    binary=\"${destination}/${basename}\"\n  elif [ -L \"${binary}\" ]; then\n    echo \"Destination binary is symlinked...\"\n    dirname=\"$(dirname \"${binary}\")\"\n    binary=\"${dirname}/$(readlink \"${binary}\")\"\n  fi\n\n  # Strip invalid architectures so \"fat\" simulator / device frameworks work on device\n  if [[ \"$(file \"$binary\")\" == *\"dynamically linked shared library\"* ]]; then\n    strip_invalid_archs \"$binary\"\n  fi\n\n  # Resign the code if required by the build settings to avoid unstable apps\n  code_sign_if_enabled \"${destination}/$(basename \"$1\")\"\n\n  # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.\n  if [ \"${XCODE_VERSION_MAJOR}\" -lt 7 ]; then\n    local swift_runtime_libs\n    swift_runtime_libs=$(xcrun otool -LX \"$binary\" | grep --color=never @rpath/libswift | sed -E s/@rpath\\\\/\\(.+dylib\\).*/\\\\1/g | uniq -u)\n    for lib in $swift_runtime_libs; do\n      echo \"rsync -auv \\\"${SWIFT_STDLIB_PATH}/${lib}\\\" \\\"${destination}\\\"\"\n      rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"\n      code_sign_if_enabled \"${destination}/${lib}\"\n    done\n  fi\n}\n# Copies and strips a vendored dSYM\ninstall_dsym() {\n  local source=\"$1\"\n  warn_missing_arch=${2:-true}\n  if [ -r \"$source\" ]; then\n    # Copy the dSYM into the targets temp dir.\n    echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --filter \\\"- CVS/\\\" --filter \\\"- .svn/\\\" --filter \\\"- .git/\\\" --filter \\\"- .hg/\\\" --filter \\\"- Headers\\\" --filter \\\"- PrivateHeaders\\\" --filter \\\"- Modules\\\" \\\"${source}\\\" \\\"${DERIVED_FILES_DIR}\\\"\"\n    rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"\n\n    local basename\n    basename=\"$(basename -s .dSYM \"$source\")\"\n    binary_name=\"$(ls \"$source/Contents/Resources/DWARF\")\"\n    binary=\"${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}\"\n\n    # Strip invalid architectures from the dSYM.\n    if [[ \"$(file \"$binary\")\" == *\"Mach-O \"*\"dSYM companion\"* ]]; then\n      strip_invalid_archs \"$binary\" \"$warn_missing_arch\"\n    fi\n    if [[ $STRIP_BINARY_RETVAL == 0 ]]; then\n      # Move the stripped file into its final destination.\n      echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \\\"- CVS/\\\" --filter \\\"- .svn/\\\" --filter \\\"- .git/\\\" --filter \\\"- .hg/\\\" --filter \\\"- Headers\\\" --filter \\\"- PrivateHeaders\\\" --filter \\\"- Modules\\\" \\\"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\\\" \\\"${DWARF_DSYM_FOLDER_PATH}\\\"\"\n      rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"\n    else\n      # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.\n      mkdir -p \"${DWARF_DSYM_FOLDER_PATH}\"\n      touch \"${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM\"\n    fi\n  fi\n}\n\n# Used as a return value for each invocation of `strip_invalid_archs` function.\nSTRIP_BINARY_RETVAL=0\n\n# Strip invalid architectures\nstrip_invalid_archs() {\n  binary=\"$1\"\n  warn_missing_arch=${2:-true}\n  # Get architectures for current target binary\n  binary_archs=\"$(lipo -info \"$binary\" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)\"\n  # Intersect them with the architectures we are building for\n  intersected_archs=\"$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\\n' | sort | uniq -d)\"\n  # If there are no archs supported by this binary then warn the user\n  if [[ -z \"$intersected_archs\" ]]; then\n    if [[ \"$warn_missing_arch\" == \"true\" ]]; then\n      echo \"warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS).\"\n    fi\n    STRIP_BINARY_RETVAL=1\n    return\n  fi\n  stripped=\"\"\n  for arch in $binary_archs; do\n    if ! [[ \"${ARCHS}\" == *\"$arch\"* ]]; then\n      # Strip non-valid architectures in-place\n      lipo -remove \"$arch\" -output \"$binary\" \"$binary\"\n      stripped=\"$stripped $arch\"\n    fi\n  done\n  if [[ \"$stripped\" ]]; then\n    echo \"Stripped $binary of architectures:$stripped\"\n  fi\n  STRIP_BINARY_RETVAL=0\n}\n\n# Copies the bcsymbolmap files of a vendored framework\ninstall_bcsymbolmap() {\n    local bcsymbolmap_path=\"$1\"\n    local destination=\"${BUILT_PRODUCTS_DIR}\"\n    echo \"rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\"\"\n    rsync --delete -av \"${RSYNC_PROTECT_TMP_FILES[@]}\" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\"\n}\n\n# Signs a framework with the provided identity\ncode_sign_if_enabled() {\n  if [ -n \"${EXPANDED_CODE_SIGN_IDENTITY:-}\" -a \"${CODE_SIGNING_REQUIRED:-}\" != \"NO\" -a \"${CODE_SIGNING_ALLOWED}\" != \"NO\" ]; then\n    # Use the current code_sign_identity\n    echo \"Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\n    local code_sign_cmd=\"/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'\"\n\n    if [ \"${COCOAPODS_PARALLEL_CODE_SIGN}\" == \"true\" ]; then\n      code_sign_cmd=\"$code_sign_cmd &\"\n    fi\n    echo \"$code_sign_cmd\"\n    eval \"$code_sign_cmd\"\n  fi\n}\n\nif [[ \"$CONFIGURATION\" == \"Debug\" ]]; then\n  install_framework \"${BUILT_PRODUCTS_DIR}/Appirater/Appirater.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework\"\nfi\nif [[ \"$CONFIGURATION\" == \"Release\" ]]; then\n  install_framework \"${BUILT_PRODUCTS_DIR}/Appirater/Appirater.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework\"\n  install_framework \"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework\"\nfi\nif [ \"${COCOAPODS_PARALLEL_CODE_SIGN}\" == \"true\" ]; then\n  wait\nfi\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n\nFOUNDATION_EXPORT double Pods_SpotifyVersionNumber;\nFOUNDATION_EXPORT const unsigned char Pods_SpotifyVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Appirater\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Appirater/Appirater.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers\" \"${PODS_ROOT}/Headers/Public\" \"${PODS_ROOT}/Headers/Public/Firebase\" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources \"${PODS_TARGET_SRCROOT}/Sources/FBLPromises/include\"\nLD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'\nOTHER_LDFLAGS = $(inherited) -ObjC -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"Appirater\" -framework \"CFNetwork\" -framework \"CoreTelephony\" -framework \"FBLPromises\" -framework \"FirebaseAnalytics\" -framework \"FirebaseCore\" -framework \"FirebaseCoreDiagnostics\" -framework \"FirebaseInstallations\" -framework \"Foundation\" -framework \"GoogleAppMeasurement\" -framework \"GoogleDataTransport\" -framework \"GoogleUtilities\" -framework \"ImageIO\" -framework \"SDWebImage\" -framework \"Security\" -framework \"StoreKit\" -framework \"SystemConfiguration\" -framework \"UIKit\" -framework \"nanopb\" -weak_framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_PODFILE_DIR_PATH = ${SRCROOT}/.\nPODS_ROOT = ${SRCROOT}/Pods\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify.modulemap",
    "content": "framework module Pods_Spotify {\n  umbrella header \"Pods-Spotify-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/Pods-Spotify/Pods-Spotify.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nFRAMEWORK_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Appirater\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_ROOT}/FirebaseAnalytics/Frameworks\" \"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\" \"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Appirater/Appirater.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers\" \"${PODS_ROOT}/Headers/Public\" \"${PODS_ROOT}/Headers/Public/Firebase\" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources \"${PODS_TARGET_SRCROOT}/Sources/FBLPromises/include\"\nLD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'\nOTHER_LDFLAGS = $(inherited) -ObjC -l\"c++\" -l\"sqlite3\" -l\"z\" -framework \"Appirater\" -framework \"CFNetwork\" -framework \"CoreTelephony\" -framework \"FBLPromises\" -framework \"FirebaseAnalytics\" -framework \"FirebaseCore\" -framework \"FirebaseCoreDiagnostics\" -framework \"FirebaseInstallations\" -framework \"Foundation\" -framework \"GoogleAppMeasurement\" -framework \"GoogleDataTransport\" -framework \"GoogleUtilities\" -framework \"ImageIO\" -framework \"SDWebImage\" -framework \"Security\" -framework \"StoreKit\" -framework \"SystemConfiguration\" -framework \"UIKit\" -framework \"nanopb\" -weak_framework \"StoreKit\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_PODFILE_DIR_PATH = ${SRCROOT}/.\nPODS_ROOT = ${SRCROOT}/Pods\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>2.0.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_PromisesObjC : NSObject\n@end\n@implementation PodsDummy_PromisesObjC\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"FBLPromise+All.h\"\n#import \"FBLPromise+Always.h\"\n#import \"FBLPromise+Any.h\"\n#import \"FBLPromise+Async.h\"\n#import \"FBLPromise+Await.h\"\n#import \"FBLPromise+Catch.h\"\n#import \"FBLPromise+Delay.h\"\n#import \"FBLPromise+Do.h\"\n#import \"FBLPromise+Race.h\"\n#import \"FBLPromise+Recover.h\"\n#import \"FBLPromise+Reduce.h\"\n#import \"FBLPromise+Retry.h\"\n#import \"FBLPromise+Testing.h\"\n#import \"FBLPromise+Then.h\"\n#import \"FBLPromise+Timeout.h\"\n#import \"FBLPromise+Validate.h\"\n#import \"FBLPromise+Wrap.h\"\n#import \"FBLPromise.h\"\n#import \"FBLPromiseError.h\"\n#import \"FBLPromises.h\"\n\nFOUNDATION_EXPORT double FBLPromisesVersionNumber;\nFOUNDATION_EXPORT const unsigned char FBLPromisesVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}/Sources/FBLPromises/include\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/PromisesObjC\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC.modulemap",
    "content": "framework module FBLPromises {\n  umbrella header \"PromisesObjC-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/PromisesObjC/PromisesObjC.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_TARGET_SRCROOT}/Sources/FBLPromises/include\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/PromisesObjC\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>5.11.1</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_SDWebImage : NSObject\n@end\n@implementation PodsDummy_SDWebImage\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage-prefix.pch",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"NSButton+WebCache.h\"\n#import \"NSData+ImageContentType.h\"\n#import \"NSImage+Compatibility.h\"\n#import \"SDAnimatedImage.h\"\n#import \"SDAnimatedImagePlayer.h\"\n#import \"SDAnimatedImageRep.h\"\n#import \"SDAnimatedImageView+WebCache.h\"\n#import \"SDAnimatedImageView.h\"\n#import \"SDDiskCache.h\"\n#import \"SDGraphicsImageRenderer.h\"\n#import \"SDImageAPNGCoder.h\"\n#import \"SDImageAWebPCoder.h\"\n#import \"SDImageCache.h\"\n#import \"SDImageCacheConfig.h\"\n#import \"SDImageCacheDefine.h\"\n#import \"SDImageCachesManager.h\"\n#import \"SDImageCoder.h\"\n#import \"SDImageCoderHelper.h\"\n#import \"SDImageCodersManager.h\"\n#import \"SDImageFrame.h\"\n#import \"SDImageGIFCoder.h\"\n#import \"SDImageGraphics.h\"\n#import \"SDImageHEICCoder.h\"\n#import \"SDImageIOAnimatedCoder.h\"\n#import \"SDImageIOCoder.h\"\n#import \"SDImageLoader.h\"\n#import \"SDImageLoadersManager.h\"\n#import \"SDImageTransformer.h\"\n#import \"SDMemoryCache.h\"\n#import \"SDWebImageCacheKeyFilter.h\"\n#import \"SDWebImageCacheSerializer.h\"\n#import \"SDWebImageCompat.h\"\n#import \"SDWebImageDefine.h\"\n#import \"SDWebImageDownloader.h\"\n#import \"SDWebImageDownloaderConfig.h\"\n#import \"SDWebImageDownloaderDecryptor.h\"\n#import \"SDWebImageDownloaderOperation.h\"\n#import \"SDWebImageDownloaderRequestModifier.h\"\n#import \"SDWebImageDownloaderResponseModifier.h\"\n#import \"SDWebImageError.h\"\n#import \"SDWebImageIndicator.h\"\n#import \"SDWebImageManager.h\"\n#import \"SDWebImageOperation.h\"\n#import \"SDWebImageOptionsProcessor.h\"\n#import \"SDWebImagePrefetcher.h\"\n#import \"SDWebImageTransition.h\"\n#import \"UIButton+WebCache.h\"\n#import \"UIImage+ExtendedCacheData.h\"\n#import \"UIImage+ForceDecode.h\"\n#import \"UIImage+GIF.h\"\n#import \"UIImage+MemoryCacheCost.h\"\n#import \"UIImage+Metadata.h\"\n#import \"UIImage+MultiFormat.h\"\n#import \"UIImage+Transform.h\"\n#import \"UIImageView+HighlightedWebCache.h\"\n#import \"UIImageView+WebCache.h\"\n#import \"UIView+WebCache.h\"\n#import \"UIView+WebCacheOperation.h\"\n#import \"SDWebImage.h\"\n\nFOUNDATION_EXPORT double SDWebImageVersionNumber;\nFOUNDATION_EXPORT const unsigned char SDWebImageVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage\nDERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = NO\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -framework \"ImageIO\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nSUPPORTS_MACCATALYST = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage.modulemap",
    "content": "framework module SDWebImage {\n  umbrella header \"SDWebImage-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage\nDERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = NO\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nOTHER_LDFLAGS = $(inherited) -framework \"ImageIO\"\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nSUPPORTS_MACCATALYST = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb-Info.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  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>2.30908.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_nanopb : NSObject\n@end\n@implementation PodsDummy_nanopb\n@end\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb-prefix.pch",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n#import \"pb.h\"\n#import \"pb_common.h\"\n#import \"pb_decode.h\"\n#import \"pb_encode.h\"\n#import \"pb.h\"\n#import \"pb_decode.h\"\n#import \"pb_common.h\"\n#import \"pb.h\"\n#import \"pb_encode.h\"\n#import \"pb_common.h\"\n\nFOUNDATION_EXPORT double nanopbVersionNumber;\nFOUNDATION_EXPORT const unsigned char nanopbVersionString[];\n\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/nanopb\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/nanopb\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb.modulemap",
    "content": "framework module nanopb {\n  umbrella header \"nanopb-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "Pods/Target Support Files/nanopb/nanopb.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nCONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/nanopb\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_ROOT = ${SRCROOT}\nPODS_TARGET_SRCROOT = ${PODS_ROOT}/nanopb\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nPRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\nSKIP_INSTALL = YES\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "Pods/nanopb/LICENSE.txt",
    "content": "Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi>\n\nThis software is provided 'as-is', without any express or \nimplied warranty. In no event will the authors be held liable \nfor any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any \npurpose, including commercial applications, and to alter it and \nredistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you \n   must not claim that you wrote the original software. If you use \n   this software in a product, an acknowledgment in the product \n   documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and \n   must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source \n   distribution.\n"
  },
  {
    "path": "Pods/nanopb/README.md",
    "content": "Nanopb - Protocol Buffers for Embedded Systems\n==============================================\n\n[![Build Status](https://travis-ci.org/nanopb/nanopb.svg?branch=master)](https://travis-ci.org/nanopb/nanopb)\n\nNanopb is a small code-size Protocol Buffers implementation in ansi C. It is\nespecially suitable for use in microcontrollers, but fits any memory\nrestricted system.\n\n* **Homepage:** https://jpa.kapsi.fi/nanopb/\n* **Documentation:** https://jpa.kapsi.fi/nanopb/docs/\n* **Downloads:** https://jpa.kapsi.fi/nanopb/download/\n* **Forum:** https://groups.google.com/forum/#!forum/nanopb\n\n\n\nUsing the nanopb library\n------------------------\nTo use the nanopb library, you need to do two things:\n\n1. Compile your .proto files for nanopb, using `protoc`.\n2. Include *pb_encode.c*, *pb_decode.c* and *pb_common.c* in your project.\n\nThe easiest way to get started is to study the project in \"examples/simple\".\nIt contains a Makefile, which should work directly under most Linux systems.\nHowever, for any other kind of build system, see the manual steps in\nREADME.txt in that folder.\n\n\n\nUsing the Protocol Buffers compiler (protoc)\n--------------------------------------------\nThe nanopb generator is implemented as a plugin for the Google's own `protoc`\ncompiler. This has the advantage that there is no need to reimplement the\nbasic parsing of .proto files. However, it does mean that you need the\nGoogle's protobuf library in order to run the generator.\n\nIf you have downloaded a binary package for nanopb (either Windows, Linux or\nMac OS X version), the `protoc` binary is included in the 'generator-bin'\nfolder. In this case, you are ready to go. Simply run this command:\n\n    generator-bin/protoc --nanopb_out=. myprotocol.proto\n\nHowever, if you are using a git checkout or a plain source distribution, you\nneed to provide your own version of `protoc` and the Google's protobuf library.\nOn Linux, the necessary packages are `protobuf-compiler` and `python-protobuf`.\nOn Windows, you can either build Google's protobuf library from source or use\none of the binary distributions of it. In either case, if you use a separate\n`protoc`, you need to manually give the path to nanopb generator:\n\n    protoc --plugin=protoc-gen-nanopb=nanopb/generator/protoc-gen-nanopb ...\n\n\n\nRunning the tests\n-----------------\nIf you want to perform further development of the nanopb core, or to verify\nits functionality using your compiler and platform, you'll want to run the\ntest suite. The build rules for the test suite are implemented using Scons,\nso you need to have that installed (ex: `sudo apt install scons` on Ubuntu). To run the tests:\n\n    cd tests\n    scons\n\nThis will show the progress of various test cases. If the output does not\nend in an error, the test cases were successful.\n\nNote: Mac OS X by default aliases 'clang' as 'gcc', while not actually\nsupporting the same command line options as gcc does. To run tests on\nMac OS X, use: \"scons CC=clang CXX=clang\". Same way can be used to run\ntests with different compilers on any platform.\n"
  },
  {
    "path": "Pods/nanopb/pb.h",
    "content": "/* Common parts of the nanopb library. Most of these are quite low-level\n * stuff. For the high-level interface, see pb_encode.h and pb_decode.h.\n */\n\n#ifndef PB_H_INCLUDED\n#define PB_H_INCLUDED\n\n/*****************************************************************\n * Nanopb compilation time options. You can change these here by *\n * uncommenting the lines, or on the compiler command line.      *\n *****************************************************************/\n\n/* Enable support for dynamically allocated fields */\n/* #define PB_ENABLE_MALLOC 1 */\n\n/* Define this if your CPU / compiler combination does not support\n * unaligned memory access to packed structures. */\n/* #define PB_NO_PACKED_STRUCTS 1 */\n\n/* Increase the number of required fields that are tracked.\n * A compiler warning will tell if you need this. */\n/* #define PB_MAX_REQUIRED_FIELDS 256 */\n\n/* Add support for tag numbers > 255 and fields larger than 255 bytes. */\n/* #define PB_FIELD_16BIT 1 */\n\n/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */\n/* #define PB_FIELD_32BIT 1 */\n\n/* Disable support for error messages in order to save some code space. */\n/* #define PB_NO_ERRMSG 1 */\n\n/* Disable support for custom streams (support only memory buffers). */\n/* #define PB_BUFFER_ONLY 1 */\n\n/* Switch back to the old-style callback function signature.\n * This was the default until nanopb-0.2.1. */\n/* #define PB_OLD_CALLBACK_STYLE */\n\n\n/* Don't encode scalar arrays as packed. This is only to be used when\n * the decoder on the receiving side cannot process packed scalar arrays.\n * Such example is older protobuf.js. */\n/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */\n\n/******************************************************************\n * You usually don't need to change anything below this line.     *\n * Feel free to look around and use the defined macros, though.   *\n ******************************************************************/\n\n\n/* Version of the nanopb library. Just in case you want to check it in\n * your own program. */\n#define NANOPB_VERSION nanopb-0.3.9.8\n\n/* Include all the system headers needed by nanopb. You will need the\n * definitions of the following:\n * - strlen, memcpy, memset functions\n * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t\n * - size_t\n * - bool\n *\n * If you don't have the standard header files, you can instead provide\n * a custom header that defines or includes all this. In that case,\n * define PB_SYSTEM_HEADER to the path of this file.\n */\n#ifdef PB_SYSTEM_HEADER\n#include PB_SYSTEM_HEADER\n#else\n#include <stdint.h>\n#include <stddef.h>\n#include <stdbool.h>\n#include <string.h>\n\n#ifdef PB_ENABLE_MALLOC\n#include <stdlib.h>\n#endif\n#endif\n\n/* Macro for defining packed structures (compiler dependent).\n * This just reduces memory requirements, but is not required.\n */\n#if defined(PB_NO_PACKED_STRUCTS)\n    /* Disable struct packing */\n#   define PB_PACKED_STRUCT_START\n#   define PB_PACKED_STRUCT_END\n#   define pb_packed\n#elif defined(__GNUC__) || defined(__clang__)\n    /* For GCC and clang */\n#   define PB_PACKED_STRUCT_START\n#   define PB_PACKED_STRUCT_END\n#   define pb_packed __attribute__((packed))\n#elif defined(__ICCARM__) || defined(__CC_ARM)\n    /* For IAR ARM and Keil MDK-ARM compilers */\n#   define PB_PACKED_STRUCT_START _Pragma(\"pack(push, 1)\")\n#   define PB_PACKED_STRUCT_END _Pragma(\"pack(pop)\")\n#   define pb_packed\n#elif defined(_MSC_VER) && (_MSC_VER >= 1500)\n    /* For Microsoft Visual C++ */\n#   define PB_PACKED_STRUCT_START __pragma(pack(push, 1))\n#   define PB_PACKED_STRUCT_END __pragma(pack(pop))\n#   define pb_packed\n#else\n    /* Unknown compiler */\n#   define PB_PACKED_STRUCT_START\n#   define PB_PACKED_STRUCT_END\n#   define pb_packed\n#endif\n\n/* Handly macro for suppressing unreferenced-parameter compiler warnings. */\n#ifndef PB_UNUSED\n#define PB_UNUSED(x) (void)(x)\n#endif\n\n/* Compile-time assertion, used for checking compatible compilation options.\n * If this does not work properly on your compiler, use\n * #define PB_NO_STATIC_ASSERT to disable it.\n *\n * But before doing that, check carefully the error message / place where it\n * comes from to see if the error has a real cause. Unfortunately the error\n * message is not always very clear to read, but you can see the reason better\n * in the place where the PB_STATIC_ASSERT macro was called.\n */\n#ifndef PB_NO_STATIC_ASSERT\n#ifndef PB_STATIC_ASSERT\n#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];\n#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)\n#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER\n#endif\n#else\n#define PB_STATIC_ASSERT(COND,MSG)\n#endif\n\n/* Number of required fields to keep track of. */\n#ifndef PB_MAX_REQUIRED_FIELDS\n#define PB_MAX_REQUIRED_FIELDS 64\n#endif\n\n#if PB_MAX_REQUIRED_FIELDS < 64\n#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64).\n#endif\n\n/* List of possible field types. These are used in the autogenerated code.\n * Least-significant 4 bits tell the scalar type\n * Most-significant 4 bits specify repeated/required/packed etc.\n */\n\ntypedef uint_least8_t pb_type_t;\n\n/**** Field data types ****/\n\n/* Numeric types */\n#define PB_LTYPE_BOOL    0x00 /* bool */\n#define PB_LTYPE_VARINT  0x01 /* int32, int64, enum, bool */\n#define PB_LTYPE_UVARINT 0x02 /* uint32, uint64 */\n#define PB_LTYPE_SVARINT 0x03 /* sint32, sint64 */\n#define PB_LTYPE_FIXED32 0x04 /* fixed32, sfixed32, float */\n#define PB_LTYPE_FIXED64 0x05 /* fixed64, sfixed64, double */\n\n/* Marker for last packable field type. */\n#define PB_LTYPE_LAST_PACKABLE 0x05\n\n/* Byte array with pre-allocated buffer.\n * data_size is the length of the allocated PB_BYTES_ARRAY structure. */\n#define PB_LTYPE_BYTES 0x06\n\n/* String with pre-allocated buffer.\n * data_size is the maximum length. */\n#define PB_LTYPE_STRING 0x07\n\n/* Submessage\n * submsg_fields is pointer to field descriptions */\n#define PB_LTYPE_SUBMESSAGE 0x08\n\n/* Extension pseudo-field\n * The field contains a pointer to pb_extension_t */\n#define PB_LTYPE_EXTENSION 0x09\n\n/* Byte array with inline, pre-allocated byffer.\n * data_size is the length of the inline, allocated buffer.\n * This differs from PB_LTYPE_BYTES by defining the element as\n * pb_byte_t[data_size] rather than pb_bytes_array_t. */\n#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0A\n\n/* Number of declared LTYPES */\n#define PB_LTYPES_COUNT 0x0B\n#define PB_LTYPE_MASK 0x0F\n\n/**** Field repetition rules ****/\n\n#define PB_HTYPE_REQUIRED 0x00\n#define PB_HTYPE_OPTIONAL 0x10\n#define PB_HTYPE_REPEATED 0x20\n#define PB_HTYPE_ONEOF    0x30\n#define PB_HTYPE_MASK     0x30\n\n/**** Field allocation types ****/\n \n#define PB_ATYPE_STATIC   0x00\n#define PB_ATYPE_POINTER  0x80\n#define PB_ATYPE_CALLBACK 0x40\n#define PB_ATYPE_MASK     0xC0\n\n#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK)\n#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK)\n#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK)\n\n/* Data type used for storing sizes of struct fields\n * and array counts.\n */\n#if defined(PB_FIELD_32BIT)\n    typedef uint32_t pb_size_t;\n    typedef int32_t pb_ssize_t;\n#elif defined(PB_FIELD_16BIT)\n    typedef uint_least16_t pb_size_t;\n    typedef int_least16_t pb_ssize_t;\n#else\n    typedef uint_least8_t pb_size_t;\n    typedef int_least8_t pb_ssize_t;\n#endif\n#define PB_SIZE_MAX ((pb_size_t)-1)\n\n/* Data type for storing encoded data and other byte streams.\n * This typedef exists to support platforms where uint8_t does not exist.\n * You can regard it as equivalent on uint8_t on other platforms.\n */\ntypedef uint_least8_t pb_byte_t;\n\n/* This structure is used in auto-generated constants\n * to specify struct fields.\n * You can change field sizes if you need structures\n * larger than 256 bytes or field tags larger than 256.\n * The compiler should complain if your .proto has such\n * structures. Fix that by defining PB_FIELD_16BIT or\n * PB_FIELD_32BIT.\n */\nPB_PACKED_STRUCT_START\ntypedef struct pb_field_s pb_field_t;\nstruct pb_field_s {\n    pb_size_t tag;\n    pb_type_t type;\n    pb_size_t data_offset; /* Offset of field data, relative to previous field. */\n    pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */\n    pb_size_t data_size; /* Data size in bytes for a single item */\n    pb_size_t array_size; /* Maximum number of entries in array */\n    \n    /* Field definitions for submessage\n     * OR default value for all other non-array, non-callback types\n     * If null, then field will zeroed. */\n    const void *ptr;\n} pb_packed;\nPB_PACKED_STRUCT_END\n\n/* Make sure that the standard integer types are of the expected sizes.\n * Otherwise fixed32/fixed64 fields can break.\n *\n * If you get errors here, it probably means that your stdint.h is not\n * correct for your platform.\n */\n#ifndef PB_WITHOUT_64BIT\nPB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE)\nPB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE)\n#endif\n\n/* This structure is used for 'bytes' arrays.\n * It has the number of bytes in the beginning, and after that an array.\n * Note that actual structs used will have a different length of bytes array.\n */\n#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; }\n#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))\n\nstruct pb_bytes_array_s {\n    pb_size_t size;\n    pb_byte_t bytes[1];\n};\ntypedef struct pb_bytes_array_s pb_bytes_array_t;\n\n/* This structure is used for giving the callback function.\n * It is stored in the message structure and filled in by the method that\n * calls pb_decode.\n *\n * The decoding callback will be given a limited-length stream\n * If the wire type was string, the length is the length of the string.\n * If the wire type was a varint/fixed32/fixed64, the length is the length\n * of the actual value.\n * The function may be called multiple times (especially for repeated types,\n * but also otherwise if the message happens to contain the field multiple\n * times.)\n *\n * The encoding callback will receive the actual output stream.\n * It should write all the data in one call, including the field tag and\n * wire type. It can write multiple fields.\n *\n * The callback can be null if you want to skip a field.\n */\ntypedef struct pb_istream_s pb_istream_t;\ntypedef struct pb_ostream_s pb_ostream_t;\ntypedef struct pb_callback_s pb_callback_t;\nstruct pb_callback_s {\n#ifdef PB_OLD_CALLBACK_STYLE\n    /* Deprecated since nanopb-0.2.1 */\n    union {\n        bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);\n        bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg);\n    } funcs;\n#else\n    /* New function signature, which allows modifying arg contents in callback. */\n    union {\n        bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg);\n        bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg);\n    } funcs;\n#endif    \n    \n    /* Free arg for use by callback */\n    void *arg;\n};\n\n/* Wire types. Library user needs these only in encoder callbacks. */\ntypedef enum {\n    PB_WT_VARINT = 0,\n    PB_WT_64BIT  = 1,\n    PB_WT_STRING = 2,\n    PB_WT_32BIT  = 5\n} pb_wire_type_t;\n\n/* Structure for defining the handling of unknown/extension fields.\n * Usually the pb_extension_type_t structure is automatically generated,\n * while the pb_extension_t structure is created by the user. However,\n * if you want to catch all unknown fields, you can also create a custom\n * pb_extension_type_t with your own callback.\n */\ntypedef struct pb_extension_type_s pb_extension_type_t;\ntypedef struct pb_extension_s pb_extension_t;\nstruct pb_extension_type_s {\n    /* Called for each unknown field in the message.\n     * If you handle the field, read off all of its data and return true.\n     * If you do not handle the field, do not read anything and return true.\n     * If you run into an error, return false.\n     * Set to NULL for default handler.\n     */\n    bool (*decode)(pb_istream_t *stream, pb_extension_t *extension,\n                   uint32_t tag, pb_wire_type_t wire_type);\n    \n    /* Called once after all regular fields have been encoded.\n     * If you have something to write, do so and return true.\n     * If you do not have anything to write, just return true.\n     * If you run into an error, return false.\n     * Set to NULL for default handler.\n     */\n    bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension);\n    \n    /* Free field for use by the callback. */\n    const void *arg;\n};\n\nstruct pb_extension_s {\n    /* Type describing the extension field. Usually you'll initialize\n     * this to a pointer to the automatically generated structure. */\n    const pb_extension_type_t *type;\n    \n    /* Destination for the decoded data. This must match the datatype\n     * of the extension field. */\n    void *dest;\n    \n    /* Pointer to the next extension handler, or NULL.\n     * If this extension does not match a field, the next handler is\n     * automatically called. */\n    pb_extension_t *next;\n\n    /* The decoder sets this to true if the extension was found.\n     * Ignored for encoding. */\n    bool found;\n};\n\n/* Memory allocation functions to use. You can define pb_realloc and\n * pb_free to custom functions if you want. */\n#ifdef PB_ENABLE_MALLOC\n#   ifndef pb_realloc\n#       define pb_realloc(ptr, size) realloc(ptr, size)\n#   endif\n#   ifndef pb_free\n#       define pb_free(ptr) free(ptr)\n#   endif\n#endif\n\n/* This is used to inform about need to regenerate .pb.h/.pb.c files. */\n#define PB_PROTO_HEADER_VERSION 30\n\n/* These macros are used to declare pb_field_t's in the constant array. */\n/* Size of a structure member, in bytes. */\n#define pb_membersize(st, m) (sizeof ((st*)0)->m)\n/* Number of entries in an array. */\n#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))\n/* Delta from start of one member to the start of another member. */\n#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))\n/* Marks the end of the field list */\n#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0}\n\n/* Macros for filling in the data_offset field */\n/* data_offset for first field in a message */\n#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))\n/* data_offset for subsequent fields */\n#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))\n/* data offset for subsequent fields inside an union (oneof) */\n#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX)\n/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */\n#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \\\n                                  ? PB_DATAOFFSET_FIRST(st, m1, m2) \\\n                                  : PB_DATAOFFSET_OTHER(st, m1, m2))\n\n/* Required fields are the simplest. They just have delta (padding) from\n * previous field end, and the size of the field. Pointer is used for\n * submessages and default values.\n */\n#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n\n/* Optional fields add the delta to the has_ variable. */\n#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, \\\n    pb_delta(st, has_ ## m, m), \\\n    pb_membersize(st, m), 0, ptr}\n\n#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n\n/* Repeated fields have a _count field and also the maximum number of entries. */\n#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \\\n    fd, \\\n    pb_delta(st, m ## _count, m), \\\n    pb_membersize(st, m[0]), \\\n    pb_arraysize(st, m), ptr}\n\n/* Allocated fields carry the size of the actual data, not the pointer */\n#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \\\n    fd, 0, pb_membersize(st, m[0]), 0, ptr}\n\n/* Optional fields don't need a has_ variable, as information would be redundant */\n#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, 0, pb_membersize(st, m[0]), 0, ptr}\n\n/* Same as optional fields*/\n#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, 0, pb_membersize(st, m[0]), 0, ptr}\n\n/* Repeated fields have a _count field and a pointer to array of pointers */\n#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \\\n    fd, pb_delta(st, m ## _count, m), \\\n    pb_membersize(st, m[0]), 0, ptr}\n\n/* Callbacks are much like required fields except with special datatype. */\n#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n\n#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n\n#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n    \n#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \\\n    fd, 0, pb_membersize(st, m), 0, ptr}\n\n/* Optional extensions don't have the has_ field, as that would be redundant.\n * Furthermore, the combination of OPTIONAL without has_ field is used\n * for indicating proto3 style fields. Extensions exist in proto2 mode only,\n * so they should be encoded according to proto2 rules. To avoid the conflict,\n * extensions are marked as REQUIRED instead.\n */\n#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \\\n    0, \\\n    0, \\\n    pb_membersize(st, m), 0, ptr}\n\n#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \\\n    PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr)\n\n#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \\\n    PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr)\n\n/* The mapping from protobuf types to LTYPEs is done using these macros. */\n#define PB_LTYPE_MAP_BOOL               PB_LTYPE_BOOL\n#define PB_LTYPE_MAP_BYTES              PB_LTYPE_BYTES\n#define PB_LTYPE_MAP_DOUBLE             PB_LTYPE_FIXED64\n#define PB_LTYPE_MAP_ENUM               PB_LTYPE_VARINT\n#define PB_LTYPE_MAP_UENUM              PB_LTYPE_UVARINT\n#define PB_LTYPE_MAP_FIXED32            PB_LTYPE_FIXED32\n#define PB_LTYPE_MAP_FIXED64            PB_LTYPE_FIXED64\n#define PB_LTYPE_MAP_FLOAT              PB_LTYPE_FIXED32\n#define PB_LTYPE_MAP_INT32              PB_LTYPE_VARINT\n#define PB_LTYPE_MAP_INT64              PB_LTYPE_VARINT\n#define PB_LTYPE_MAP_MESSAGE            PB_LTYPE_SUBMESSAGE\n#define PB_LTYPE_MAP_SFIXED32           PB_LTYPE_FIXED32\n#define PB_LTYPE_MAP_SFIXED64           PB_LTYPE_FIXED64\n#define PB_LTYPE_MAP_SINT32             PB_LTYPE_SVARINT\n#define PB_LTYPE_MAP_SINT64             PB_LTYPE_SVARINT\n#define PB_LTYPE_MAP_STRING             PB_LTYPE_STRING\n#define PB_LTYPE_MAP_UINT32             PB_LTYPE_UVARINT\n#define PB_LTYPE_MAP_UINT64             PB_LTYPE_UVARINT\n#define PB_LTYPE_MAP_EXTENSION          PB_LTYPE_EXTENSION\n#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES\n\n/* This is the actual macro used in field descriptions.\n * It takes these arguments:\n * - Field tag number\n * - Field type:   BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64,\n *                 FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64\n *                 SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION\n * - Field rules:  REQUIRED, OPTIONAL or REPEATED\n * - Allocation:   STATIC, CALLBACK or POINTER\n * - Placement: FIRST or OTHER, depending on if this is the first field in structure.\n * - Message name\n * - Field name\n * - Previous field name (or field name again for first field)\n * - Pointer to default value or submsg fields.\n */\n\n#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \\\n        PB_ ## rules ## _ ## allocation(tag, message, field, \\\n        PB_DATAOFFSET_ ## placement(message, field, prevfield), \\\n        PB_LTYPE_MAP_ ## type, ptr)\n\n/* Field description for repeated static fixed count fields.*/\n#define PB_REPEATED_FIXED_COUNT(tag, type, placement, message, field, prevfield, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | PB_LTYPE_MAP_ ## type, \\\n    PB_DATAOFFSET_ ## placement(message, field, prevfield), \\\n    0, \\\n    pb_membersize(message, field[0]), \\\n    pb_arraysize(message, field), ptr}\n\n/* Field description for oneof fields. This requires taking into account the\n * union name also, that's why a separate set of macros is needed.\n */\n#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \\\n    fd, pb_delta(st, which_ ## u, u.m), \\\n    pb_membersize(st, u.m), 0, ptr}\n\n#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \\\n    fd, pb_delta(st, which_ ## u, u.m), \\\n    pb_membersize(st, u.m[0]), 0, ptr}\n\n#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \\\n        PB_ONEOF_ ## allocation(union_name, tag, message, field, \\\n        PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \\\n        PB_LTYPE_MAP_ ## type, ptr)\n\n#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \\\n    fd, pb_delta(st, which_ ## u, m), \\\n    pb_membersize(st, m), 0, ptr}\n\n#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \\\n    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \\\n    fd, pb_delta(st, which_ ## u, m), \\\n    pb_membersize(st, m[0]), 0, ptr}\n\n#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \\\n        PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \\\n        PB_DATAOFFSET_ ## placement(message, field, prevfield), \\\n        PB_LTYPE_MAP_ ## type, ptr)\n\n/* These macros are used for giving out error messages.\n * They are mostly a debugging aid; the main error information\n * is the true/false return value from functions.\n * Some code space can be saved by disabling the error\n * messages if not used.\n *\n * PB_SET_ERROR() sets the error message if none has been set yet.\n *                msg must be a constant string literal.\n * PB_GET_ERROR() always returns a pointer to a string.\n * PB_RETURN_ERROR() sets the error and returns false from current\n *                   function.\n */\n#ifdef PB_NO_ERRMSG\n#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream)\n#define PB_GET_ERROR(stream) \"(errmsg disabled)\"\n#else\n#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg))\n#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : \"(none)\")\n#endif\n\n#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false\n\n#endif\n"
  },
  {
    "path": "Pods/nanopb/pb_common.c",
    "content": "/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.\n *\n * 2014 Petteri Aimonen <jpa@kapsi.fi>\n */\n\n#include \"pb_common.h\"\n\nbool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct)\n{\n    iter->start = fields;\n    iter->pos = fields;\n    iter->required_field_index = 0;\n    iter->dest_struct = dest_struct;\n    iter->pData = (char*)dest_struct + iter->pos->data_offset;\n    iter->pSize = (char*)iter->pData + iter->pos->size_offset;\n    \n    return (iter->pos->tag != 0);\n}\n\nbool pb_field_iter_next(pb_field_iter_t *iter)\n{\n    const pb_field_t *prev_field = iter->pos;\n\n    if (prev_field->tag == 0)\n    {\n        /* Handle empty message types, where the first field is already the terminator.\n         * In other cases, the iter->pos never points to the terminator. */\n        return false;\n    }\n    \n    iter->pos++;\n    \n    if (iter->pos->tag == 0)\n    {\n        /* Wrapped back to beginning, reinitialize */\n        (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct);\n        return false;\n    }\n    else\n    {\n        /* Increment the pointers based on previous field size */\n        size_t prev_size = prev_field->data_size;\n    \n        if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF &&\n            PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF &&\n            iter->pos->data_offset == PB_SIZE_MAX)\n        {\n            /* Don't advance pointers inside unions */\n            return true;\n        }\n        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&\n                 PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)\n        {\n            /* In static arrays, the data_size tells the size of a single entry and\n             * array_size is the number of entries */\n            prev_size *= prev_field->array_size;\n        }\n        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER)\n        {\n            /* Pointer fields always have a constant size in the main structure.\n             * The data_size only applies to the dynamically allocated area. */\n            prev_size = sizeof(void*);\n        }\n\n        if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED)\n        {\n            /* Count the required fields, in order to check their presence in the\n             * decoder. */\n            iter->required_field_index++;\n        }\n    \n        iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;\n        iter->pSize = (char*)iter->pData + iter->pos->size_offset;\n        return true;\n    }\n}\n\nbool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)\n{\n    const pb_field_t *start = iter->pos;\n    \n    do {\n        if (iter->pos->tag == tag &&\n            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)\n        {\n            /* Found the wanted field */\n            return true;\n        }\n        \n        (void)pb_field_iter_next(iter);\n    } while (iter->pos != start);\n    \n    /* Searched all the way back to start, and found nothing. */\n    return false;\n}\n\n\n"
  },
  {
    "path": "Pods/nanopb/pb_common.h",
    "content": "/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c.\n * These functions are rarely needed by applications directly.\n */\n\n#ifndef PB_COMMON_H_INCLUDED\n#define PB_COMMON_H_INCLUDED\n\n#include \"pb.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Iterator for pb_field_t list */\nstruct pb_field_iter_s {\n    const pb_field_t *start;       /* Start of the pb_field_t array */\n    const pb_field_t *pos;         /* Current position of the iterator */\n    unsigned required_field_index; /* Zero-based index that counts only the required fields */\n    void *dest_struct;             /* Pointer to start of the structure */\n    void *pData;                   /* Pointer to current field value */\n    void *pSize;                   /* Pointer to count/has field */\n};\ntypedef struct pb_field_iter_s pb_field_iter_t;\n\n/* Initialize the field iterator structure to beginning.\n * Returns false if the message type is empty. */\nbool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct);\n\n/* Advance the iterator to the next field.\n * Returns false when the iterator wraps back to the first field. */\nbool pb_field_iter_next(pb_field_iter_t *iter);\n\n/* Advance the iterator until it points at a field with the given tag.\n * Returns false if no such field exists. */\nbool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag);\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n\n"
  },
  {
    "path": "Pods/nanopb/pb_decode.c",
    "content": "/* pb_decode.c -- decode a protobuf using minimal resources\n *\n * 2011 Petteri Aimonen <jpa@kapsi.fi>\n */\n\n/* Use the GCC warn_unused_result attribute to check that all return values\n * are propagated correctly. On other compilers and gcc before 3.4.0 just\n * ignore the annotation.\n */\n#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)\n    #define checkreturn\n#else\n    #define checkreturn __attribute__((warn_unused_result))\n#endif\n\n#include \"pb.h\"\n#include \"pb_decode.h\"\n#include \"pb_common.h\"\n\n/**************************************\n * Declarations internal to this file *\n **************************************/\n\ntypedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;\n\nstatic bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);\nstatic bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size);\nstatic bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);\nstatic bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);\nstatic bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);\nstatic void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension);\nstatic bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type);\nstatic bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter);\nstatic bool checkreturn find_extension_field(pb_field_iter_t *iter);\nstatic void pb_field_set_to_default(pb_field_iter_t *iter);\nstatic void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);\nstatic bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof);\nstatic bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);\nstatic bool checkreturn pb_skip_varint(pb_istream_t *stream);\nstatic bool checkreturn pb_skip_string(pb_istream_t *stream);\n\n#ifdef PB_ENABLE_MALLOC\nstatic bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size);\nstatic bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter);\nstatic void pb_release_single_field(const pb_field_iter_t *iter);\n#endif\n\n#ifdef PB_WITHOUT_64BIT\n#define pb_int64_t int32_t\n#define pb_uint64_t uint32_t\n#else\n#define pb_int64_t int64_t\n#define pb_uint64_t uint64_t\n#endif\n\n/* --- Function pointers to field decoders ---\n * Order in the array must match pb_action_t LTYPE numbering.\n */\nstatic const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {\n    &pb_dec_bool,\n    &pb_dec_varint,\n    &pb_dec_uvarint,\n    &pb_dec_svarint,\n    &pb_dec_fixed32,\n    &pb_dec_fixed64,\n    \n    &pb_dec_bytes,\n    &pb_dec_string,\n    &pb_dec_submessage,\n    NULL, /* extensions */\n    &pb_dec_fixed_length_bytes\n};\n\n/*******************************\n * pb_istream_t implementation *\n *******************************/\n\nstatic bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)\n{\n    size_t i;\n    const pb_byte_t *source = (const pb_byte_t*)stream->state;\n    stream->state = (pb_byte_t*)stream->state + count;\n    \n    if (buf != NULL)\n    {\n        for (i = 0; i < count; i++)\n            buf[i] = source[i];\n    }\n    \n    return true;\n}\n\nbool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)\n{\n    if (count == 0)\n        return true;\n\n#ifndef PB_BUFFER_ONLY\n\tif (buf == NULL && stream->callback != buf_read)\n\t{\n\t\t/* Skip input bytes */\n\t\tpb_byte_t tmp[16];\n\t\twhile (count > 16)\n\t\t{\n\t\t\tif (!pb_read(stream, tmp, 16))\n\t\t\t\treturn false;\n\t\t\t\n\t\t\tcount -= 16;\n\t\t}\n\t\t\n\t\treturn pb_read(stream, tmp, count);\n\t}\n#endif\n\n    if (stream->bytes_left < count)\n        PB_RETURN_ERROR(stream, \"end-of-stream\");\n    \n#ifndef PB_BUFFER_ONLY\n    if (!stream->callback(stream, buf, count))\n        PB_RETURN_ERROR(stream, \"io error\");\n#else\n    if (!buf_read(stream, buf, count))\n        return false;\n#endif\n    \n    stream->bytes_left -= count;\n    return true;\n}\n\n/* Read a single byte from input stream. buf may not be NULL.\n * This is an optimization for the varint decoding. */\nstatic bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf)\n{\n    if (stream->bytes_left == 0)\n        PB_RETURN_ERROR(stream, \"end-of-stream\");\n\n#ifndef PB_BUFFER_ONLY\n    if (!stream->callback(stream, buf, 1))\n        PB_RETURN_ERROR(stream, \"io error\");\n#else\n    *buf = *(const pb_byte_t*)stream->state;\n    stream->state = (pb_byte_t*)stream->state + 1;\n#endif\n\n    stream->bytes_left--;\n    \n    return true;    \n}\n\npb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize)\n{\n    pb_istream_t stream;\n    /* Cast away the const from buf without a compiler error.  We are\n     * careful to use it only in a const manner in the callbacks.\n     */\n    union {\n        void *state;\n        const void *c_state;\n    } state;\n#ifdef PB_BUFFER_ONLY\n    stream.callback = NULL;\n#else\n    stream.callback = &buf_read;\n#endif\n    state.c_state = buf;\n    stream.state = state.state;\n    stream.bytes_left = bufsize;\n#ifndef PB_NO_ERRMSG\n    stream.errmsg = NULL;\n#endif\n    return stream;\n}\n\n/********************\n * Helper functions *\n ********************/\n\nstatic bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof)\n{\n    pb_byte_t byte;\n    uint32_t result;\n    \n    if (!pb_readbyte(stream, &byte))\n    {\n        if (stream->bytes_left == 0)\n        {\n            if (eof)\n            {\n                *eof = true;\n            }\n        }\n\n        return false;\n    }\n    \n    if ((byte & 0x80) == 0)\n    {\n        /* Quick case, 1 byte value */\n        result = byte;\n    }\n    else\n    {\n        /* Multibyte case */\n        uint_fast8_t bitpos = 7;\n        result = byte & 0x7F;\n        \n        do\n        {\n            if (!pb_readbyte(stream, &byte))\n                return false;\n            \n            if (bitpos >= 32)\n            {\n                /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */\n                uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01;\n                \n                if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension))\n                {\n                    PB_RETURN_ERROR(stream, \"varint overflow\");\n                }\n            }\n            else\n            {\n                result |= (uint32_t)(byte & 0x7F) << bitpos;\n            }\n            bitpos = (uint_fast8_t)(bitpos + 7);\n        } while (byte & 0x80);\n        \n        if (bitpos == 35 && (byte & 0x70) != 0)\n        {\n            /* The last byte was at bitpos=28, so only bottom 4 bits fit. */\n            PB_RETURN_ERROR(stream, \"varint overflow\");\n        }\n   }\n   \n   *dest = result;\n   return true;\n}\n\nbool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)\n{\n    return pb_decode_varint32_eof(stream, dest, NULL);\n}\n\n#ifndef PB_WITHOUT_64BIT\nbool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)\n{\n    pb_byte_t byte;\n    uint_fast8_t bitpos = 0;\n    uint64_t result = 0;\n    \n    do\n    {\n        if (bitpos >= 64)\n            PB_RETURN_ERROR(stream, \"varint overflow\");\n        \n        if (!pb_readbyte(stream, &byte))\n            return false;\n\n        result |= (uint64_t)(byte & 0x7F) << bitpos;\n        bitpos = (uint_fast8_t)(bitpos + 7);\n    } while (byte & 0x80);\n    \n    *dest = result;\n    return true;\n}\n#endif\n\nbool checkreturn pb_skip_varint(pb_istream_t *stream)\n{\n    pb_byte_t byte;\n    do\n    {\n        if (!pb_read(stream, &byte, 1))\n            return false;\n    } while (byte & 0x80);\n    return true;\n}\n\nbool checkreturn pb_skip_string(pb_istream_t *stream)\n{\n    uint32_t length;\n    if (!pb_decode_varint32(stream, &length))\n        return false;\n    \n    return pb_read(stream, NULL, length);\n}\n\nbool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)\n{\n    uint32_t temp;\n    *eof = false;\n    *wire_type = (pb_wire_type_t) 0;\n    *tag = 0;\n    \n    if (!pb_decode_varint32_eof(stream, &temp, eof))\n    {\n        return false;\n    }\n    \n    if (temp == 0)\n    {\n        *eof = true; /* Special feature: allow 0-terminated messages. */\n        return false;\n    }\n    \n    *tag = temp >> 3;\n    *wire_type = (pb_wire_type_t)(temp & 7);\n    return true;\n}\n\nbool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)\n{\n    switch (wire_type)\n    {\n        case PB_WT_VARINT: return pb_skip_varint(stream);\n        case PB_WT_64BIT: return pb_read(stream, NULL, 8);\n        case PB_WT_STRING: return pb_skip_string(stream);\n        case PB_WT_32BIT: return pb_read(stream, NULL, 4);\n        default: PB_RETURN_ERROR(stream, \"invalid wire_type\");\n    }\n}\n\n/* Read a raw value to buffer, for the purpose of passing it to callback as\n * a substream. Size is maximum size on call, and actual size on return.\n */\nstatic bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size)\n{\n    size_t max_size = *size;\n    switch (wire_type)\n    {\n        case PB_WT_VARINT:\n            *size = 0;\n            do\n            {\n                (*size)++;\n                if (*size > max_size) return false;\n                if (!pb_read(stream, buf, 1)) return false;\n            } while (*buf++ & 0x80);\n            return true;\n            \n        case PB_WT_64BIT:\n            *size = 8;\n            return pb_read(stream, buf, 8);\n        \n        case PB_WT_32BIT:\n            *size = 4;\n            return pb_read(stream, buf, 4);\n        \n        case PB_WT_STRING:\n            /* Calling read_raw_value with a PB_WT_STRING is an error.\n             * Explicitly handle this case and fallthrough to default to avoid\n             * compiler warnings.\n             */\n\n        default: PB_RETURN_ERROR(stream, \"invalid wire_type\");\n    }\n}\n\n/* Decode string length from stream and return a substream with limited length.\n * Remember to close the substream using pb_close_string_substream().\n */\nbool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)\n{\n    uint32_t size;\n    if (!pb_decode_varint32(stream, &size))\n        return false;\n    \n    *substream = *stream;\n    if (substream->bytes_left < size)\n        PB_RETURN_ERROR(stream, \"parent stream too short\");\n    \n    substream->bytes_left = size;\n    stream->bytes_left -= size;\n    return true;\n}\n\nbool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)\n{\n    if (substream->bytes_left) {\n        if (!pb_read(substream, NULL, substream->bytes_left))\n            return false;\n    }\n\n    stream->state = substream->state;\n\n#ifndef PB_NO_ERRMSG\n    stream->errmsg = substream->errmsg;\n#endif\n    return true;\n}\n\n/*************************\n * Decode a single field *\n *************************/\n\nstatic bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)\n{\n    pb_type_t type;\n    pb_decoder_t func;\n    \n    type = iter->pos->type;\n    func = PB_DECODERS[PB_LTYPE(type)];\n\n    switch (PB_HTYPE(type))\n    {\n        case PB_HTYPE_REQUIRED:\n            return func(stream, iter->pos, iter->pData);\n            \n        case PB_HTYPE_OPTIONAL:\n            if (iter->pSize != iter->pData)\n                *(bool*)iter->pSize = true;\n            return func(stream, iter->pos, iter->pData);\n    \n        case PB_HTYPE_REPEATED:\n            if (wire_type == PB_WT_STRING\n                && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE)\n            {\n                /* Packed array */\n                bool status = true;\n                pb_size_t *size = (pb_size_t*)iter->pSize;\n\n                pb_istream_t substream;\n                if (!pb_make_string_substream(stream, &substream))\n                    return false;\n\n                while (substream.bytes_left > 0 && *size < iter->pos->array_size)\n                {\n                    void *pItem = (char*)iter->pData + iter->pos->data_size * (*size);\n                    if (!func(&substream, iter->pos, pItem))\n                    {\n                        status = false;\n                        break;\n                    }\n                    (*size)++;\n                }\n\n                if (substream.bytes_left != 0)\n                    PB_RETURN_ERROR(stream, \"array overflow\");\n                if (!pb_close_string_substream(stream, &substream))\n                    return false;\n\n                return status;\n            }\n            else\n            {\n                /* Repeated field */\n                pb_size_t *size = (pb_size_t*)iter->pSize;\n                char *pItem = (char*)iter->pData + iter->pos->data_size * (*size);\n\n                if ((*size)++ >= iter->pos->array_size)\n                    PB_RETURN_ERROR(stream, \"array overflow\");\n\n                return func(stream, iter->pos, pItem);\n            }\n\n        case PB_HTYPE_ONEOF:\n            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE &&\n                *(pb_size_t*)iter->pSize != iter->pos->tag)\n            {\n                /* We memset to zero so that any callbacks are set to NULL.\n                 * This is because the callbacks might otherwise have values\n                 * from some other union field. */\n                memset(iter->pData, 0, iter->pos->data_size);\n                pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData);\n            }\n            *(pb_size_t*)iter->pSize = iter->pos->tag;\n\n            return func(stream, iter->pos, iter->pData);\n\n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n}\n\n#ifdef PB_ENABLE_MALLOC\n/* Allocate storage for the field and store the pointer at iter->pData.\n * array_size is the number of entries to reserve in an array.\n * Zero size is not allowed, use pb_free() for releasing.\n */\nstatic bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size)\n{    \n    void *ptr = *(void**)pData;\n    \n    if (data_size == 0 || array_size == 0)\n        PB_RETURN_ERROR(stream, \"invalid size\");\n    \n#ifdef __AVR__\n    /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284\n     * Realloc to size of 1 byte can cause corruption of the malloc structures.\n     */\n    if (data_size == 1 && array_size == 1)\n    {\n        data_size = 2;\n    }\n#endif\n\n    /* Check for multiplication overflows.\n     * This code avoids the costly division if the sizes are small enough.\n     * Multiplication is safe as long as only half of bits are set\n     * in either multiplicand.\n     */\n    {\n        const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4);\n        if (data_size >= check_limit || array_size >= check_limit)\n        {\n            const size_t size_max = (size_t)-1;\n            if (size_max / array_size < data_size)\n            {\n                PB_RETURN_ERROR(stream, \"size too large\");\n            }\n        }\n    }\n    \n    /* Allocate new or expand previous allocation */\n    /* Note: on failure the old pointer will remain in the structure,\n     * the message must be freed by caller also on error return. */\n    ptr = pb_realloc(ptr, array_size * data_size);\n    if (ptr == NULL)\n        PB_RETURN_ERROR(stream, \"realloc failed\");\n    \n    *(void**)pData = ptr;\n    return true;\n}\n\n/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */\nstatic void initialize_pointer_field(void *pItem, pb_field_iter_t *iter)\n{\n    if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING ||\n        PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES)\n    {\n        *(void**)pItem = NULL;\n    }\n    else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE)\n    {\n        /* We memset to zero so that any callbacks are set to NULL.\n         * Then set any default values. */\n        memset(pItem, 0, iter->pos->data_size);\n        pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem);\n    }\n}\n#endif\n\nstatic bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)\n{\n#ifndef PB_ENABLE_MALLOC\n    PB_UNUSED(wire_type);\n    PB_UNUSED(iter);\n    PB_RETURN_ERROR(stream, \"no malloc support\");\n#else\n    pb_type_t type;\n    pb_decoder_t func;\n    \n    type = iter->pos->type;\n    func = PB_DECODERS[PB_LTYPE(type)];\n    \n    switch (PB_HTYPE(type))\n    {\n        case PB_HTYPE_REQUIRED:\n        case PB_HTYPE_OPTIONAL:\n        case PB_HTYPE_ONEOF:\n            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE &&\n                *(void**)iter->pData != NULL)\n            {\n                /* Duplicate field, have to release the old allocation first. */\n                pb_release_single_field(iter);\n            }\n        \n            if (PB_HTYPE(type) == PB_HTYPE_ONEOF)\n            {\n                *(pb_size_t*)iter->pSize = iter->pos->tag;\n            }\n\n            if (PB_LTYPE(type) == PB_LTYPE_STRING ||\n                PB_LTYPE(type) == PB_LTYPE_BYTES)\n            {\n                return func(stream, iter->pos, iter->pData);\n            }\n            else\n            {\n                if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1))\n                    return false;\n                \n                initialize_pointer_field(*(void**)iter->pData, iter);\n                return func(stream, iter->pos, *(void**)iter->pData);\n            }\n    \n        case PB_HTYPE_REPEATED:\n            if (wire_type == PB_WT_STRING\n                && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE)\n            {\n                /* Packed array, multiple items come in at once. */\n                bool status = true;\n                pb_size_t *size = (pb_size_t*)iter->pSize;\n                size_t allocated_size = *size;\n                void *pItem;\n                pb_istream_t substream;\n                \n                if (!pb_make_string_substream(stream, &substream))\n                    return false;\n                \n                while (substream.bytes_left)\n                {\n                    if (*size == PB_SIZE_MAX)\n                    {\n#ifndef PB_NO_ERRMSG\n                        stream->errmsg = \"too many array entries\";\n#endif\n                        status = false;\n                        break;\n                    }\n\n                    if ((size_t)*size + 1 > allocated_size)\n                    {\n                        /* Allocate more storage. This tries to guess the\n                         * number of remaining entries. Round the division\n                         * upwards. */\n                        size_t remain = (substream.bytes_left - 1) / iter->pos->data_size + 1;\n                        if (remain < PB_SIZE_MAX - allocated_size)\n                            allocated_size += remain;\n                        else\n                            allocated_size += 1;\n                        \n                        if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size))\n                        {\n                            status = false;\n                            break;\n                        }\n                    }\n\n                    /* Decode the array entry */\n                    pItem = *(char**)iter->pData + iter->pos->data_size * (*size);\n                    initialize_pointer_field(pItem, iter);\n                    if (!func(&substream, iter->pos, pItem))\n                    {\n                        status = false;\n                        break;\n                    }\n                    \n                    (*size)++;\n                }\n                if (!pb_close_string_substream(stream, &substream))\n                    return false;\n                \n                return status;\n            }\n            else\n            {\n                /* Normal repeated field, i.e. only one item at a time. */\n                pb_size_t *size = (pb_size_t*)iter->pSize;\n                void *pItem;\n                \n                if (*size == PB_SIZE_MAX)\n                    PB_RETURN_ERROR(stream, \"too many array entries\");\n                \n                if (!allocate_field(stream, iter->pData, iter->pos->data_size, (size_t)(*size + 1)))\n                    return false;\n            \n                pItem = *(char**)iter->pData + iter->pos->data_size * (*size);\n                (*size)++;\n                initialize_pointer_field(pItem, iter);\n                return func(stream, iter->pos, pItem);\n            }\n\n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n#endif\n}\n\nstatic bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)\n{\n    pb_callback_t *pCallback = (pb_callback_t*)iter->pData;\n#ifdef PB_OLD_CALLBACK_STYLE\n    void *arg;\n#else\n    void **arg;\n#endif\n    \n    if (pCallback == NULL || pCallback->funcs.decode == NULL)\n        return pb_skip_field(stream, wire_type);\n\n#ifdef PB_OLD_CALLBACK_STYLE\n    arg = pCallback->arg;\n#else\n    arg = &(pCallback->arg);\n#endif\n    \n    if (wire_type == PB_WT_STRING)\n    {\n        pb_istream_t substream;\n        \n        if (!pb_make_string_substream(stream, &substream))\n            return false;\n        \n        do\n        {\n            if (!pCallback->funcs.decode(&substream, iter->pos, arg))\n                PB_RETURN_ERROR(stream, \"callback failed\");\n        } while (substream.bytes_left);\n        \n        if (!pb_close_string_substream(stream, &substream))\n            return false;\n\n        return true;\n    }\n    else\n    {\n        /* Copy the single scalar value to stack.\n         * This is required so that we can limit the stream length,\n         * which in turn allows to use same callback for packed and\n         * not-packed fields. */\n        pb_istream_t substream;\n        pb_byte_t buffer[10];\n        size_t size = sizeof(buffer);\n        \n        if (!read_raw_value(stream, wire_type, buffer, &size))\n            return false;\n        substream = pb_istream_from_buffer(buffer, size);\n        \n        return pCallback->funcs.decode(&substream, iter->pos, arg);\n    }\n}\n\nstatic bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)\n{\n#ifdef PB_ENABLE_MALLOC\n    /* When decoding an oneof field, check if there is old data that must be\n     * released first. */\n    if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF)\n    {\n        if (!pb_release_union_field(stream, iter))\n            return false;\n    }\n#endif\n\n    switch (PB_ATYPE(iter->pos->type))\n    {\n        case PB_ATYPE_STATIC:\n            return decode_static_field(stream, wire_type, iter);\n        \n        case PB_ATYPE_POINTER:\n            return decode_pointer_field(stream, wire_type, iter);\n        \n        case PB_ATYPE_CALLBACK:\n            return decode_callback_field(stream, wire_type, iter);\n        \n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n}\n\nstatic void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension)\n{\n    /* Fake a field iterator for the extension field.\n     * It is not actually safe to advance this iterator, but decode_field\n     * will not even try to. */\n    const pb_field_t *field = (const pb_field_t*)extension->type->arg;\n    (void)pb_field_iter_begin(iter, field, extension->dest);\n    iter->pData = extension->dest;\n    iter->pSize = &extension->found;\n    \n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n    {\n        /* For pointer extensions, the pointer is stored directly\n         * in the extension structure. This avoids having an extra\n         * indirection. */\n        iter->pData = &extension->dest;\n    }\n}\n\n/* Default handler for extension fields. Expects a pb_field_t structure\n * in extension->type->arg. */\nstatic bool checkreturn default_extension_decoder(pb_istream_t *stream,\n    pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type)\n{\n    const pb_field_t *field = (const pb_field_t*)extension->type->arg;\n    pb_field_iter_t iter;\n    \n    if (field->tag != tag)\n        return true;\n    \n    iter_from_extension(&iter, extension);\n    extension->found = true;\n    return decode_field(stream, wire_type, &iter);\n}\n\n/* Try to decode an unknown field as an extension field. Tries each extension\n * decoder in turn, until one of them handles the field or loop ends. */\nstatic bool checkreturn decode_extension(pb_istream_t *stream,\n    uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter)\n{\n    pb_extension_t *extension = *(pb_extension_t* const *)iter->pData;\n    size_t pos = stream->bytes_left;\n    \n    while (extension != NULL && pos == stream->bytes_left)\n    {\n        bool status;\n        if (extension->type->decode)\n            status = extension->type->decode(stream, extension, tag, wire_type);\n        else\n            status = default_extension_decoder(stream, extension, tag, wire_type);\n\n        if (!status)\n            return false;\n        \n        extension = extension->next;\n    }\n    \n    return true;\n}\n\n/* Step through the iterator until an extension field is found or until all\n * entries have been checked. There can be only one extension field per\n * message. Returns false if no extension field is found. */\nstatic bool checkreturn find_extension_field(pb_field_iter_t *iter)\n{\n    const pb_field_t *start = iter->pos;\n    \n    do {\n        if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION)\n            return true;\n        (void)pb_field_iter_next(iter);\n    } while (iter->pos != start);\n    \n    return false;\n}\n\n/* Initialize message fields to default values, recursively */\nstatic void pb_field_set_to_default(pb_field_iter_t *iter)\n{\n    pb_type_t type;\n    type = iter->pos->type;\n    \n    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)\n    {\n        pb_extension_t *ext = *(pb_extension_t* const *)iter->pData;\n        while (ext != NULL)\n        {\n            pb_field_iter_t ext_iter;\n            ext->found = false;\n            iter_from_extension(&ext_iter, ext);\n            pb_field_set_to_default(&ext_iter);\n            ext = ext->next;\n        }\n    }\n    else if (PB_ATYPE(type) == PB_ATYPE_STATIC)\n    {\n        bool init_data = true;\n        if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && iter->pSize != iter->pData)\n        {\n            /* Set has_field to false. Still initialize the optional field\n             * itself also. */\n            *(bool*)iter->pSize = false;\n        }\n        else if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||\n                 PB_HTYPE(type) == PB_HTYPE_ONEOF)\n        {\n            /* REPEATED: Set array count to 0, no need to initialize contents.\n               ONEOF: Set which_field to 0. */\n            *(pb_size_t*)iter->pSize = 0;\n            init_data = false;\n        }\n\n        if (init_data)\n        {\n            if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE)\n            {\n                /* Initialize submessage to defaults */\n                pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData);\n            }\n            else if (iter->pos->ptr != NULL)\n            {\n                /* Initialize to default value */\n                memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size);\n            }\n            else\n            {\n                /* Initialize to zeros */\n                memset(iter->pData, 0, iter->pos->data_size);\n            }\n        }\n    }\n    else if (PB_ATYPE(type) == PB_ATYPE_POINTER)\n    {\n        /* Initialize the pointer to NULL. */\n        *(void**)iter->pData = NULL;\n        \n        /* Initialize array count to 0. */\n        if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||\n            PB_HTYPE(type) == PB_HTYPE_ONEOF)\n        {\n            *(pb_size_t*)iter->pSize = 0;\n        }\n    }\n    else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)\n    {\n        /* Don't overwrite callback */\n    }\n}\n\nstatic void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)\n{\n    pb_field_iter_t iter;\n\n    if (!pb_field_iter_begin(&iter, fields, dest_struct))\n        return; /* Empty message type */\n    \n    do\n    {\n        pb_field_set_to_default(&iter);\n    } while (pb_field_iter_next(&iter));\n}\n\n/*********************\n * Decode all fields *\n *********************/\n\nbool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)\n{\n    uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0};\n    const uint32_t allbits = ~(uint32_t)0;\n    uint32_t extension_range_start = 0;\n    pb_field_iter_t iter;\n\n    /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed\n     * count field. This can only handle _one_ repeated fixed count field that\n     * is unpacked and unordered among other (non repeated fixed count) fields.\n     */\n    const pb_field_t *fixed_count_field = NULL;\n    pb_size_t fixed_count_size = 0;\n\n    /* Return value ignored, as empty message types will be correctly handled by\n     * pb_field_iter_find() anyway. */\n    (void)pb_field_iter_begin(&iter, fields, dest_struct);\n\n    while (stream->bytes_left)\n    {\n        uint32_t tag;\n        pb_wire_type_t wire_type;\n        bool eof;\n\n        if (!pb_decode_tag(stream, &wire_type, &tag, &eof))\n        {\n            if (eof)\n                break;\n            else\n                return false;\n        }\n\n        if (!pb_field_iter_find(&iter, tag))\n        {\n            /* No match found, check if it matches an extension. */\n            if (tag >= extension_range_start)\n            {\n                if (!find_extension_field(&iter))\n                    extension_range_start = (uint32_t)-1;\n                else\n                    extension_range_start = iter.pos->tag;\n\n                if (tag >= extension_range_start)\n                {\n                    size_t pos = stream->bytes_left;\n\n                    if (!decode_extension(stream, tag, wire_type, &iter))\n                        return false;\n\n                    if (pos != stream->bytes_left)\n                    {\n                        /* The field was handled */\n                        continue;\n                    }\n                }\n            }\n\n            /* No match found, skip data */\n            if (!pb_skip_field(stream, wire_type))\n                return false;\n            continue;\n        }\n\n        /* If a repeated fixed count field was found, get size from\n         * 'fixed_count_field' as there is no counter contained in the struct.\n         */\n        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED\n            && iter.pSize == iter.pData)\n        {\n            if (fixed_count_field != iter.pos) {\n                /* If the new fixed count field does not match the previous one,\n                 * check that the previous one is NULL or that it finished\n                 * receiving all the expected data.\n                 */\n                if (fixed_count_field != NULL &&\n                    fixed_count_size != fixed_count_field->array_size)\n                {\n                    PB_RETURN_ERROR(stream, \"wrong size for fixed count field\");\n                }\n\n                fixed_count_field = iter.pos;\n                fixed_count_size = 0;\n            }\n\n            iter.pSize = &fixed_count_size;\n        }\n\n        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED\n            && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)\n        {\n            uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31));\n            fields_seen[iter.required_field_index >> 5] |= tmp;\n        }\n\n        if (!decode_field(stream, wire_type, &iter))\n            return false;\n    }\n\n    /* Check that all elements of the last decoded fixed count field were present. */\n    if (fixed_count_field != NULL &&\n        fixed_count_size != fixed_count_field->array_size)\n    {\n        PB_RETURN_ERROR(stream, \"wrong size for fixed count field\");\n    }\n\n    /* Check that all required fields were present. */\n    {\n        /* First figure out the number of required fields by\n         * seeking to the end of the field array. Usually we\n         * are already close to end after decoding.\n         */\n        unsigned req_field_count;\n        pb_type_t last_type;\n        unsigned i;\n        do {\n            req_field_count = iter.required_field_index;\n            last_type = iter.pos->type;\n        } while (pb_field_iter_next(&iter));\n        \n        /* Fixup if last field was also required. */\n        if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0)\n            req_field_count++;\n        \n        if (req_field_count > PB_MAX_REQUIRED_FIELDS)\n            req_field_count = PB_MAX_REQUIRED_FIELDS;\n\n        if (req_field_count > 0)\n        {\n            /* Check the whole words */\n            for (i = 0; i < (req_field_count >> 5); i++)\n            {\n                if (fields_seen[i] != allbits)\n                    PB_RETURN_ERROR(stream, \"missing required field\");\n            }\n            \n            /* Check the remaining bits (if any) */\n            if ((req_field_count & 31) != 0)\n            {\n                if (fields_seen[req_field_count >> 5] !=\n                    (allbits >> (32 - (req_field_count & 31))))\n                {\n                    PB_RETURN_ERROR(stream, \"missing required field\");\n                }\n            }\n        }\n    }\n    \n    return true;\n}\n\nbool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)\n{\n    bool status;\n    pb_message_set_to_defaults(fields, dest_struct);\n    status = pb_decode_noinit(stream, fields, dest_struct);\n    \n#ifdef PB_ENABLE_MALLOC\n    if (!status)\n        pb_release(fields, dest_struct);\n#endif\n    \n    return status;\n}\n\nbool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)\n{\n    pb_istream_t substream;\n    bool status;\n\n    if (!pb_make_string_substream(stream, &substream))\n        return false;\n\n    status = pb_decode_noinit(&substream, fields, dest_struct);\n\n    if (!pb_close_string_substream(stream, &substream))\n        return false;\n    return status;\n}\n\nbool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)\n{\n    pb_istream_t substream;\n    bool status;\n    \n    if (!pb_make_string_substream(stream, &substream))\n        return false;\n    \n    status = pb_decode(&substream, fields, dest_struct);\n\n    if (!pb_close_string_substream(stream, &substream))\n        return false;\n    return status;\n}\n\nbool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)\n{\n    /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */\n    return pb_decode(stream, fields, dest_struct);\n}\n\n#ifdef PB_ENABLE_MALLOC\n/* Given an oneof field, if there has already been a field inside this oneof,\n * release it before overwriting with a different one. */\nstatic bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter)\n{\n    pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */\n    pb_size_t new_tag = iter->pos->tag; /* New which_ value */\n\n    if (old_tag == 0)\n        return true; /* Ok, no old data in union */\n\n    if (old_tag == new_tag)\n        return true; /* Ok, old data is of same type => merge */\n\n    /* Release old data. The find can fail if the message struct contains\n     * invalid data. */\n    if (!pb_field_iter_find(iter, old_tag))\n        PB_RETURN_ERROR(stream, \"invalid union tag\");\n\n    pb_release_single_field(iter);\n\n    /* Restore iterator to where it should be.\n     * This shouldn't fail unless the pb_field_t structure is corrupted. */\n    if (!pb_field_iter_find(iter, new_tag))\n        PB_RETURN_ERROR(stream, \"iterator error\");\n\n    if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER)\n    {\n        /* Initialize the pointer to NULL to make sure it is valid\n         * even in case of error return. */\n        *(void**)iter->pData = NULL;\n    }\n\n    return true;\n}\n\nstatic void pb_release_single_field(const pb_field_iter_t *iter)\n{\n    pb_type_t type;\n    type = iter->pos->type;\n\n    if (PB_HTYPE(type) == PB_HTYPE_ONEOF)\n    {\n        if (*(pb_size_t*)iter->pSize != iter->pos->tag)\n            return; /* This is not the current field in the union */\n    }\n\n    /* Release anything contained inside an extension or submsg.\n     * This has to be done even if the submsg itself is statically\n     * allocated. */\n    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)\n    {\n        /* Release fields from all extensions in the linked list */\n        pb_extension_t *ext = *(pb_extension_t**)iter->pData;\n        while (ext != NULL)\n        {\n            pb_field_iter_t ext_iter;\n            iter_from_extension(&ext_iter, ext);\n            pb_release_single_field(&ext_iter);\n            ext = ext->next;\n        }\n    }\n    else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && PB_ATYPE(type) != PB_ATYPE_CALLBACK)\n    {\n        /* Release fields in submessage or submsg array */\n        void *pItem = iter->pData;\n        pb_size_t count = 1;\n        \n        if (PB_ATYPE(type) == PB_ATYPE_POINTER)\n        {\n            pItem = *(void**)iter->pData;\n        }\n        \n        if (PB_HTYPE(type) == PB_HTYPE_REPEATED)\n        {\n            if (PB_ATYPE(type) == PB_ATYPE_STATIC && iter->pSize == iter->pData) {\n                /* No _count field so use size of the array */\n                count = iter->pos->array_size;\n            } else {\n                count = *(pb_size_t*)iter->pSize;\n            }\n\n            if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size)\n            {\n                /* Protect against corrupted _count fields */\n                count = iter->pos->array_size;\n            }\n        }\n        \n        if (pItem)\n        {\n            while (count--)\n            {\n                pb_release((const pb_field_t*)iter->pos->ptr, pItem);\n                pItem = (char*)pItem + iter->pos->data_size;\n            }\n        }\n    }\n    \n    if (PB_ATYPE(type) == PB_ATYPE_POINTER)\n    {\n        if (PB_HTYPE(type) == PB_HTYPE_REPEATED &&\n            (PB_LTYPE(type) == PB_LTYPE_STRING ||\n             PB_LTYPE(type) == PB_LTYPE_BYTES))\n        {\n            /* Release entries in repeated string or bytes array */\n            void **pItem = *(void***)iter->pData;\n            pb_size_t count = *(pb_size_t*)iter->pSize;\n            while (count--)\n            {\n                pb_free(*pItem);\n                *pItem++ = NULL;\n            }\n        }\n        \n        if (PB_HTYPE(type) == PB_HTYPE_REPEATED)\n        {\n            /* We are going to release the array, so set the size to 0 */\n            *(pb_size_t*)iter->pSize = 0;\n        }\n        \n        /* Release main item */\n        pb_free(*(void**)iter->pData);\n        *(void**)iter->pData = NULL;\n    }\n}\n\nvoid pb_release(const pb_field_t fields[], void *dest_struct)\n{\n    pb_field_iter_t iter;\n    \n    if (!dest_struct)\n        return; /* Ignore NULL pointers, similar to free() */\n\n    if (!pb_field_iter_begin(&iter, fields, dest_struct))\n        return; /* Empty message type */\n    \n    do\n    {\n        pb_release_single_field(&iter);\n    } while (pb_field_iter_next(&iter));\n}\n#endif\n\n/* Field decoders */\n\nbool pb_decode_bool(pb_istream_t *stream, bool *dest)\n{\n    return pb_dec_bool(stream, NULL, (void*)dest);\n}\n\nbool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest)\n{\n    pb_uint64_t value;\n    if (!pb_decode_varint(stream, &value))\n        return false;\n    \n    if (value & 1)\n        *dest = (pb_int64_t)(~(value >> 1));\n    else\n        *dest = (pb_int64_t)(value >> 1);\n    \n    return true;\n}\n\nbool pb_decode_fixed32(pb_istream_t *stream, void *dest)\n{\n    pb_byte_t bytes[4];\n\n    if (!pb_read(stream, bytes, 4))\n        return false;\n    \n    *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) |\n                       ((uint32_t)bytes[1] << 8) |\n                       ((uint32_t)bytes[2] << 16) |\n                       ((uint32_t)bytes[3] << 24);\n    return true;\n}\n\n#ifndef PB_WITHOUT_64BIT\nbool pb_decode_fixed64(pb_istream_t *stream, void *dest)\n{\n    pb_byte_t bytes[8];\n\n    if (!pb_read(stream, bytes, 8))\n        return false;\n    \n    *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) |\n                       ((uint64_t)bytes[1] << 8) |\n                       ((uint64_t)bytes[2] << 16) |\n                       ((uint64_t)bytes[3] << 24) |\n                       ((uint64_t)bytes[4] << 32) |\n                       ((uint64_t)bytes[5] << 40) |\n                       ((uint64_t)bytes[6] << 48) |\n                       ((uint64_t)bytes[7] << 56);\n    \n    return true;\n}\n#endif\n\nstatic bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    uint32_t value;\n    PB_UNUSED(field);\n    if (!pb_decode_varint32(stream, &value))\n        return false;\n\n    *(bool*)dest = (value != 0);\n    return true;\n}\n\nstatic bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    pb_uint64_t value;\n    pb_int64_t svalue;\n    pb_int64_t clamped;\n    if (!pb_decode_varint(stream, &value))\n        return false;\n    \n    /* See issue 97: Google's C++ protobuf allows negative varint values to\n     * be cast as int32_t, instead of the int64_t that should be used when\n     * encoding. Previous nanopb versions had a bug in encoding. In order to\n     * not break decoding of such messages, we cast <=32 bit fields to\n     * int32_t first to get the sign correct.\n     */\n    if (field->data_size == sizeof(pb_int64_t))\n        svalue = (pb_int64_t)value;\n    else\n        svalue = (int32_t)value;\n\n    /* Cast to the proper field size, while checking for overflows */\n    if (field->data_size == sizeof(pb_int64_t))\n        clamped = *(pb_int64_t*)dest = svalue;\n    else if (field->data_size == sizeof(int32_t))\n        clamped = *(int32_t*)dest = (int32_t)svalue;\n    else if (field->data_size == sizeof(int_least16_t))\n        clamped = *(int_least16_t*)dest = (int_least16_t)svalue;\n    else if (field->data_size == sizeof(int_least8_t))\n        clamped = *(int_least8_t*)dest = (int_least8_t)svalue;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n\n    if (clamped != svalue)\n        PB_RETURN_ERROR(stream, \"integer too large\");\n    \n    return true;\n}\n\nstatic bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    pb_uint64_t value, clamped;\n    if (!pb_decode_varint(stream, &value))\n        return false;\n    \n    /* Cast to the proper field size, while checking for overflows */\n    if (field->data_size == sizeof(pb_uint64_t))\n        clamped = *(pb_uint64_t*)dest = value;\n    else if (field->data_size == sizeof(uint32_t))\n        clamped = *(uint32_t*)dest = (uint32_t)value;\n    else if (field->data_size == sizeof(uint_least16_t))\n        clamped = *(uint_least16_t*)dest = (uint_least16_t)value;\n    else if (field->data_size == sizeof(uint_least8_t))\n        clamped = *(uint_least8_t*)dest = (uint_least8_t)value;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n    \n    if (clamped != value)\n        PB_RETURN_ERROR(stream, \"integer too large\");\n\n    return true;\n}\n\nstatic bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    pb_int64_t value, clamped;\n    if (!pb_decode_svarint(stream, &value))\n        return false;\n    \n    /* Cast to the proper field size, while checking for overflows */\n    if (field->data_size == sizeof(pb_int64_t))\n        clamped = *(pb_int64_t*)dest = value;\n    else if (field->data_size == sizeof(int32_t))\n        clamped = *(int32_t*)dest = (int32_t)value;\n    else if (field->data_size == sizeof(int_least16_t))\n        clamped = *(int_least16_t*)dest = (int_least16_t)value;\n    else if (field->data_size == sizeof(int_least8_t))\n        clamped = *(int_least8_t*)dest = (int_least8_t)value;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n\n    if (clamped != value)\n        PB_RETURN_ERROR(stream, \"integer too large\");\n    \n    return true;\n}\n\nstatic bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    PB_UNUSED(field);\n    return pb_decode_fixed32(stream, dest);\n}\n\nstatic bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    PB_UNUSED(field);\n#ifndef PB_WITHOUT_64BIT\n    return pb_decode_fixed64(stream, dest);\n#else\n    PB_UNUSED(dest);\n    PB_RETURN_ERROR(stream, \"no 64bit support\");\n#endif\n}\n\nstatic bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    uint32_t size;\n    size_t alloc_size;\n    pb_bytes_array_t *bdest;\n    \n    if (!pb_decode_varint32(stream, &size))\n        return false;\n    \n    if (size > PB_SIZE_MAX)\n        PB_RETURN_ERROR(stream, \"bytes overflow\");\n    \n    alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size);\n    if (size > alloc_size)\n        PB_RETURN_ERROR(stream, \"size too large\");\n    \n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n    {\n#ifndef PB_ENABLE_MALLOC\n        PB_RETURN_ERROR(stream, \"no malloc support\");\n#else\n        if (stream->bytes_left < size)\n            PB_RETURN_ERROR(stream, \"end-of-stream\");\n\n        if (!allocate_field(stream, dest, alloc_size, 1))\n            return false;\n        bdest = *(pb_bytes_array_t**)dest;\n#endif\n    }\n    else\n    {\n        if (alloc_size > field->data_size)\n            PB_RETURN_ERROR(stream, \"bytes overflow\");\n        bdest = (pb_bytes_array_t*)dest;\n    }\n\n    bdest->size = (pb_size_t)size;\n    return pb_read(stream, bdest->bytes, size);\n}\n\nstatic bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    uint32_t size;\n    size_t alloc_size;\n    bool status;\n    if (!pb_decode_varint32(stream, &size))\n        return false;\n    \n    /* Space for null terminator */\n    alloc_size = size + 1;\n    \n    if (alloc_size < size)\n        PB_RETURN_ERROR(stream, \"size too large\");\n    \n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n    {\n#ifndef PB_ENABLE_MALLOC\n        PB_RETURN_ERROR(stream, \"no malloc support\");\n#else\n        if (stream->bytes_left < size)\n            PB_RETURN_ERROR(stream, \"end-of-stream\");\n\n        if (!allocate_field(stream, dest, alloc_size, 1))\n            return false;\n        dest = *(void**)dest;\n#endif\n    }\n    else\n    {\n        if (alloc_size > field->data_size)\n            PB_RETURN_ERROR(stream, \"string overflow\");\n    }\n    \n    status = pb_read(stream, (pb_byte_t*)dest, size);\n    *((pb_byte_t*)dest + size) = 0;\n    return status;\n}\n\nstatic bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    bool status;\n    pb_istream_t substream;\n    const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr;\n    \n    if (!pb_make_string_substream(stream, &substream))\n        return false;\n    \n    if (field->ptr == NULL)\n        PB_RETURN_ERROR(stream, \"invalid field descriptor\");\n    \n    /* New array entries need to be initialized, while required and optional\n     * submessages have already been initialized in the top-level pb_decode. */\n    if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED)\n        status = pb_decode(&substream, submsg_fields, dest);\n    else\n        status = pb_decode_noinit(&substream, submsg_fields, dest);\n    \n    if (!pb_close_string_substream(stream, &substream))\n        return false;\n    return status;\n}\n\nstatic bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)\n{\n    uint32_t size;\n\n    if (!pb_decode_varint32(stream, &size))\n        return false;\n\n    if (size > PB_SIZE_MAX)\n        PB_RETURN_ERROR(stream, \"bytes overflow\");\n\n    if (size == 0)\n    {\n        /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */\n        memset(dest, 0, field->data_size);\n        return true;\n    }\n\n    if (size != field->data_size)\n        PB_RETURN_ERROR(stream, \"incorrect fixed length bytes size\");\n\n    return pb_read(stream, (pb_byte_t*)dest, field->data_size);\n}\n"
  },
  {
    "path": "Pods/nanopb/pb_decode.h",
    "content": "/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c.\n * The main function is pb_decode. You also need an input stream, and the\n * field descriptions created by nanopb_generator.py.\n */\n\n#ifndef PB_DECODE_H_INCLUDED\n#define PB_DECODE_H_INCLUDED\n\n#include \"pb.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Structure for defining custom input streams. You will need to provide\n * a callback function to read the bytes from your storage, which can be\n * for example a file or a network socket.\n * \n * The callback must conform to these rules:\n *\n * 1) Return false on IO errors. This will cause decoding to abort.\n * 2) You can use state to store your own data (e.g. buffer pointer),\n *    and rely on pb_read to verify that no-body reads past bytes_left.\n * 3) Your callback may be used with substreams, in which case bytes_left\n *    is different than from the main stream. Don't use bytes_left to compute\n *    any pointers.\n */\nstruct pb_istream_s\n{\n#ifdef PB_BUFFER_ONLY\n    /* Callback pointer is not used in buffer-only configuration.\n     * Having an int pointer here allows binary compatibility but\n     * gives an error if someone tries to assign callback function.\n     */\n    int *callback;\n#else\n    bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count);\n#endif\n\n    void *state; /* Free field for use by callback implementation */\n    size_t bytes_left;\n    \n#ifndef PB_NO_ERRMSG\n    const char *errmsg;\n#endif\n};\n\n/***************************\n * Main decoding functions *\n ***************************/\n \n/* Decode a single protocol buffers message from input stream into a C structure.\n * Returns true on success, false on any failure.\n * The actual struct pointed to by dest must match the description in fields.\n * Callback fields of the destination structure must be initialized by caller.\n * All other fields will be initialized by this function.\n *\n * Example usage:\n *    MyMessage msg = {};\n *    uint8_t buffer[64];\n *    pb_istream_t stream;\n *    \n *    // ... read some data into buffer ...\n *\n *    stream = pb_istream_from_buffer(buffer, count);\n *    pb_decode(&stream, MyMessage_fields, &msg);\n */\nbool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);\n\n/* Same as pb_decode, except does not initialize the destination structure\n * to default values. This is slightly faster if you need no default values\n * and just do memset(struct, 0, sizeof(struct)) yourself.\n *\n * This can also be used for 'merging' two messages, i.e. update only the\n * fields that exist in the new message.\n *\n * Note: If this function returns with an error, it will not release any\n * dynamically allocated fields. You will need to call pb_release() yourself.\n */\nbool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);\n\n/* Same as pb_decode, except expects the stream to start with the message size\n * encoded as varint. Corresponds to parseDelimitedFrom() in Google's\n * protobuf API.\n */\nbool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);\n\n/* Same as pb_decode_delimited, except that it does not initialize the destination structure.\n * See pb_decode_noinit\n */\nbool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);\n\n/* Same as pb_decode, except allows the message to be terminated with a null byte.\n * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour\n * is not supported in most other protobuf implementations, so pb_decode_delimited()\n * is a better option for compatibility.\n */\nbool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);\n\n#ifdef PB_ENABLE_MALLOC\n/* Release any allocated pointer fields. If you use dynamic allocation, you should\n * call this for any successfully decoded message when you are done with it. If\n * pb_decode() returns with an error, the message is already released.\n */\nvoid pb_release(const pb_field_t fields[], void *dest_struct);\n#endif\n\n\n/**************************************\n * Functions for manipulating streams *\n **************************************/\n\n/* Create an input stream for reading from a memory buffer.\n *\n * Alternatively, you can use a custom stream that reads directly from e.g.\n * a file or a network socket.\n */\npb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize);\n\n/* Function to read from a pb_istream_t. You can use this if you need to\n * read some custom header data, or to read data in field callbacks.\n */\nbool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);\n\n\n/************************************************\n * Helper functions for writing field callbacks *\n ************************************************/\n\n/* Decode the tag for the next field in the stream. Gives the wire type and\n * field tag. At end of the message, returns false and sets eof to true. */\nbool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof);\n\n/* Skip the field payload data, given the wire type. */\nbool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type);\n\n/* Decode an integer in the varint format. This works for enum, int32,\n * int64, uint32 and uint64 field types. */\n#ifndef PB_WITHOUT_64BIT\nbool pb_decode_varint(pb_istream_t *stream, uint64_t *dest);\n#else\n#define pb_decode_varint pb_decode_varint32\n#endif\n\n/* Decode an integer in the varint format. This works for enum, int32,\n * and uint32 field types. */\nbool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);\n\n/* Decode a bool value in varint format. */\nbool pb_decode_bool(pb_istream_t *stream, bool *dest);\n\n/* Decode an integer in the zig-zagged svarint format. This works for sint32\n * and sint64. */\n#ifndef PB_WITHOUT_64BIT\nbool pb_decode_svarint(pb_istream_t *stream, int64_t *dest);\n#else\nbool pb_decode_svarint(pb_istream_t *stream, int32_t *dest);\n#endif\n\n/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to\n * a 4-byte wide C variable. */\nbool pb_decode_fixed32(pb_istream_t *stream, void *dest);\n\n#ifndef PB_WITHOUT_64BIT\n/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to\n * a 8-byte wide C variable. */\nbool pb_decode_fixed64(pb_istream_t *stream, void *dest);\n#endif\n\n/* Make a limited-length substream for reading a PB_WT_STRING field. */\nbool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream);\nbool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "Pods/nanopb/pb_encode.c",
    "content": "/* pb_encode.c -- encode a protobuf using minimal resources\n *\n * 2011 Petteri Aimonen <jpa@kapsi.fi>\n */\n\n#include \"pb.h\"\n#include \"pb_encode.h\"\n#include \"pb_common.h\"\n\n/* Use the GCC warn_unused_result attribute to check that all return values\n * are propagated correctly. On other compilers and gcc before 3.4.0 just\n * ignore the annotation.\n */\n#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)\n    #define checkreturn\n#else\n    #define checkreturn __attribute__((warn_unused_result))\n#endif\n\n/**************************************\n * Declarations internal to this file *\n **************************************/\ntypedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn;\n\nstatic bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);\nstatic bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func);\nstatic bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);\nstatic bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);\nstatic bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);\nstatic void *pb_const_cast(const void *p);\nstatic bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src);\nstatic bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);\n\n#ifdef PB_WITHOUT_64BIT\n#define pb_int64_t int32_t\n#define pb_uint64_t uint32_t\n\nstatic bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value);\n#else\n#define pb_int64_t int64_t\n#define pb_uint64_t uint64_t\n#endif\n\n/* --- Function pointers to field encoders ---\n * Order in the array must match pb_action_t LTYPE numbering.\n */\nstatic const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {\n    &pb_enc_bool,\n    &pb_enc_varint,\n    &pb_enc_uvarint,\n    &pb_enc_svarint,\n    &pb_enc_fixed32,\n    &pb_enc_fixed64,\n    \n    &pb_enc_bytes,\n    &pb_enc_string,\n    &pb_enc_submessage,\n    NULL, /* extensions */\n    &pb_enc_fixed_length_bytes\n};\n\n/*******************************\n * pb_ostream_t implementation *\n *******************************/\n\nstatic bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)\n{\n    size_t i;\n    pb_byte_t *dest = (pb_byte_t*)stream->state;\n    stream->state = dest + count;\n    \n    for (i = 0; i < count; i++)\n        dest[i] = buf[i];\n    \n    return true;\n}\n\npb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)\n{\n    pb_ostream_t stream;\n#ifdef PB_BUFFER_ONLY\n    stream.callback = (void*)1; /* Just a marker value */\n#else\n    stream.callback = &buf_write;\n#endif\n    stream.state = buf;\n    stream.max_size = bufsize;\n    stream.bytes_written = 0;\n#ifndef PB_NO_ERRMSG\n    stream.errmsg = NULL;\n#endif\n    return stream;\n}\n\nbool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)\n{\n    if (count > 0 && stream->callback != NULL)\n    {\n        if (stream->bytes_written + count < stream->bytes_written ||\n            stream->bytes_written + count > stream->max_size)\n        {\n            PB_RETURN_ERROR(stream, \"stream full\");\n        }\n\n#ifdef PB_BUFFER_ONLY\n        if (!buf_write(stream, buf, count))\n            PB_RETURN_ERROR(stream, \"io error\");\n#else        \n        if (!stream->callback(stream, buf, count))\n            PB_RETURN_ERROR(stream, \"io error\");\n#endif\n    }\n    \n    stream->bytes_written += count;\n    return true;\n}\n\n/*************************\n * Encode a single field *\n *************************/\n\n/* Read a bool value without causing undefined behavior even if the value\n * is invalid. See issue #434 and\n * https://stackoverflow.com/questions/27661768/weird-results-for-conditional\n */\nstatic bool safe_read_bool(const void *pSize)\n{\n    const char *p = (const char *)pSize;\n    size_t i;\n    for (i = 0; i < sizeof(bool); i++)\n    {\n        if (p[i] != 0)\n            return true;\n    }\n    return false;\n}\n\n/* Encode a static array. Handles the size calculations and possible packing. */\nstatic bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field,\n                         const void *pData, size_t count, pb_encoder_t func)\n{\n    size_t i;\n    const void *p;\n#ifndef PB_ENCODE_ARRAYS_UNPACKED\n    size_t size;\n#endif\n\n    if (count == 0)\n        return true;\n\n    if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)\n        PB_RETURN_ERROR(stream, \"array max size exceeded\");\n    \n#ifndef PB_ENCODE_ARRAYS_UNPACKED\n    /* We always pack arrays if the datatype allows it. */\n    if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)\n    {\n        if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))\n            return false;\n        \n        /* Determine the total size of packed array. */\n        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)\n        {\n            size = 4 * count;\n        }\n        else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)\n        {\n            size = 8 * count;\n        }\n        else\n        { \n            pb_ostream_t sizestream = PB_OSTREAM_SIZING;\n            p = pData;\n            for (i = 0; i < count; i++)\n            {\n                if (!func(&sizestream, field, p))\n                    return false;\n                p = (const char*)p + field->data_size;\n            }\n            size = sizestream.bytes_written;\n        }\n        \n        if (!pb_encode_varint(stream, (pb_uint64_t)size))\n            return false;\n        \n        if (stream->callback == NULL)\n            return pb_write(stream, NULL, size); /* Just sizing.. */\n        \n        /* Write the data */\n        p = pData;\n        for (i = 0; i < count; i++)\n        {\n            if (!func(stream, field, p))\n                return false;\n            p = (const char*)p + field->data_size;\n        }\n    }\n    else\n#endif\n    {\n        p = pData;\n        for (i = 0; i < count; i++)\n        {\n            if (!pb_encode_tag_for_field(stream, field))\n                return false;\n\n            /* Normally the data is stored directly in the array entries, but\n             * for pointer-type string and bytes fields, the array entries are\n             * actually pointers themselves also. So we have to dereference once\n             * more to get to the actual data. */\n            if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&\n                (PB_LTYPE(field->type) == PB_LTYPE_STRING ||\n                 PB_LTYPE(field->type) == PB_LTYPE_BYTES))\n            {\n                if (!func(stream, field, *(const void* const*)p))\n                    return false;\n            }\n            else\n            {\n                if (!func(stream, field, p))\n                    return false;\n            }\n            p = (const char*)p + field->data_size;\n        }\n    }\n    \n    return true;\n}\n\n/* In proto3, all fields are optional and are only encoded if their value is \"non-zero\".\n * This function implements the check for the zero value. */\nstatic bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData)\n{\n    pb_type_t type = field->type;\n    const void *pSize = (const char*)pData + field->size_offset;\n\n    if (PB_HTYPE(type) == PB_HTYPE_REQUIRED)\n    {\n        /* Required proto2 fields inside proto3 submessage, pretty rare case */\n        return false;\n    }\n    else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)\n    {\n        /* Repeated fields inside proto3 submessage: present if count != 0 */\n        if (field->size_offset != 0)\n            return *(const pb_size_t*)pSize == 0;\n        else if (PB_ATYPE(type) == PB_ATYPE_STATIC)\n            return false; /* Fixed length array */\n    }\n    else if (PB_HTYPE(type) == PB_HTYPE_ONEOF)\n    {\n        /* Oneof fields */\n        return *(const pb_size_t*)pSize == 0;\n    }\n    else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset != 0)\n    {\n        /* Proto2 optional fields inside proto3 submessage */\n        return safe_read_bool(pSize) == false;\n    }\n\n    /* Rest is proto3 singular fields */\n\n    if (PB_ATYPE(type) == PB_ATYPE_STATIC)\n    {\n        if (PB_LTYPE(type) == PB_LTYPE_BYTES)\n        {\n            const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData;\n            return bytes->size == 0;\n        }\n        else if (PB_LTYPE(type) == PB_LTYPE_STRING)\n        {\n            return *(const char*)pData == '\\0';\n        }\n        else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES)\n        {\n            /* Fixed length bytes is only empty if its length is fixed\n             * as 0. Which would be pretty strange, but we can check\n             * it anyway. */\n            return field->data_size == 0;\n        }\n        else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)\n        {\n            /* Check all fields in the submessage to find if any of them\n             * are non-zero. The comparison cannot be done byte-per-byte\n             * because the C struct may contain padding bytes that must\n             * be skipped.\n             */\n            pb_field_iter_t iter;\n            if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData)))\n            {\n                do\n                {\n                    if (!pb_check_proto3_default_value(iter.pos, iter.pData))\n                    {\n                        return false;\n                    }\n                } while (pb_field_iter_next(&iter));\n            }\n            return true;\n        }\n    }\n\n    /* Compares pointers to NULL in case of FT_POINTER */\n    if (PB_ATYPE(type) == PB_ATYPE_POINTER && PB_LTYPE(type) > PB_LTYPE_LAST_PACKABLE)\n    {\n        return !*(const void**)((uintptr_t)pData);\n    }\n    \n\t{\n\t    /* Catch-all branch that does byte-per-byte comparison for zero value.\n\t     *\n\t     * This is for all pointer fields, and for static PB_LTYPE_VARINT,\n\t     * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also\n\t     * callback fields. These all have integer or pointer value which\n\t     * can be compared with 0.\n\t     */\n\t    pb_size_t i;\n\t    const char *p = (const char*)pData;\n\t    for (i = 0; i < field->data_size; i++)\n\t    {\n\t        if (p[i] != 0)\n\t        {\n\t            return false;\n\t        }\n\t    }\n\n\t    return true;\n\t}\n}\n\n/* Encode a field with static or pointer allocation, i.e. one whose data\n * is available to the encoder directly. */\nstatic bool checkreturn encode_basic_field(pb_ostream_t *stream,\n    const pb_field_t *field, const void *pData)\n{\n    pb_encoder_t func;\n    bool implicit_has;\n    const void *pSize = &implicit_has;\n    \n    func = PB_ENCODERS[PB_LTYPE(field->type)];\n    \n    if (field->size_offset)\n    {\n        /* Static optional, repeated or oneof field */\n        pSize = (const char*)pData + field->size_offset;\n    }\n    else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL)\n    {\n        /* Proto3 style field, optional but without explicit has_ field. */\n        implicit_has = !pb_check_proto3_default_value(field, pData);\n    }\n    else\n    {\n        /* Required field, always present */\n        implicit_has = true;\n    }\n\n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n    {\n        /* pData is a pointer to the field, which contains pointer to\n         * the data. If the 2nd pointer is NULL, it is interpreted as if\n         * the has_field was false.\n         */\n        pData = *(const void* const*)pData;\n        implicit_has = (pData != NULL);\n    }\n\n    switch (PB_HTYPE(field->type))\n    {\n        case PB_HTYPE_REQUIRED:\n            if (!pData)\n                PB_RETURN_ERROR(stream, \"missing required field\");\n            if (!pb_encode_tag_for_field(stream, field))\n                return false;\n            if (!func(stream, field, pData))\n                return false;\n            break;\n        \n        case PB_HTYPE_OPTIONAL:\n            if (safe_read_bool(pSize))\n            {\n                if (!pb_encode_tag_for_field(stream, field))\n                    return false;\n            \n                if (!func(stream, field, pData))\n                    return false;\n            }\n            break;\n        \n        case PB_HTYPE_REPEATED: {\n            pb_size_t count;\n            if (field->size_offset != 0) {\n                count = *(const pb_size_t*)pSize;\n            } else {\n                count = field->array_size;\n            }\n            if (!encode_array(stream, field, pData, count, func))\n                return false;\n            break;\n        }\n        \n        case PB_HTYPE_ONEOF:\n            if (*(const pb_size_t*)pSize == field->tag)\n            {\n                if (!pb_encode_tag_for_field(stream, field))\n                    return false;\n\n                if (!func(stream, field, pData))\n                    return false;\n            }\n            break;\n            \n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n    \n    return true;\n}\n\n/* Encode a field with callback semantics. This means that a user function is\n * called to provide and encode the actual data. */\nstatic bool checkreturn encode_callback_field(pb_ostream_t *stream,\n    const pb_field_t *field, const void *pData)\n{\n    const pb_callback_t *callback = (const pb_callback_t*)pData;\n    \n#ifdef PB_OLD_CALLBACK_STYLE\n    const void *arg = callback->arg;\n#else\n    void * const *arg = &(callback->arg);\n#endif    \n    \n    if (callback->funcs.encode != NULL)\n    {\n        if (!callback->funcs.encode(stream, field, arg))\n            PB_RETURN_ERROR(stream, \"callback error\");\n    }\n    return true;\n}\n\n/* Encode a single field of any callback or static type. */\nstatic bool checkreturn encode_field(pb_ostream_t *stream,\n    const pb_field_t *field, const void *pData)\n{\n    switch (PB_ATYPE(field->type))\n    {\n        case PB_ATYPE_STATIC:\n        case PB_ATYPE_POINTER:\n            return encode_basic_field(stream, field, pData);\n        \n        case PB_ATYPE_CALLBACK:\n            return encode_callback_field(stream, field, pData);\n        \n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n}\n\n/* Default handler for extension fields. Expects to have a pb_field_t\n * pointer in the extension->type->arg field. */\nstatic bool checkreturn default_extension_encoder(pb_ostream_t *stream,\n    const pb_extension_t *extension)\n{\n    const pb_field_t *field = (const pb_field_t*)extension->type->arg;\n    \n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n    {\n        /* For pointer extensions, the pointer is stored directly\n         * in the extension structure. This avoids having an extra\n         * indirection. */\n        return encode_field(stream, field, &extension->dest);\n    }\n    else\n    {\n        return encode_field(stream, field, extension->dest);\n    }\n}\n\n/* Walk through all the registered extensions and give them a chance\n * to encode themselves. */\nstatic bool checkreturn encode_extension_field(pb_ostream_t *stream,\n    const pb_field_t *field, const void *pData)\n{\n    const pb_extension_t *extension = *(const pb_extension_t* const *)pData;\n    PB_UNUSED(field);\n    \n    while (extension)\n    {\n        bool status;\n        if (extension->type->encode)\n            status = extension->type->encode(stream, extension);\n        else\n            status = default_extension_encoder(stream, extension);\n\n        if (!status)\n            return false;\n        \n        extension = extension->next;\n    }\n    \n    return true;\n}\n\n/*********************\n * Encode all fields *\n *********************/\n\nstatic void *pb_const_cast(const void *p)\n{\n    /* Note: this casts away const, in order to use the common field iterator\n     * logic for both encoding and decoding. */\n    union {\n        void *p1;\n        const void *p2;\n    } t;\n    t.p2 = p;\n    return t.p1;\n}\n\nbool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)\n{\n    pb_field_iter_t iter;\n    if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct)))\n        return true; /* Empty message type */\n    \n    do {\n        if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION)\n        {\n            /* Special case for the extension field placeholder */\n            if (!encode_extension_field(stream, iter.pos, iter.pData))\n                return false;\n        }\n        else\n        {\n            /* Regular field */\n            if (!encode_field(stream, iter.pos, iter.pData))\n                return false;\n        }\n    } while (pb_field_iter_next(&iter));\n    \n    return true;\n}\n\nbool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)\n{\n    return pb_encode_submessage(stream, fields, src_struct);\n}\n\nbool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)\n{\n    const pb_byte_t zero = 0;\n\n    if (!pb_encode(stream, fields, src_struct))\n        return false;\n\n    return pb_write(stream, &zero, 1);\n}\n\nbool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct)\n{\n    pb_ostream_t stream = PB_OSTREAM_SIZING;\n    \n    if (!pb_encode(&stream, fields, src_struct))\n        return false;\n    \n    *size = stream.bytes_written;\n    return true;\n}\n\n/********************\n * Helper functions *\n ********************/\n\n#ifdef PB_WITHOUT_64BIT\nbool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value)\n{\n  pb_byte_t buffer[10];\n  size_t i = 0;\n  size_t compensation = 32;/* we need to compensate 32 bits all set to 1 */\n\n  while (value)\n  {\n    buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);\n    value >>= 7;\n    if (compensation)\n    {\n      /* re-set all the compensation bits we can or need */\n      size_t bits = compensation > 7 ? 7 : compensation;\n      value ^= (pb_uint64_t)((0xFFu >> (8 - bits)) << 25); /* set the number of bits needed on the lowest of the most significant 7 bits */\n      compensation -= bits;\n    }\n    i++;\n  }\n  buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */\n\n  return pb_write(stream, buffer, i);\n}\n#endif\n\nbool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value)\n{\n    pb_byte_t buffer[10];\n    size_t i = 0;\n    \n    if (value <= 0x7F)\n    {\n        pb_byte_t v = (pb_byte_t)value;\n        return pb_write(stream, &v, 1);\n    }\n    \n    while (value)\n    {\n        buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);\n        value >>= 7;\n        i++;\n    }\n    buffer[i-1] &= 0x7F; /* Unset top bit on last byte */\n    \n    return pb_write(stream, buffer, i);\n}\n\nbool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value)\n{\n    pb_uint64_t zigzagged;\n    if (value < 0)\n        zigzagged = ~((pb_uint64_t)value << 1);\n    else\n        zigzagged = (pb_uint64_t)value << 1;\n    \n    return pb_encode_varint(stream, zigzagged);\n}\n\nbool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)\n{\n    uint32_t val = *(const uint32_t*)value;\n    pb_byte_t bytes[4];\n    bytes[0] = (pb_byte_t)(val & 0xFF);\n    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);\n    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);\n    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);\n    return pb_write(stream, bytes, 4);\n}\n\n#ifndef PB_WITHOUT_64BIT\nbool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)\n{\n    uint64_t val = *(const uint64_t*)value;\n    pb_byte_t bytes[8];\n    bytes[0] = (pb_byte_t)(val & 0xFF);\n    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);\n    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);\n    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);\n    bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);\n    bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);\n    bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);\n    bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);\n    return pb_write(stream, bytes, 8);\n}\n#endif\n\nbool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)\n{\n    pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype;\n    return pb_encode_varint(stream, tag);\n}\n\nbool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field)\n{\n    pb_wire_type_t wiretype;\n    switch (PB_LTYPE(field->type))\n    {\n        case PB_LTYPE_BOOL:\n        case PB_LTYPE_VARINT:\n        case PB_LTYPE_UVARINT:\n        case PB_LTYPE_SVARINT:\n            wiretype = PB_WT_VARINT;\n            break;\n        \n        case PB_LTYPE_FIXED32:\n            wiretype = PB_WT_32BIT;\n            break;\n        \n        case PB_LTYPE_FIXED64:\n            wiretype = PB_WT_64BIT;\n            break;\n        \n        case PB_LTYPE_BYTES:\n        case PB_LTYPE_STRING:\n        case PB_LTYPE_SUBMESSAGE:\n        case PB_LTYPE_FIXED_LENGTH_BYTES:\n            wiretype = PB_WT_STRING;\n            break;\n        \n        default:\n            PB_RETURN_ERROR(stream, \"invalid field type\");\n    }\n    \n    return pb_encode_tag(stream, wiretype, field->tag);\n}\n\nbool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)\n{\n    if (!pb_encode_varint(stream, (pb_uint64_t)size))\n        return false;\n    \n    return pb_write(stream, buffer, size);\n}\n\nbool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)\n{\n    /* First calculate the message size using a non-writing substream. */\n    pb_ostream_t substream = PB_OSTREAM_SIZING;\n    size_t size;\n    bool status;\n    \n    if (!pb_encode(&substream, fields, src_struct))\n    {\n#ifndef PB_NO_ERRMSG\n        stream->errmsg = substream.errmsg;\n#endif\n        return false;\n    }\n    \n    size = substream.bytes_written;\n    \n    if (!pb_encode_varint(stream, (pb_uint64_t)size))\n        return false;\n    \n    if (stream->callback == NULL)\n        return pb_write(stream, NULL, size); /* Just sizing */\n    \n    if (stream->bytes_written + size > stream->max_size)\n        PB_RETURN_ERROR(stream, \"stream full\");\n        \n    /* Use a substream to verify that a callback doesn't write more than\n     * what it did the first time. */\n    substream.callback = stream->callback;\n    substream.state = stream->state;\n    substream.max_size = size;\n    substream.bytes_written = 0;\n#ifndef PB_NO_ERRMSG\n    substream.errmsg = NULL;\n#endif\n    \n    status = pb_encode(&substream, fields, src_struct);\n    \n    stream->bytes_written += substream.bytes_written;\n    stream->state = substream.state;\n#ifndef PB_NO_ERRMSG\n    stream->errmsg = substream.errmsg;\n#endif\n    \n    if (substream.bytes_written != size)\n        PB_RETURN_ERROR(stream, \"submsg size changed\");\n    \n    return status;\n}\n\n/* Field encoders */\n\nstatic bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    uint32_t value = safe_read_bool(src) ? 1 : 0;\n    PB_UNUSED(field);\n    return pb_encode_varint(stream, value);\n}\n\nstatic bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    pb_int64_t value = 0;\n    \n    if (field->data_size == sizeof(int_least8_t))\n        value = *(const int_least8_t*)src;\n    else if (field->data_size == sizeof(int_least16_t))\n        value = *(const int_least16_t*)src;\n    else if (field->data_size == sizeof(int32_t))\n        value = *(const int32_t*)src;\n    else if (field->data_size == sizeof(pb_int64_t))\n        value = *(const pb_int64_t*)src;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n    \n#ifdef PB_WITHOUT_64BIT\n    if (value < 0)\n      return pb_encode_negative_varint(stream, (pb_uint64_t)value);\n    else\n#endif\n      return pb_encode_varint(stream, (pb_uint64_t)value);\n}\n\nstatic bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    pb_uint64_t value = 0;\n    \n    if (field->data_size == sizeof(uint_least8_t))\n        value = *(const uint_least8_t*)src;\n    else if (field->data_size == sizeof(uint_least16_t))\n        value = *(const uint_least16_t*)src;\n    else if (field->data_size == sizeof(uint32_t))\n        value = *(const uint32_t*)src;\n    else if (field->data_size == sizeof(pb_uint64_t))\n        value = *(const pb_uint64_t*)src;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n    \n    return pb_encode_varint(stream, value);\n}\n\nstatic bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    pb_int64_t value = 0;\n    \n    if (field->data_size == sizeof(int_least8_t))\n        value = *(const int_least8_t*)src;\n    else if (field->data_size == sizeof(int_least16_t))\n        value = *(const int_least16_t*)src;\n    else if (field->data_size == sizeof(int32_t))\n        value = *(const int32_t*)src;\n    else if (field->data_size == sizeof(pb_int64_t))\n        value = *(const pb_int64_t*)src;\n    else\n        PB_RETURN_ERROR(stream, \"invalid data_size\");\n    \n    return pb_encode_svarint(stream, value);\n}\n\nstatic bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    PB_UNUSED(field);\n#ifndef PB_WITHOUT_64BIT\n    return pb_encode_fixed64(stream, src);\n#else\n    PB_UNUSED(src);\n    PB_RETURN_ERROR(stream, \"no 64bit support\");\n#endif\n}\n\nstatic bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    PB_UNUSED(field);\n    return pb_encode_fixed32(stream, src);\n}\n\nstatic bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    const pb_bytes_array_t *bytes = NULL;\n    size_t allocsize;\n\n    bytes = (const pb_bytes_array_t*)src;\n    \n    if (src == NULL)\n    {\n        /* Treat null pointer as an empty bytes field */\n        return pb_encode_string(stream, NULL, 0);\n    }\n    \n    allocsize = PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size);\n    if (allocsize < bytes->size ||\n        (PB_ATYPE(field->type) == PB_ATYPE_STATIC && allocsize > field->data_size))\n    {\n        PB_RETURN_ERROR(stream, \"bytes size exceeded\");\n    }\n    \n    return pb_encode_string(stream, bytes->bytes, bytes->size);\n}\n\nstatic bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    size_t size = 0;\n    size_t max_size = field->data_size;\n    const char *p = (const char*)src;\n    \n    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)\n        max_size = (size_t)-1;\n\n    if (src == NULL)\n    {\n        size = 0; /* Treat null pointer as an empty string */\n    }\n    else\n    {\n        /* strnlen() is not always available, so just use a loop */\n        while (size < max_size && *p != '\\0')\n        {\n            size++;\n            p++;\n        }\n    }\n\n    return pb_encode_string(stream, (const pb_byte_t*)src, size);\n}\n\nstatic bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    if (field->ptr == NULL)\n        PB_RETURN_ERROR(stream, \"invalid field descriptor\");\n    \n    return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src);\n}\n\nstatic bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)\n{\n    return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size);\n}\n\n"
  },
  {
    "path": "Pods/nanopb/pb_encode.h",
    "content": "/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c.\n * The main function is pb_encode. You also need an output stream, and the\n * field descriptions created by nanopb_generator.py.\n */\n\n#ifndef PB_ENCODE_H_INCLUDED\n#define PB_ENCODE_H_INCLUDED\n\n#include \"pb.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Structure for defining custom output streams. You will need to provide\n * a callback function to write the bytes to your storage, which can be\n * for example a file or a network socket.\n *\n * The callback must conform to these rules:\n *\n * 1) Return false on IO errors. This will cause encoding to abort.\n * 2) You can use state to store your own data (e.g. buffer pointer).\n * 3) pb_write will update bytes_written after your callback runs.\n * 4) Substreams will modify max_size and bytes_written. Don't use them\n *    to calculate any pointers.\n */\nstruct pb_ostream_s\n{\n#ifdef PB_BUFFER_ONLY\n    /* Callback pointer is not used in buffer-only configuration.\n     * Having an int pointer here allows binary compatibility but\n     * gives an error if someone tries to assign callback function.\n     * Also, NULL pointer marks a 'sizing stream' that does not\n     * write anything.\n     */\n    int *callback;\n#else\n    bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);\n#endif\n    void *state;          /* Free field for use by callback implementation. */\n    size_t max_size;      /* Limit number of output bytes written (or use SIZE_MAX). */\n    size_t bytes_written; /* Number of bytes written so far. */\n    \n#ifndef PB_NO_ERRMSG\n    const char *errmsg;\n#endif\n};\n\n/***************************\n * Main encoding functions *\n ***************************/\n\n/* Encode a single protocol buffers message from C structure into a stream.\n * Returns true on success, false on any failure.\n * The actual struct pointed to by src_struct must match the description in fields.\n * All required fields in the struct are assumed to have been filled in.\n *\n * Example usage:\n *    MyMessage msg = {};\n *    uint8_t buffer[64];\n *    pb_ostream_t stream;\n *\n *    msg.field1 = 42;\n *    stream = pb_ostream_from_buffer(buffer, sizeof(buffer));\n *    pb_encode(&stream, MyMessage_fields, &msg);\n */\nbool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);\n\n/* Same as pb_encode, but prepends the length of the message as a varint.\n * Corresponds to writeDelimitedTo() in Google's protobuf API.\n */\nbool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);\n\n/* Same as pb_encode, but appends a null byte to the message for termination.\n * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited()\n * is a better option for compatibility.\n */\nbool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);\n\n/* Encode the message to get the size of the encoded data, but do not store\n * the data. */\nbool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);\n\n/**************************************\n * Functions for manipulating streams *\n **************************************/\n\n/* Create an output stream for writing into a memory buffer.\n * The number of bytes written can be found in stream.bytes_written after\n * encoding the message.\n *\n * Alternatively, you can use a custom stream that writes directly to e.g.\n * a file or a network socket.\n */\npb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize);\n\n/* Pseudo-stream for measuring the size of a message without actually storing\n * the encoded data.\n * \n * Example usage:\n *    MyMessage msg = {};\n *    pb_ostream_t stream = PB_OSTREAM_SIZING;\n *    pb_encode(&stream, MyMessage_fields, &msg);\n *    printf(\"Message size is %d\\n\", stream.bytes_written);\n */\n#ifndef PB_NO_ERRMSG\n#define PB_OSTREAM_SIZING {0,0,0,0,0}\n#else\n#define PB_OSTREAM_SIZING {0,0,0,0}\n#endif\n\n/* Function to write into a pb_ostream_t stream. You can use this if you need\n * to append or prepend some custom headers to the message.\n */\nbool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);\n\n\n/************************************************\n * Helper functions for writing field callbacks *\n ************************************************/\n\n/* Encode field header based on type and field number defined in the field\n * structure. Call this from the callback before writing out field contents. */\nbool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field);\n\n/* Encode field header by manually specifying wire type. You need to use this\n * if you want to write out packed arrays from a callback field. */\nbool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number);\n\n/* Encode an integer in the varint format.\n * This works for bool, enum, int32, int64, uint32 and uint64 field types. */\n#ifndef PB_WITHOUT_64BIT\nbool pb_encode_varint(pb_ostream_t *stream, uint64_t value);\n#else\nbool pb_encode_varint(pb_ostream_t *stream, uint32_t value);\n#endif\n\n/* Encode an integer in the zig-zagged svarint format.\n * This works for sint32 and sint64. */\n#ifndef PB_WITHOUT_64BIT\nbool pb_encode_svarint(pb_ostream_t *stream, int64_t value);\n#else\nbool pb_encode_svarint(pb_ostream_t *stream, int32_t value);\n#endif\n\n/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */\nbool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size);\n\n/* Encode a fixed32, sfixed32 or float value.\n * You need to pass a pointer to a 4-byte wide C variable. */\nbool pb_encode_fixed32(pb_ostream_t *stream, const void *value);\n\n#ifndef PB_WITHOUT_64BIT\n/* Encode a fixed64, sfixed64 or double value.\n * You need to pass a pointer to a 8-byte wide C variable. */\nbool pb_encode_fixed64(pb_ostream_t *stream, const void *value);\n#endif\n\n/* Encode a submessage field.\n * You need to pass the pb_field_t array and pointer to struct, just like\n * with pb_encode(). This internally encodes the submessage twice, first to\n * calculate message size and then to actually write it out.\n */\nbool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "README.md",
    "content": "# Spotify Client (iOS - Swift 5 - 2021)\n\nFull featured Spotify like app written in Swift 5 with MVVM architecture.\n\n![Spotify Client iOS Academy](https://raw.githubusercontent.com/AfrazCodes/Spotify-iOS/master/screenshots.png)\n\n## Features\n- Official Spotify API Use\n- Playlists, Playlist Creation,\n- Browse & Recommended\n- Search Songs, Albums, Artists, More\n- Playback and Playlists Playback\n- Save Albums\n- Sign In/Sign Out (OAUTH 2.0)\n- View Your Profile\n- Browse Categories\n- Categorical Playlists\n\n## Notes\n\nThis code is free to use. Note that I have removed the Client Id and Client Secret from the AuthManager that I originally developed this with.\n\nYou can obtain your own credentials from the Spotify Developer website.\n"
  },
  {
    "path": "Spotify/Controllers/Core/HomeViewController.swift",
    "content": "//\n//  ViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nenum BrowseSectionType {\n    case newReleases(viewModels: [NewReleasesCellViewModel]) // 1\n    case featuredPlaylists(viewModels: [FeaturedPlaylistCellViewModel]) // 2\n    case recommendedTracks(viewModels: [RecommendedTrackCellViewModel]) // 3\n\n    var title: String {\n        switch self {\n        case .newReleases:\n            return \"New Released Albums\"\n        case .featuredPlaylists:\n            return \"Featured Playlists\"\n        case .recommendedTracks:\n            return \"Recommended\"\n        }\n    }\n}\n\nclass HomeViewController: UIViewController {\n\n    private var newAlbums: [Album] = []\n    private var playlists: [Playlist] = []\n    private var tracks: [AudioTrack] = []\n\n    private var collectionView: UICollectionView = UICollectionView(\n        frame: .zero,\n        collectionViewLayout: UICollectionViewCompositionalLayout { sectionIndex, _ -> NSCollectionLayoutSection? in\n            return HomeViewController.createSectionLayout(section: sectionIndex)\n        }\n    )\n\n    private let spinner: UIActivityIndicatorView = {\n        let spinner = UIActivityIndicatorView()\n        spinner.tintColor = .label\n        spinner.hidesWhenStopped = true\n        return spinner\n    }()\n\n    private var sections = [BrowseSectionType]()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = \"Browse\"\n        view.backgroundColor = .systemBackground\n        navigationItem.rightBarButtonItem = UIBarButtonItem(\n            image: UIImage(systemName: \"gear\"),\n            style: .done,\n            target: self,\n            action: #selector(didTapSettings)\n        )\n        configureCollectionView()\n        view.addSubview(spinner)\n        fetchData()\n        addLongTapGesture()\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        collectionView.frame = view.bounds\n    }\n\n    private func addLongTapGesture() {\n        let gesture = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(_:)))\n        collectionView.isUserInteractionEnabled = true\n        collectionView.addGestureRecognizer(gesture)\n    }\n\n    @objc func didLongPress(_ gesture: UILongPressGestureRecognizer) {\n        guard gesture.state == .began else {\n            return\n        }\n\n        let touchPoint = gesture.location(in: collectionView)\n        print(\"point: \\(touchPoint)\")\n\n        guard let indexPath = collectionView.indexPathForItem(at: touchPoint),\n              indexPath.section == 2 else {\n            return\n        }\n\n        let model = tracks[indexPath.row]\n\n        let actionSheet = UIAlertController(\n            title: model.name,\n            message: \"Would you like to add this to a playlist?\",\n            preferredStyle: .actionSheet\n        )\n\n        actionSheet.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n\n        actionSheet.addAction(UIAlertAction(title: \"Add to Playlist\", style: .default, handler: { [weak self] _ in\n            DispatchQueue.main.async {\n                let vc = LibraryPlaylistsViewController()\n                vc.selectionHandler = { playlist in\n                    APICaller.shared.addTrackToPlaylist(\n                        track: model,\n                        playlist: playlist\n                    ) { success in\n                        print(\"Added to playlist success: \\(success)\")\n                    }\n                }\n                vc.title = \"Select Playlist\"\n                self?.present(UINavigationController(rootViewController: vc),\n                              animated: true, completion: nil)\n            }\n        }))\n\n        present(actionSheet, animated: true)\n    }\n\n    private func configureCollectionView() {\n        view.addSubview(collectionView)\n        collectionView.register(UICollectionViewCell.self,\n                                forCellWithReuseIdentifier: \"cell\")\n        collectionView.register(NewReleaseCollectionViewCell.self,\n                                forCellWithReuseIdentifier: NewReleaseCollectionViewCell.identifier)\n        collectionView.register(FeaturedPlaylistCollectionViewCell.self,\n                                forCellWithReuseIdentifier: FeaturedPlaylistCollectionViewCell.identifier)\n        collectionView.register(RecommendedTrackCollectionViewCell.self,\n                                forCellWithReuseIdentifier: RecommendedTrackCollectionViewCell.identifier)\n        collectionView.register(\n            TitleHeaderCollectionReusableView.self,\n            forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,\n            withReuseIdentifier: TitleHeaderCollectionReusableView.identifier\n        )\n        collectionView.dataSource = self\n        collectionView.delegate = self\n        collectionView.backgroundColor = .systemBackground\n    }\n\n    private func fetchData() {\n        let group = DispatchGroup()\n        group.enter()\n        group.enter()\n        group.enter()\n        var newReleases: NewReleasesResponse?\n        var featuredPlaylist: FeaturedPlaylistsResponse?\n        var recommendations: RecommendationsResponse?\n\n        // New Releases\n        APICaller.shared.getNewReleases { result in\n            defer {\n                group.leave()\n            }\n            switch result {\n            case .success(let model):\n                newReleases = model\n            case .failure(let error):\n                print(error.localizedDescription)\n            }\n        }\n\n        // Featured Playlists\n        APICaller.shared.getFeaturedFlaylists { result in\n            defer {\n                group.leave()\n            }\n\n            switch result {\n            case .success(let model):\n                featuredPlaylist = model\n            case .failure(let error):\n                print(error.localizedDescription)\n\n            }\n        }\n\n        // Recommended Tracks\n        APICaller.shared.gerRecommendedGenres { result in\n            switch result {\n            case .success(let model):\n                let genres = model.genres\n                var seeds = Set<String>()\n                while seeds.count < 5 {\n                    if let random = genres.randomElement() {\n                        seeds.insert(random)\n                    }\n                }\n\n                APICaller.shared.getRecommendations(genres: seeds) { recommendedResult in\n                    defer {\n                        group.leave()\n                    }\n\n                    switch recommendedResult {\n                    case .success(let model):\n                        recommendations = model\n\n                    case .failure(let error):\n                        print(error.localizedDescription)\n                    }\n                }\n\n            case .failure(let error):\n                print(error.localizedDescription)\n            }\n        }\n\n        group.notify(queue: .main) {\n            guard let newAlbums = newReleases?.albums.items,\n                  let playlists = featuredPlaylist?.playlists.items,\n                  let tracks = recommendations?.tracks else {\n                fatalError(\"Models are nil\")\n            }\n            self.configureModels(\n                newAlbums: newAlbums,\n                playlists: playlists,\n                tracks: tracks\n            )\n        }\n    }\n\n    private func configureModels(\n        newAlbums: [Album],\n        playlists: [Playlist],\n        tracks: [AudioTrack]\n    ) {\n        self.newAlbums = newAlbums\n        self.playlists = playlists\n        self.tracks = tracks\n        sections.append(.newReleases(viewModels: newAlbums.compactMap({\n            return NewReleasesCellViewModel(\n                name: $0.name,\n                artworkURL: URL(string: $0.images.first?.url ?? \"\"),\n                numberOfTracks: $0.total_tracks,\n                artistName: $0.artists.first?.name ?? \"-\"\n            )\n        })))\n\n        sections.append(.featuredPlaylists(viewModels: playlists.compactMap({\n            return FeaturedPlaylistCellViewModel(\n                name: $0.name,\n                artworkURL: URL(string: $0.images.first?.url ?? \"\"),\n                creatorName: $0.owner.display_name\n            )\n        })))\n\n        sections.append(.recommendedTracks(viewModels: tracks.compactMap({\n            return RecommendedTrackCellViewModel(\n                name: $0.name,\n                artistName: $0.artists.first?.name ?? \"-\",\n                artworkURL: URL(string: $0.album?.images.first?.url ?? \"\")\n            )\n        })))\n\n        collectionView.reloadData()\n    }\n\n    @objc func didTapSettings() {\n        let vc = SettingsViewController()\n        vc.title = \"Settings\"\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n}\n\nextension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource {\n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        let type = sections[section]\n        switch type {\n        case .newReleases(let viewModels):\n            return viewModels.count\n        case .featuredPlaylists(let viewModels):\n            return viewModels.count\n        case .recommendedTracks(let viewModels):\n            return viewModels.count\n        }\n    }\n\n    func numberOfSections(in collectionView: UICollectionView) -> Int {\n        return sections.count\n    }\n\n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        let type = sections[indexPath.section]\n        switch type {\n        case .newReleases(let viewModels):\n            guard let cell = collectionView.dequeueReusableCell(\n                withReuseIdentifier: NewReleaseCollectionViewCell.identifier,\n                for: indexPath\n            ) as? NewReleaseCollectionViewCell else {\n                return UICollectionViewCell()\n            }\n            let viewModel = viewModels[indexPath.row]\n            cell.configure(with: viewModel)\n            return cell\n        case .featuredPlaylists(let viewModels):\n            guard let cell = collectionView.dequeueReusableCell(\n                withReuseIdentifier: FeaturedPlaylistCollectionViewCell.identifier,\n                for: indexPath\n            ) as? FeaturedPlaylistCollectionViewCell else {\n                return UICollectionViewCell()\n            }\n            cell.configure(with: viewModels[indexPath.row])\n            return cell\n        case .recommendedTracks(let viewModels):\n            guard let cell = collectionView.dequeueReusableCell(\n                withReuseIdentifier: RecommendedTrackCollectionViewCell.identifier,\n                for: indexPath\n            ) as? RecommendedTrackCollectionViewCell else {\n                return UICollectionViewCell()\n            }\n            cell.configure(with: viewModels[indexPath.row])\n            return cell\n        }\n    }\n\n    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {\n        collectionView.deselectItem(at: indexPath, animated: true)\n        HapticsManager.shared.vibrateForSelection()\n        let section = sections[indexPath.section]\n        switch section {\n        case .featuredPlaylists:\n            let playlist = playlists[indexPath.row]\n            let vc = PlaylistViewController(playlist: playlist)\n            vc.title = playlist.name\n            vc.navigationItem.largeTitleDisplayMode = .never\n            navigationController?.pushViewController(vc, animated: true)\n        case .newReleases:\n            let album = newAlbums[indexPath.row]\n            let vc = AlbumViewController(album: album)\n            vc.title = album.name\n            vc.navigationItem.largeTitleDisplayMode = .never\n            navigationController?.pushViewController(vc, animated: true)\n        case .recommendedTracks:\n            let track = tracks[indexPath.row]\n            PlaybackPresenter.shared.startPlayback(from: self, track: track)\n        }\n    }\n\n    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {\n        guard let header = collectionView.dequeueReusableSupplementaryView(\n            ofKind: kind,\n            withReuseIdentifier: TitleHeaderCollectionReusableView.identifier,\n            for: indexPath\n        ) as? TitleHeaderCollectionReusableView, kind == UICollectionView.elementKindSectionHeader else {\n            return UICollectionReusableView()\n        }\n        let section = indexPath.section\n        let title = sections[section].title\n        header.configure(with: title)\n        return header\n    }\n\n    static func createSectionLayout(section: Int) -> NSCollectionLayoutSection {\n        let supplementaryViews = [\n            NSCollectionLayoutBoundarySupplementaryItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1),\n                    heightDimension: .absolute(50)\n                ),\n                elementKind: UICollectionView.elementKindSectionHeader,\n                alignment: .top\n            )\n        ]\n\n        switch section {\n        case 0:\n            // Item\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .fractionalHeight(1.0)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)\n\n            // Vertical group in horizontal group\n            let verticalGroup = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .absolute(390)\n                ),\n                subitem: item,\n                count: 3\n            )\n\n            let horizontalGroup = NSCollectionLayoutGroup.horizontal(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(0.9),\n                    heightDimension: .absolute(390)\n                ),\n                subitem: verticalGroup,\n                count: 1\n            )\n\n            // Section\n            let section = NSCollectionLayoutSection(group: horizontalGroup)\n            section.orthogonalScrollingBehavior = .groupPaging\n            section.boundarySupplementaryItems = supplementaryViews\n            return section\n        case 1:\n            // Item\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .absolute(200),\n                    heightDimension: .absolute(200)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)\n\n            let verticalGroup = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .absolute(200),\n                    heightDimension: .absolute(400)\n                ),\n                subitem: item,\n                count: 2\n            )\n\n            let horizontalGroup = NSCollectionLayoutGroup.horizontal(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .absolute(200),\n                    heightDimension: .absolute(400)\n                ),\n                subitem: verticalGroup,\n                count: 1\n            )\n\n            // Section\n            let section = NSCollectionLayoutSection(group: horizontalGroup)\n            section.orthogonalScrollingBehavior = .continuous\n            section.boundarySupplementaryItems = supplementaryViews\n            return section\n        case 2:\n            // Item\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .fractionalHeight(1.0)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)\n\n            let group = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1),\n                    heightDimension: .absolute(80)\n                ),\n                subitem: item,\n                count: 1\n            )\n\n            let section = NSCollectionLayoutSection(group: group)\n            section.boundarySupplementaryItems = supplementaryViews\n            return section\n        default:\n            // Item\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .fractionalHeight(1.0)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)\n\n            let group = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .absolute(390)\n                ),\n                subitem: item,\n                count: 1\n            )\n            let section = NSCollectionLayoutSection(group: group)\n            section.boundarySupplementaryItems = supplementaryViews\n            return section\n        }\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Core/LibraryViewController.swift",
    "content": "//\n//  LibraryViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass LibraryViewController: UIViewController {\n\n    private let playlistsVC = LibraryPlaylistsViewController()\n    private let albumsVC = LibraryAlbumsViewController()\n\n    private let scrollView: UIScrollView = {\n        let scrollView = UIScrollView()\n        scrollView.isPagingEnabled = true\n        return scrollView\n    }()\n\n    private let toggleView = LibraryToggleView()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .systemBackground\n\n        view.addSubview(toggleView)\n        toggleView.delegate = self\n\n        view.addSubview(scrollView)\n        scrollView.contentSize = CGSize(width: view.width*2, height: scrollView.height)\n        scrollView.delegate = self\n\n        addChildren()\n        updateBarButtons()\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        scrollView.frame = CGRect(\n            x: 0,\n            y: view.safeAreaInsets.top+55,\n            width: view.width,\n            height: view.height-view.safeAreaInsets.top-view.safeAreaInsets.bottom-55\n        )\n        toggleView.frame = CGRect(\n            x: 0,\n            y: view.safeAreaInsets.top,\n            width: 200,\n            height: 55\n        )\n    }\n\n    private func updateBarButtons() {\n        switch toggleView.state {\n        case .playlist:\n            navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(didTapAdd))\n        case .album:\n            navigationItem.rightBarButtonItem = nil\n        }\n    }\n\n    @objc private func didTapAdd() {\n        playlistsVC.showCreatePlaylistAlert()\n    }\n\n    private func addChildren() {\n        addChild(playlistsVC)\n        scrollView.addSubview(playlistsVC.view)\n        playlistsVC.view.frame = CGRect(x: 0, y: 0, width: scrollView.width, height: scrollView.height)\n        playlistsVC.didMove(toParent: self)\n\n        addChild(albumsVC)\n        scrollView.addSubview(albumsVC.view)\n        albumsVC.view.frame = CGRect(x: view.width, y: 0, width: scrollView.width, height: scrollView.height)\n        albumsVC.didMove(toParent: self)\n    }\n}\n\nextension LibraryViewController: UIScrollViewDelegate {\n    func scrollViewDidScroll(_ scrollView: UIScrollView) {\n        if scrollView.contentOffset.x >= (view.width-100) {\n            toggleView.update(for: .album)\n            updateBarButtons()\n        }\n        else {\n            toggleView.update(for: .playlist)\n            updateBarButtons()\n        }\n    }\n}\n\nextension LibraryViewController: LibraryToggleViewDelegate {\n    func libraryToggleViewDidTapPlaylists(_ toggleView: LibraryToggleView) {\n        scrollView.setContentOffset(.zero, animated: true)\n        updateBarButtons()\n    }\n\n    func libraryToggleViewDidTapAlbums(_ toggleView: LibraryToggleView) {\n        scrollView.setContentOffset(CGPoint(x: view.width, y: 0), animated: true)\n        updateBarButtons()\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Core/SearchViewController.swift",
    "content": "//\n//  SearchViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport SafariServices\nimport UIKit\n\nclass SearchViewController: UIViewController, UISearchResultsUpdating, UISearchBarDelegate {\n\n    let searchController: UISearchController = {\n        let vc = UISearchController(searchResultsController: SearchResultsViewController())\n        vc.searchBar.placeholder = \"Songs, Artists, Albums\"\n        vc.searchBar.searchBarStyle = .minimal\n        vc.definesPresentationContext = true\n        return vc\n    }()\n\n    private let collectionView: UICollectionView = UICollectionView(\n        frame: .zero,\n        collectionViewLayout: UICollectionViewCompositionalLayout(sectionProvider: { _, _ -> NSCollectionLayoutSection? in\n            let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)))\n\n            item.contentInsets = NSDirectionalEdgeInsets(\n                top: 2,\n                leading: 7,\n                bottom: 2,\n                trailing: 7\n            )\n\n            let group = NSCollectionLayoutGroup.horizontal(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1),\n                    heightDimension: .absolute(150)),\n                subitem: item,\n                count: 2\n            )\n\n            group.contentInsets = NSDirectionalEdgeInsets(\n                top: 10,\n                leading: 0,\n                bottom: 10,\n                trailing: 0\n            )\n\n            return NSCollectionLayoutSection(group: group)\n        })\n    )\n\n    private var categories = [Category]()\n\n    // MARK: - Lifecycle\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .systemBackground\n        searchController.searchResultsUpdater = self\n        searchController.searchBar.delegate = self\n        navigationItem.searchController = searchController\n        view.addSubview(collectionView)\n        collectionView.register(CategoryCollectionViewCell.self,\n                                forCellWithReuseIdentifier: CategoryCollectionViewCell.identifier)\n        collectionView.delegate = self\n        collectionView.dataSource = self\n        collectionView.backgroundColor = .systemBackground\n\n        APICaller.shared.getCategories { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let categories):\n                    self?.categories = categories\n                    self?.collectionView.reloadData()\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        collectionView.frame = view.bounds\n    }\n\n    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {\n        guard let resultsController = searchController.searchResultsController as? SearchResultsViewController,\n              let query = searchBar.text,\n              !query.trimmingCharacters(in: .whitespaces).isEmpty else {\n            return\n        }\n        resultsController.delegate = self\n\n        APICaller.shared.search(with: query) { result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let results):\n                    resultsController.update(with: results)\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    func updateSearchResults(for searchController: UISearchController) {\n    }\n}\n\nextension SearchViewController: SearchResultsViewControllerDelegate {\n    func didTapResult(_ result: SearchResult) {\n        switch result {\n        case .artist(let model):\n            guard let url = URL(string: model.external_urls[\"spotify\"] ?? \"\") else {\n                return\n            }\n            let vc = SFSafariViewController(url: url)\n            present(vc, animated: true)\n\n        case .album(let model):\n            let vc = AlbumViewController(album: model)\n            vc.navigationItem.largeTitleDisplayMode = .never\n            navigationController?.pushViewController(vc, animated: true)\n        case .track(let model):\n            PlaybackPresenter.shared.startPlayback(\n                from: self, track: model\n            )\n        case .playlist(let model):\n            let vc = PlaylistViewController(playlist: model)\n            vc.navigationItem.largeTitleDisplayMode = .never\n            navigationController?.pushViewController(vc, animated: true)\n        }\n    }\n}\n\nextension SearchViewController: UICollectionViewDelegate, UICollectionViewDataSource {\n    func numberOfSections(in collectionView: UICollectionView) -> Int {\n        return 1\n    }\n\n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return categories.count\n    }\n\n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        guard let cell = collectionView.dequeueReusableCell(\n                withReuseIdentifier: CategoryCollectionViewCell.identifier,\n                for: indexPath\n        ) as? CategoryCollectionViewCell else {\n            return UICollectionViewCell()\n        }\n        let category = categories[indexPath.row]\n        cell.configure(\n            with: CategoryCollectionViewCellViewModel(\n                title: category.name,\n                artworkURL: URL(string: category.icons.first?.url ?? \"\")\n            )\n        )\n        return cell\n    }\n\n    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {\n        collectionView.deselectItem(at: indexPath, animated: true)\n        HapticsManager.shared.vibrateForSelection()\n        let category = categories[indexPath.row]\n        let vc = CategoryViewController(category: category)\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Core/TabBarViewController.swift",
    "content": "//\n//  TabBarViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass TabBarViewController: UITabBarController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        let vc1 = HomeViewController()\n        let vc2 = SearchViewController()\n        let vc3 = LibraryViewController()\n\n        vc1.title = \"Browse\"\n        vc2.title = \"Search\"\n        vc3.title = \"Library\"\n\n        vc1.navigationItem.largeTitleDisplayMode = .always\n        vc2.navigationItem.largeTitleDisplayMode = .always\n        vc3.navigationItem.largeTitleDisplayMode = .always\n\n        let nav1 = UINavigationController(rootViewController: vc1)\n        let nav2 = UINavigationController(rootViewController: vc2)\n        let nav3 = UINavigationController(rootViewController: vc3)\n\n        nav1.navigationBar.tintColor = .label\n        nav2.navigationBar.tintColor = .label\n        nav3.navigationBar.tintColor = .label\n\n        nav1.tabBarItem = UITabBarItem(title: \"Home\", image: UIImage(systemName: \"house\"), tag: 1)\n        nav2.tabBarItem = UITabBarItem(title: \"Search\", image: UIImage(systemName: \"magnifyingglass\"), tag: 1)\n        nav3.tabBarItem = UITabBarItem(title: \"Library\", image: UIImage(systemName: \"music.note.list\"), tag: 1)\n\n        nav1.navigationBar.prefersLargeTitles = true\n        nav2.navigationBar.prefersLargeTitles = true\n        nav3.navigationBar.prefersLargeTitles = true\n\n        setViewControllers([nav1, nav2, nav3], animated: false)\n    }\n\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/AlbumViewController.swift",
    "content": "//\n//  AlbumViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport UIKit\n\nclass AlbumViewController: UIViewController {\n\n    private let collectionView = UICollectionView(\n        frame: .zero,\n        collectionViewLayout: UICollectionViewCompositionalLayout(sectionProvider: { _, _ -> NSCollectionLayoutSection? in\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .fractionalHeight(1.0)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 2, bottom: 1, trailing: 2)\n\n            let group = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1),\n                    heightDimension: .absolute(60)\n                ),\n                subitem: item,\n                count: 1\n            )\n\n            let section = NSCollectionLayoutSection(group: group)\n            section.boundarySupplementaryItems = [\n                NSCollectionLayoutBoundarySupplementaryItem(\n                    layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),\n                                                       heightDimension: .fractionalWidth(1)),\n                    elementKind: UICollectionView.elementKindSectionHeader,\n                    alignment: .top\n                )\n            ]\n            return section\n        })\n    )\n\n    private var viewModels = [AlbumCollectionViewCellViewModel]()\n\n    private var tracks = [AudioTrack]()\n\n    private let album: Album\n\n    init(album: Album) {\n        self.album = album\n        super.init(nibName: nil, bundle: nil)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = album.name\n        view.backgroundColor = .systemBackground\n        view.addSubview(collectionView)\n        collectionView.register(\n            AlbumTrackCollectionViewCell.self,\n            forCellWithReuseIdentifier: AlbumTrackCollectionViewCell.identifier\n        )\n        collectionView.register(\n            PlaylistHeaderCollectionReusableView.self,\n            forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,\n            withReuseIdentifier: PlaylistHeaderCollectionReusableView.identifier\n        )\n        collectionView.backgroundColor = .systemBackground\n        collectionView.delegate = self\n        collectionView.dataSource = self\n        fetchData()\n        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action,\n                                                            target: self,\n                                                            action: #selector(didTapActions))\n    }\n\n    @objc func didTapActions() {\n        let actionSheet = UIAlertController(title: album.name, message: \"Actions\", preferredStyle: .actionSheet)\n        actionSheet.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n        actionSheet.addAction(UIAlertAction(title: \"Save Album\", style: .default, handler: { [weak self] _ in\n            guard let strongSelf = self else { return }\n            APICaller.shared.saveAlbum(album: strongSelf.album) { success in\n                if success {\n                    HapticsManager.shared.vibrate(for: .success)\n                    NotificationCenter.default.post(name: .albumSavedNotification, object: nil)\n                }\n                else {\n                    HapticsManager.shared.vibrate(for: .error)\n                }\n            }\n        }))\n\n        present(actionSheet, animated: true)\n    }\n\n    func fetchData() {\n        APICaller.shared.getAlbumDetails(for: album) { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let model):\n                    self?.tracks = model.tracks.items\n                    self?.viewModels = model.tracks.items.compactMap({\n                        AlbumCollectionViewCellViewModel(\n                            name: $0.name,\n                            artistName: $0.artists.first?.name ?? \"-\"\n                        )\n                    })\n                    self?.collectionView.reloadData()\n\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        collectionView.frame = view.bounds\n    }\n}\n\nextension AlbumViewController: UICollectionViewDelegate, UICollectionViewDataSource {\n    func numberOfSections(in collectionView: UICollectionView) -> Int {\n        return 1\n    }\n\n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return viewModels.count\n    }\n\n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        guard let cell = collectionView.dequeueReusableCell(\n            withReuseIdentifier: AlbumTrackCollectionViewCell.identifier,\n            for: indexPath\n        ) as? AlbumTrackCollectionViewCell else {\n            return UICollectionViewCell()\n        }\n        cell.configure(with: viewModels[indexPath.row])\n        return cell\n    }\n\n    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {\n        guard let header = collectionView.dequeueReusableSupplementaryView(\n            ofKind: kind,\n            withReuseIdentifier: PlaylistHeaderCollectionReusableView.identifier,\n            for: indexPath\n        ) as? PlaylistHeaderCollectionReusableView,\n        kind == UICollectionView.elementKindSectionHeader else {\n            return UICollectionReusableView()\n        }\n        let headerViewModel = PlaylistHeaderViewViewModel(\n            name: album.name,\n            ownerName: album.artists.first?.name,\n            description: \"Release Date: \\(String.formattedDate(string: album.release_date))\",\n            artworkURL: URL(string: album.images.first?.url ?? \"\")\n        )\n        header.configure(with: headerViewModel)\n        header.delegate = self\n        return header\n    }\n\n    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {\n        collectionView.deselectItem(at: indexPath, animated: true)\n        var track = tracks[indexPath.row]\n        track.album = self.album\n        PlaybackPresenter.shared.startPlayback(from: self, track: track)\n    }\n}\n\nextension AlbumViewController: PlaylistHeaderCollectionReusableViewDelegate {\n    func playlistHeaderCollectionReusableViewDidTapPlayAll(_ header: PlaylistHeaderCollectionReusableView) {\n        let tracksWithAlbum: [AudioTrack] = tracks.compactMap({\n            var track = $0\n            track.album = self.album\n            return track\n        })\n        PlaybackPresenter.shared.startPlayback(from: self, tracks: tracksWithAlbum)\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/AuthViewController.swift",
    "content": "//\n//  AuthViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\nimport WebKit\n\nclass AuthViewController: UIViewController, WKNavigationDelegate {\n\n    private let webView: WKWebView = {\n        let prefs = WKWebpagePreferences()\n        prefs.allowsContentJavaScript = true\n        let config = WKWebViewConfiguration()\n        config.defaultWebpagePreferences = prefs\n        let webView = WKWebView(frame: .zero,\n                                configuration: config)\n        return webView\n    }()\n\n    public var completionHandler: ((Bool) -> Void)?\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = \"Sign In\"\n        view.backgroundColor = .systemBackground\n        webView.navigationDelegate = self\n        view.addSubview(webView)\n        guard let url = AuthManager.shared.signInURL else {\n            return\n        }\n        webView.load(URLRequest(url: url))\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        webView.frame = view.bounds\n    }\n\n    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {\n        guard let url = webView.url else {\n            return\n        }\n\n        // Exchange the code for access token\n        guard let code = URLComponents(string: url.absoluteString)?.queryItems?.first(where: { $0.name == \"code\"  })?.value else {\n            return\n        }\n        webView.isHidden = true\n\n        AuthManager.shared.exchangeCodeForToken(code: code) { [weak self] success in\n            DispatchQueue.main.async {\n                self?.navigationController?.popToRootViewController(animated: true)\n                self?.completionHandler?(success)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/CategoryViewController.swift",
    "content": "//\n//  CategoryViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport UIKit\n\nclass CategoryViewController: UIViewController {\n    let category: Category\n\n    private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewCompositionalLayout(sectionProvider: { _, _ -> NSCollectionLayoutSection? in\n        let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)))\n\n        item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)\n\n        let group = NSCollectionLayoutGroup.horizontal(\n            layoutSize: NSCollectionLayoutSize(\n                widthDimension: .fractionalWidth(1),\n                heightDimension: .absolute(250)\n            ),\n            subitem: item,\n            count: 2\n        )\n        group.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)\n\n        return NSCollectionLayoutSection(group: group)\n    }))\n\n    // MARK: - Init\n\n    init(category: Category) {\n        self.category = category\n        super.init(nibName: nil, bundle: nil)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    private var playlists = [Playlist]()\n\n    // MARK: - Lifecycle\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = category.name\n        view.addSubview(collectionView)\n        view.backgroundColor = .systemBackground\n        collectionView.backgroundColor = .systemBackground\n        collectionView.register(\n            FeaturedPlaylistCollectionViewCell.self,\n            forCellWithReuseIdentifier: FeaturedPlaylistCollectionViewCell.identifier\n        )\n        collectionView.delegate = self\n        collectionView.dataSource = self\n\n        APICaller.shared.getCategoryPlaylists(category: category) { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let playlists):\n                    self?.playlists = playlists\n                    self?.collectionView.reloadData()\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        collectionView.frame = view.bounds\n    }\n}\n\nextension CategoryViewController: UICollectionViewDelegate, UICollectionViewDataSource {\n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return playlists.count\n    }\n\n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        guard let cell = collectionView.dequeueReusableCell(\n            withReuseIdentifier: FeaturedPlaylistCollectionViewCell.identifier,\n            for: indexPath\n        ) as? FeaturedPlaylistCollectionViewCell else {\n            return UICollectionViewCell()\n        }\n        let playlist = playlists[indexPath.row]\n        cell.configure(with: FeaturedPlaylistCellViewModel(\n            name: playlist.name,\n            artworkURL: URL(string: playlist.images.first?.url ?? \"\"),\n            creatorName: playlist.owner.display_name\n        )\n        )\n        return cell\n    }\n\n    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {\n        collectionView.deselectItem(at: indexPath, animated: true)\n        let vc = PlaylistViewController(playlist: playlists[indexPath.row])\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/Library/LibraryAlbumsViewController.swift",
    "content": "//\n//  LibraryAlbumsViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport UIKit\n\nclass LibraryAlbumsViewController: UIViewController {\n\n    var albums = [Album]()\n\n    private let noAlbumsView = ActionLabelView()\n\n    private let tableView: UITableView = {\n        let tableView = UITableView(frame: .zero, style: .grouped)\n        tableView.register(\n            SearchResultSubtitleTableViewCell.self,\n            forCellReuseIdentifier: SearchResultSubtitleTableViewCell.identfier)\n        tableView.isHidden = true\n        return tableView\n    }()\n\n    private var observer: NSObjectProtocol?\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .systemBackground\n        tableView.delegate = self\n        tableView.dataSource = self\n        view.addSubview(tableView)\n        setUpNoAlbumsView()\n        fetchData()\n        observer = NotificationCenter.default.addObserver(\n            forName: .albumSavedNotification,\n            object: nil,\n            queue: .main,\n            using: { [weak self] _ in\n                self?.fetchData()\n            }\n        )\n    }\n\n    @objc func didTapClose() {\n        dismiss(animated: true, completion: nil)\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        noAlbumsView.frame = CGRect(x: (view.width-150)/2, y: (view.height-150)/2, width: 150, height: 150)\n        tableView.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)\n    }\n\n    private func setUpNoAlbumsView() {\n        view.addSubview(noAlbumsView)\n        noAlbumsView.delegate = self\n        noAlbumsView.configure(\n            with: ActionLabelViewViewModel(\n                text: \"You have not saved any albums yet.\",\n                actionTitle: \"Browse\"\n            )\n        )\n    }\n\n    private func fetchData() {\n        albums.removeAll()\n        APICaller.shared.getCurrentUserAlbums { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let albums):\n                    self?.albums = albums\n                    self?.updateUI()\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    private func updateUI() {\n        if albums.isEmpty {\n            // Show label\n            noAlbumsView.isHidden = false\n            tableView.isHidden = true\n        }\n        else {\n            // Show table\n            tableView.reloadData()\n            noAlbumsView.isHidden = true\n            tableView.isHidden = false\n        }\n    }\n}\n\nextension LibraryAlbumsViewController: ActionLabelViewDelegate {\n    func actionLabelViewDidTapButton(_ actionView: ActionLabelView) {\n        tabBarController?.selectedIndex = 0\n    }\n}\n\nextension LibraryAlbumsViewController: UITableViewDelegate, UITableViewDataSource {\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return albums.count\n    }\n\n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        guard let cell = tableView.dequeueReusableCell(\n            withIdentifier: SearchResultSubtitleTableViewCell.identfier,\n            for: indexPath\n        ) as? SearchResultSubtitleTableViewCell else {\n            return UITableViewCell()\n        }\n        let album = albums[indexPath.row]\n        cell.configure(\n            with: SearchResultSubtitleTableViewCellViewModel(\n                title: album.name,\n                subtitle: album.artists.first?.name ?? \"-\",\n                imageURL: URL(string: album.images.first?.url ?? \"\")\n            )\n        )\n        return cell\n    }\n\n    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n        tableView.deselectRow(at: indexPath, animated: true)\n        HapticsManager.shared.vibrateForSelection()\n        let album = albums[indexPath.row]\n        let vc = AlbumViewController(album: album)\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n\n    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {\n        return 70\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/Library/LibraryPlaylistsViewController.swift",
    "content": "//\n//  LibraryPlaylistsViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport UIKit\n\nclass LibraryPlaylistsViewController: UIViewController {\n\n    var playlists = [Playlist]()\n\n    public var selectionHandler: ((Playlist) -> Void)?\n\n    private let noPlaylistsView = ActionLabelView()\n\n    private let tableView: UITableView = {\n        let tableView = UITableView(frame: .zero, style: .grouped)\n        tableView.register(\n            SearchResultSubtitleTableViewCell.self,\n            forCellReuseIdentifier: SearchResultSubtitleTableViewCell.identfier)\n        tableView.isHidden = true\n        return tableView\n    }()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .systemBackground\n        tableView.delegate = self\n        tableView.dataSource = self\n        view.addSubview(tableView)\n        setUpNoPlaylistsView()\n        fetchData()\n\n        if selectionHandler != nil {\n            navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(didTapClose))\n        }\n    }\n\n    @objc func didTapClose() {\n        dismiss(animated: true, completion: nil)\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        noPlaylistsView.frame = CGRect(x: 0, y: 0, width: 150, height: 150)\n        noPlaylistsView.center = view.center\n        tableView.frame = view.bounds\n    }\n\n    private func setUpNoPlaylistsView() {\n        view.addSubview(noPlaylistsView)\n        noPlaylistsView.delegate = self\n        noPlaylistsView.configure(\n            with: ActionLabelViewViewModel(\n                text: \"You don't have any playlists yet.\",\n                actionTitle: \"Create\"\n            )\n        )\n    }\n\n    private func fetchData() {\n        APICaller.shared.getCurrentUserPlaylists { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let playlists):\n                    self?.playlists = playlists\n                    self?.updateUI()\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n    }\n\n    private func updateUI() {\n        if playlists.isEmpty {\n            // Show label\n            noPlaylistsView.isHidden = false\n            tableView.isHidden = true\n        }\n        else {\n            // Show table\n            tableView.reloadData()\n            noPlaylistsView.isHidden = true\n            tableView.isHidden = false\n        }\n    }\n\n    public func showCreatePlaylistAlert() {\n        let alert = UIAlertController(\n            title: \"New Playlists\",\n            message: \"Enter playlist name.\",\n            preferredStyle: .alert\n        )\n        alert.addTextField { textField in\n            textField.placeholder = \"Playlist...\"\n        }\n\n        alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n        alert.addAction(UIAlertAction(title: \"Create\", style: .default, handler: { _ in\n            guard let field = alert.textFields?.first,\n                  let text = field.text,\n                  !text.trimmingCharacters(in: .whitespaces).isEmpty else {\n                return\n            }\n\n            APICaller.shared.createPlaylist(with: text) { [weak self] success in\n                if success {\n                    HapticsManager.shared.vibrate(for: .success)\n                    // Refresh list of playlists\n                    self?.fetchData()\n                }\n                else {\n                    HapticsManager.shared.vibrate(for: .error)\n                    print(\"Failed to create playlist\")\n                }\n            }\n        }))\n\n        present(alert, animated: true)\n    }\n}\n\nextension LibraryPlaylistsViewController: ActionLabelViewDelegate {\n    func actionLabelViewDidTapButton(_ actionView: ActionLabelView) {\n        showCreatePlaylistAlert()\n    }\n}\n\nextension LibraryPlaylistsViewController: UITableViewDelegate, UITableViewDataSource {\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return playlists.count\n    }\n\n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        guard let cell = tableView.dequeueReusableCell(\n            withIdentifier: SearchResultSubtitleTableViewCell.identfier,\n            for: indexPath\n        ) as? SearchResultSubtitleTableViewCell else {\n            return UITableViewCell()\n        }\n        let playlist = playlists[indexPath.row]\n        cell.configure(\n            with: SearchResultSubtitleTableViewCellViewModel(\n                title: playlist.name,\n                subtitle: playlist.owner.display_name,\n                imageURL: URL(string: playlist.images.first?.url ?? \"\")\n            )\n        )\n        return cell\n    }\n\n    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n        tableView.deselectRow(at: indexPath, animated: true)\n        HapticsManager.shared.vibrateForSelection()\n        let playlist = playlists[indexPath.row]\n        guard selectionHandler == nil else {\n            selectionHandler?(playlist)\n            dismiss(animated: true, completion: nil)\n            return\n        }\n\n        let vc = PlaylistViewController(playlist: playlist)\n        vc.navigationItem.largeTitleDisplayMode = .never\n        vc.isOwner = true\n        navigationController?.pushViewController(vc, animated: true)\n    }\n\n    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {\n        return 70\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/PlayerViewController.swift",
    "content": "//\n//  PlayerViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\nimport SDWebImage\n\nprotocol PlayerViewControllerDelegate: AnyObject {\n    func didTapPlayPause()\n    func didTapForward()\n    func didTapBackward()\n    func didSlideSlider(_ value: Float)\n}\n\nclass PlayerViewController: UIViewController {\n\n    weak var dataSource: PlayerDataSource?\n    weak var delegate: PlayerViewControllerDelegate?\n\n    private let imageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    private let controlsView = PlayerControlsView()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .systemBackground\n        view.addSubview(imageView)\n        view.addSubview(controlsView)\n        controlsView.delegate = self\n        configureBarButtons()\n        configure()\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        imageView.frame = CGRect(x: 0, y: view.safeAreaInsets.top, width: view.width, height: view.width)\n        controlsView.frame = CGRect(\n            x: 10,\n            y: imageView.bottom+10,\n            width: view.width-20,\n            height: view.height-imageView.height-view.safeAreaInsets.top-view.safeAreaInsets.bottom-15\n        )\n    }\n\n    private func configure() {\n        imageView.sd_setImage(with: dataSource?.imageURL, completed: nil)\n        controlsView.configure(\n            with: PlayerControlsViewViewModel(\n                title: dataSource?.songName,\n                subtitle: dataSource?.subtitle\n            )\n        )\n    }\n\n    private func configureBarButtons() {\n        navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(didTapClose))\n        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(didTapAction))\n    }\n\n    @objc private func didTapClose() {\n        dismiss(animated: true, completion: nil)\n    }\n\n    @objc private func didTapAction() {\n        // Actions\n    }\n\n    func refreshUI() {\n\n        configure()\n    }\n}\n\nextension PlayerViewController: PlayerControlsViewDelegate {\n    func playerControlsViewDidTapPlayPauseButton(_ playerControlsView: PlayerControlsView) {\n        delegate?.didTapPlayPause()\n    }\n\n    func playerControlsViewDidTapForwardButton(_ playerControlsView: PlayerControlsView) {\n        delegate?.didTapForward()\n    }\n\n    func playerControlsViewDidTapBackwardsButton(_ playerControlsView: PlayerControlsView) {\n        delegate?.didTapBackward()\n    }\n\n    func playerControlsView(_ playerControlsView: PlayerControlsView, didSlideSlider value: Float) {\n        delegate?.didSlideSlider(value)\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/PlaylistViewController.swift",
    "content": "//\n//  PlaylistViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass PlaylistViewController: UIViewController {\n\n    private let playlist: Playlist\n\n    public var isOwner = false\n\n    private let collectionView = UICollectionView(\n        frame: .zero,\n        collectionViewLayout: UICollectionViewCompositionalLayout(sectionProvider: { _, _ -> NSCollectionLayoutSection? in\n            let item = NSCollectionLayoutItem(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1.0),\n                    heightDimension: .fractionalHeight(1.0)\n                )\n            )\n\n            item.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 2, bottom: 1, trailing: 2)\n\n            let group = NSCollectionLayoutGroup.vertical(\n                layoutSize: NSCollectionLayoutSize(\n                    widthDimension: .fractionalWidth(1),\n                    heightDimension: .absolute(60)\n                ),\n                subitem: item,\n                count: 1\n            )\n\n            let section = NSCollectionLayoutSection(group: group)\n            section.boundarySupplementaryItems = [\n                NSCollectionLayoutBoundarySupplementaryItem(\n                    layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),\n                                                       heightDimension: .fractionalWidth(1)),\n                    elementKind: UICollectionView.elementKindSectionHeader,\n                    alignment: .top\n                )\n            ]\n            return section\n        })\n    )\n\n    init(playlist: Playlist) {\n        self.playlist = playlist\n        super.init(nibName: nil, bundle: nil)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    private var viewModels = [RecommendedTrackCellViewModel]()\n    private var tracks = [AudioTrack]()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = playlist.name\n        view.backgroundColor = .systemBackground\n\n        view.addSubview(collectionView)\n        collectionView.register(\n            RecommendedTrackCollectionViewCell.self,\n            forCellWithReuseIdentifier: RecommendedTrackCollectionViewCell.identifier\n        )\n        collectionView.register(\n            PlaylistHeaderCollectionReusableView.self,\n            forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,\n            withReuseIdentifier: PlaylistHeaderCollectionReusableView.identifier\n        )\n        collectionView.backgroundColor = .systemBackground\n        collectionView.delegate = self\n        collectionView.dataSource = self\n\n        APICaller.shared.getPlaylistDetails(for: playlist) { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let model):\n                    self?.tracks = model.tracks.items.compactMap({ $0.track })\n                    self?.viewModels = model.tracks.items.compactMap({\n                        RecommendedTrackCellViewModel(\n                            name: $0.track.name,\n                            artistName: $0.track.artists.first?.name ?? \"-\",\n                            artworkURL: URL(string: $0.track.album?.images.first?.url ?? \"\")\n                        )\n                    })\n                    self?.collectionView.reloadData()\n                case .failure(let error):\n                    print(error.localizedDescription)\n                }\n            }\n        }\n\n        navigationItem.rightBarButtonItem = UIBarButtonItem(\n            barButtonSystemItem: .action,\n            target: self,\n            action: #selector(didTapShare)\n        )\n\n        let gesture = UILongPressGestureRecognizer(target: self,\n                                                   action: #selector(didLongPress(_:)))\n        collectionView.addGestureRecognizer(gesture)\n    }\n\n    @objc func didLongPress(_ gesture: UILongPressGestureRecognizer) {\n        guard gesture.state == .began else {\n            return\n        }\n        let touchPoint = gesture.location(in: collectionView)\n        guard let indexPath = collectionView.indexPathForItem(at: touchPoint) else {\n            return\n        }\n        let trackToDelete = tracks[indexPath.row]\n\n        let actionSheet = UIAlertController(\n            title: trackToDelete.name,\n            message: \"Would you like to remove this from the playlist?\",\n            preferredStyle: .actionSheet\n        )\n        actionSheet.addAction(UIAlertAction(title: \"Cancel\",\n                                            style: .cancel,\n                                            handler: nil))\n        actionSheet.addAction(\n            UIAlertAction(\n                title: \"Remove\",\n                style: .destructive,\n                handler: { [weak self] _ in\n                    guard let strongSelf = self else {\n                        return\n                    }\n                    APICaller.shared.removeTrackFromPlaylist(track: trackToDelete, playlist: strongSelf.playlist) { success in\n                        DispatchQueue.main.async {\n                            if success {\n                                strongSelf.tracks.remove(at: indexPath.row)\n                                strongSelf.viewModels.remove(at: indexPath.row)\n                                strongSelf.collectionView.reloadData()\n                            }\n                            else {\n                                print(\"Failed to remove\")\n                            }\n                        }\n                    }\n                }\n            )\n        )\n        present(actionSheet,\n                animated: true,\n                completion: nil)\n    }\n\n    @objc private func didTapShare() {\n        guard let url = URL(string: playlist.external_urls[\"spotify\"] ?? \"\") else {\n            return\n        }\n\n        let vc = UIActivityViewController(\n            activityItems: [url],\n            applicationActivities: []\n        )\n        vc.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem\n        present(vc, animated: true)\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        collectionView.frame = view.bounds\n    }\n}\n\nextension PlaylistViewController: UICollectionViewDelegate, UICollectionViewDataSource {\n    func numberOfSections(in collectionView: UICollectionView) -> Int {\n        return 1\n    }\n\n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return viewModels.count\n    }\n\n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        guard let cell = collectionView.dequeueReusableCell(\n            withReuseIdentifier: RecommendedTrackCollectionViewCell.identifier,\n            for: indexPath\n        ) as? RecommendedTrackCollectionViewCell else {\n            return UICollectionViewCell()\n        }\n        cell.configure(with: viewModels[indexPath.row])\n        return cell\n    }\n\n    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {\n        guard let header = collectionView.dequeueReusableSupplementaryView(\n            ofKind: kind,\n            withReuseIdentifier: PlaylistHeaderCollectionReusableView.identifier,\n            for: indexPath\n        ) as? PlaylistHeaderCollectionReusableView,\n        kind == UICollectionView.elementKindSectionHeader else {\n            return UICollectionReusableView()\n        }\n        let headerViewModel = PlaylistHeaderViewViewModel(\n            name: playlist.name,\n            ownerName: playlist.owner.display_name,\n            description: playlist.description,\n            artworkURL: URL(string: playlist.images.first?.url ?? \"\")\n        )\n        header.configure(with: headerViewModel)\n        header.delegate = self\n        return header\n    }\n\n    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {\n        collectionView.deselectItem(at: indexPath, animated: true)\n        let index = indexPath.row\n        let track = tracks[index]\n        PlaybackPresenter.shared.startPlayback(from: self, track: track)\n    }\n}\n\nextension PlaylistViewController: PlaylistHeaderCollectionReusableViewDelegate {\n    func playlistHeaderCollectionReusableViewDidTapPlayAll(_ header: PlaylistHeaderCollectionReusableView) {\n        PlaybackPresenter.shared.startPlayback(\n            from: self,\n            tracks: tracks\n        )\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/ProfileViewController.swift",
    "content": "//\n//  ProfileViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport SDWebImage\nimport UIKit\n\nclass ProfileViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {\n\n    private let tableView: UITableView = {\n        let tableView = UITableView()\n        tableView.isHidden = true\n        tableView.register(UITableViewCell.self,\n                           forCellReuseIdentifier: \"cell\")\n        return tableView\n    }()\n\n    private var models = [String]()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = \"Profile\"\n        tableView.delegate = self\n        tableView.dataSource = self\n        view.addSubview(tableView)\n        fetchProfile()\n        view.backgroundColor = .systemBackground\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        tableView.frame = view.bounds\n    }\n\n    private func fetchProfile() {\n        APICaller.shared.getCurrentUserProfile { [weak self] result in\n            DispatchQueue.main.async {\n                switch result {\n                case .success(let model):\n                    self?.updateUI(with: model)\n                case .failure(let error):\n                    print(\"Profile Error: \\(error.localizedDescription)\")\n                    self?.failedToGetProfile()\n                }\n            }\n        }\n    }\n\n    private func updateUI(with model: UserProfile) {\n        tableView.isHidden = false\n        // configure table models\n        models.append(\"Full Name: \\(model.display_name)\")\n        models.append(\"Email Address: \\(model.email)\")\n        models.append(\"User ID: \\(model.id)\")\n        models.append(\"Plan: \\(model.product)\")\n        createTableHeader(with: model.images.first?.url)\n        tableView.reloadData()\n    }\n\n    private func createTableHeader(with string: String?) {\n        guard let urlString = string, let url = URL(string: urlString) else {\n            return\n        }\n\n        let headerView = UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: view.width/1.5))\n\n        let imageSize: CGFloat = headerView.height/2\n        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: imageSize, height: imageSize))\n        headerView.addSubview(imageView)\n        imageView.center = headerView.center\n        imageView.contentMode = .scaleAspectFill\n        imageView.sd_setImage(with: url, completed: nil)\n        imageView.layer.masksToBounds = true\n        imageView.layer.cornerRadius = imageSize/2\n\n        tableView.tableHeaderView = headerView\n    }\n\n    private func failedToGetProfile() {\n        let label = UILabel(frame: .zero)\n        label.text = \"Failed to load profile.\"\n        label.sizeToFit()\n        label.textColor = .secondaryLabel\n        view.addSubview(label)\n        label.center = view.center\n    }\n\n    // MARK: - TableView\n\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return models.count\n    }\n\n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        let cell = tableView.dequeueReusableCell(withIdentifier: \"cell\", for: indexPath)\n        cell.textLabel?.text = models[indexPath.row]\n        cell.selectionStyle = .none\n        return cell\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/SearchResultsViewController.swift",
    "content": "//\n//  SearchResultsViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nstruct SearchSection {\n    let title: String\n    let results: [SearchResult]\n}\n\nprotocol SearchResultsViewControllerDelegate: AnyObject {\n    func didTapResult(_ result: SearchResult)\n}\n\nclass SearchResultsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {\n\n    weak var delegate: SearchResultsViewControllerDelegate?\n\n    private var sections: [SearchSection] = []\n\n    private let tableView: UITableView = {\n        let tableView = UITableView(frame: .zero, style: .grouped)\n        tableView.backgroundColor = .systemBackground\n        tableView.register(SearchResultDefaultTableViewCell.self,\n                           forCellReuseIdentifier: SearchResultDefaultTableViewCell.identfier)\n        tableView.register(SearchResultSubtitleTableViewCell.self,\n                           forCellReuseIdentifier: SearchResultSubtitleTableViewCell.identfier)\n        tableView.isHidden = true\n        return tableView\n    }()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        view.backgroundColor = .clear\n        view.addSubview(tableView)\n        tableView.delegate = self\n        tableView.dataSource = self\n    }\n    \n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        tableView.frame = view.bounds\n    }\n\n    func update(with results: [SearchResult]) {\n        let artists = results.filter({\n            switch $0 {\n            case .artist: return true\n            default: return false\n            }\n        })\n\n        let albums = results.filter({\n            switch $0 {\n            case .album: return true\n            default: return false\n            }\n        })\n\n        let tracks = results.filter({\n            switch $0 {\n            case .track: return true\n            default: return false\n            }\n        })\n\n        let playlists = results.filter({\n            switch $0 {\n            case .playlist: return true\n            default: return false\n            }\n        })\n\n        self.sections = [\n            SearchSection(title: \"Songs\", results: tracks),\n            SearchSection(title: \"Artists\", results: artists),\n            SearchSection(title: \"Playlists\", results: playlists),\n            SearchSection(title: \"Albums\", results: albums)\n        ]\n\n        tableView.reloadData()\n        tableView.isHidden = results.isEmpty\n    }\n\n    func numberOfSections(in tableView: UITableView) -> Int {\n        return sections.count\n    }\n\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return sections[section].results.count\n    }\n\n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        let result = sections[indexPath.section].results[indexPath.row]\n\n        switch result {\n        case .artist(let artist):\n            guard let cell = tableView.dequeueReusableCell(\n                withIdentifier: SearchResultDefaultTableViewCell.identfier,\n                for: indexPath\n            ) as? SearchResultDefaultTableViewCell else {\n                return  UITableViewCell()\n            }\n            let viewModel = SearchResultDefaultTableViewCellViewModel(\n                title: artist.name,\n                imageURL: URL(string: artist.images?.first?.url ?? \"\")\n            )\n            cell.configure(with: viewModel)\n            return cell\n        case .album(let album):\n            guard let cell = tableView.dequeueReusableCell(\n                withIdentifier: SearchResultSubtitleTableViewCell.identfier,\n                for: indexPath\n            ) as? SearchResultSubtitleTableViewCell else {\n                return  UITableViewCell()\n            }\n            let viewModel = SearchResultSubtitleTableViewCellViewModel(\n                title: album.name,\n                subtitle: album.artists.first?.name ?? \"\",\n                imageURL: URL(string: album.images.first?.url ?? \"\")\n            )\n            cell.configure(with: viewModel)\n            return cell\n        case .track(let track):\n            guard let cell = tableView.dequeueReusableCell(\n                withIdentifier: SearchResultSubtitleTableViewCell.identfier,\n                for: indexPath\n            ) as? SearchResultSubtitleTableViewCell else {\n                return  UITableViewCell()\n            }\n            let viewModel = SearchResultSubtitleTableViewCellViewModel(\n                title: track.name,\n                subtitle: track.artists.first?.name ?? \"-\",\n                imageURL: URL(string: track.album?.images.first?.url ?? \"\")\n            )\n            cell.configure(with: viewModel)\n            return cell\n        case .playlist(let playlist):\n            guard let cell = tableView.dequeueReusableCell(\n                withIdentifier: SearchResultSubtitleTableViewCell.identfier,\n                for: indexPath\n            ) as? SearchResultSubtitleTableViewCell else {\n                return  UITableViewCell()\n            }\n            let viewModel = SearchResultSubtitleTableViewCellViewModel(\n                title: playlist.name,\n                subtitle: playlist.owner.display_name,\n                imageURL: URL(string: playlist.images.first?.url ?? \"\")\n            )\n            cell.configure(with: viewModel)\n            return cell\n        }\n    }\n\n    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n        tableView.deselectRow(at: indexPath, animated: true)\n        let result = sections[indexPath.section].results[indexPath.row]\n        delegate?.didTapResult(result)\n    }\n\n    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {\n        return sections[section].title\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/SettingsViewController.swift",
    "content": "//\n//  SettingsViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass SettingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {\n\n    private let tableView: UITableView = {\n        let tableView = UITableView(frame: .zero, style: .grouped)\n        tableView.register(UITableViewCell.self,\n                           forCellReuseIdentifier: \"cell\")\n        return tableView\n    }()\n\n    private var sections = [Section]()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        configureModels()\n        title = \"Settings\"\n        view.backgroundColor = .systemBackground\n        view.addSubview(tableView)\n        tableView.dataSource = self\n        tableView.delegate = self\n    }\n\n    private func configureModels() {\n        sections.append(Section(title: \"Profile\", options: [Option(title: \"View Your Profile\", handler: { [weak self] in\n            DispatchQueue.main.async {\n                self?.viewProfile()\n            }\n        })]))\n\n        sections.append(Section(title: \"Account\", options: [Option(title: \"Sign Out\", handler: { [weak self] in\n            DispatchQueue.main.async {\n                self?.signOutTapped()\n            }\n        })]))\n    }\n\n    private func signOutTapped() {\n       let alert = UIAlertController(title: \"Sign Out\",\n                                     message: \"Are you sure?\",\n                                     preferredStyle: .alert)\n        alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n        alert.addAction(UIAlertAction(title: \"Sign Out\", style: .destructive, handler: { _ in\n            AuthManager.shared.signOut { [weak self] signedOut in\n                if signedOut {\n                    DispatchQueue.main.async {\n                        let navVC = UINavigationController(rootViewController: WelcomeViewController())\n                        navVC.navigationBar.prefersLargeTitles = true\n                        navVC.viewControllers.first?.navigationItem.largeTitleDisplayMode = .always\n                        navVC.modalPresentationStyle = .fullScreen\n                        self?.present(navVC, animated: true, completion: {\n                            self?.navigationController?.popToRootViewController(animated: false)\n                        })\n                    }\n                }\n            }\n        }))\n        present(alert, animated: true)\n    }\n\n    private func viewProfile() {\n        let vc = ProfileViewController()\n        vc.title = \"Profile\"\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        tableView.frame = view.bounds\n    }\n\n    // MARK: - TableView\n\n    func numberOfSections(in tableView: UITableView) -> Int {\n        return sections.count\n    }\n\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return sections[section].options.count\n    }\n\n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        let model = sections[indexPath.section].options[indexPath.row]\n        let cell = tableView.dequeueReusableCell(withIdentifier: \"cell\", for: indexPath)\n        cell.textLabel?.text = model.title\n        return cell\n    }\n\n    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n        tableView.deselectRow(at: indexPath, animated: true)\n        // Call handler for cll\n        let model = sections[indexPath.section].options[indexPath.row]\n        model.handler()\n    }\n\n    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {\n        let model = sections[section]\n        return model.title\n    }\n}\n"
  },
  {
    "path": "Spotify/Controllers/Other/WelcomeViewController.swift",
    "content": "//\n//  WelcomeViewController.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass WelcomeViewController: UIViewController {\n\n    private let signInButton: UIButton = {\n        let button = UIButton()\n        button.backgroundColor = .white\n        button.setTitle(\"Sign In with Spotify\", for: .normal)\n        button.setTitleColor(.black, for: .normal)\n        return button\n    }()\n\n    private let imageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFill\n        imageView.image = UIImage(named: \"albums_background\")\n        return imageView\n    }()\n\n    private let overlayView: UIView = {\n        let view = UIView()\n        view.backgroundColor = .black\n        view.alpha = 0.7\n        return view\n    }()\n\n    private let logoImageView: UIImageView = {\n        let imageView = UIImageView(image: UIImage(named: \"logo\"))\n        imageView.contentMode = .scaleAspectFit\n        return imageView\n    }()\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.textAlignment = .center\n        label.textColor = .white\n        label.font = .systemFont(ofSize: 32, weight: .semibold)\n        label.text = \"Listen to Millions\\nof Songs on\\nthe go.\"\n        return label\n    }()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        title = \"Spotify\"\n        view.addSubview(imageView)\n        view.addSubview(overlayView)\n        view.backgroundColor = .blue\n        view.addSubview(signInButton)\n        signInButton.addTarget(self, action: #selector(didTapSignIn), for: .touchUpInside)\n        view.addSubview(label)\n        view.addSubview(logoImageView)\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        imageView.frame = view.bounds\n        overlayView.frame = view.bounds\n        signInButton.frame = CGRect(\n            x: 20,\n            y: view.height-50-view.safeAreaInsets.bottom,\n            width: view.width-40,\n            height: 50\n        )\n\n        logoImageView.frame = CGRect(x: (view.width-120)/2, y: (view.height-350)/2, width: 120, height: 120)\n        label.frame = CGRect(x: 30, y: logoImageView.bottom+30, width: view.width-60, height: 150)\n    }\n\n    @objc func didTapSignIn() {\n        let vc = AuthViewController()\n        vc.completionHandler = { [weak self] success in\n            DispatchQueue.main.async {\n                self?.handleSignIn(success: success)\n            }\n        }\n        vc.navigationItem.largeTitleDisplayMode = .never\n        navigationController?.pushViewController(vc, animated: true)\n    }\n\n    private func handleSignIn(success: Bool) {\n        // Log user in or yell at them for error\n        guard success else {\n            let alert = UIAlertController(title: \"Oops\",\n                                          message: \"Something went wrong when signing in.\",\n                                          preferredStyle: .alert)\n            alert.addAction(UIAlertAction(title: \"Dismiss\", style: .cancel, handler: nil))\n            present(alert, animated: true)\n            return\n        }\n\n        let mainAppTabBarVC = TabBarViewController()\n        mainAppTabBarVC.modalPresentationStyle = .fullScreen\n        present(mainAppTabBarVC, animated: true)\n    }\n}\n"
  },
  {
    "path": "Spotify/Info.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>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>UIApplicationSupportsIndirectInputEvents</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Spotify/Managers/APICaller.swift",
    "content": "//\n//  APICaller.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nfinal class APICaller {\n    static let shared = APICaller()\n\n    private init() {}\n\n    struct Constants {\n        static let baseAPIURL = \"https://api.spotify.com/v1\"\n    }\n\n    enum APIError: Error {\n        case faileedToGetData\n    }\n\n    // MARK: - Albums\n\n    public func getAlbumDetails(for album: Album, completion: @escaping (Result<AlbumDetailsResponse, Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/albums/\" + album.id),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(AlbumDetailsResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func getCurrentUserAlbums(completion: @escaping (Result<[Album], Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/me/albums\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(LibraryAlbumsResponse.self, from: data)\n                    completion(.success(result.items.compactMap({ $0.album })))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func saveAlbum(album: Album, completion: @escaping (Bool) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/me/albums?ids=\\(album.id)\"),\n            type: .PUT\n        ) { baseRequest in\n            var request = baseRequest\n            request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n\n            let task = URLSession.shared.dataTask(with: request) { data, response, error in\n                guard let code = (response as? HTTPURLResponse)?.statusCode,\n                      error == nil else {\n                    completion(false)\n                    return\n                }\n                print(code)\n                completion(code == 200)\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Playlists\n\n    public func getPlaylistDetails(for playlist: Playlist, completion: @escaping (Result<PlaylistDetailsResponse, Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/playlists/\" + playlist.id),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(PlaylistDetailsResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func getCurrentUserPlaylists(completion: @escaping (Result<[Playlist], Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/me/playlists/?limit=50\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(LibraryPlaylistsResponse.self, from: data)\n                    completion(.success(result.items))\n                }\n                catch {\n                    print(error)\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func createPlaylist(with name: String, completion: @escaping (Bool) -> Void) {\n        getCurrentUserProfile { [weak self] result in\n            switch result {\n            case .success(let profile):\n                let urlString = Constants.baseAPIURL + \"/users/\\(profile.id)/playlists\"\n                print(urlString)\n                self?.createRequest(with: URL(string: urlString), type: .POST) { baseRequest in\n                    var request = baseRequest\n                    let json = [\n                        \"name\": name\n                    ]\n                    request.httpBody = try? JSONSerialization.data(withJSONObject: json, options: .fragmentsAllowed)\n                    print(\"Starting creation...\")\n                    let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                        guard let data = data, error == nil else {\n                            completion(false)\n                            return\n                        }\n\n                        do {\n                            let result = try JSONSerialization.jsonObject(with: data, options: .allowFragments)\n                            if let response = result as? [String: Any], response[\"id\"] as? String != nil {\n                                completion(true)\n                            }\n                            else {\n                                completion(false)\n                            }\n                        }\n                        catch {\n                            print(error.localizedDescription)\n                            completion(false)\n                        }\n                    }\n                    task.resume()\n                }\n\n            case .failure(let error):\n                print(error.localizedDescription)\n            }\n        }\n    }\n\n    public func addTrackToPlaylist(\n        track: AudioTrack,\n        playlist: Playlist,\n        completion: @escaping (Bool) -> Void\n    ) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/playlists/\\(playlist.id)/tracks\"),\n            type: .POST\n        ) { baseRequest in\n            var request = baseRequest\n            let json = [\n                \"uris\": [\n                    \"spotify:track:\\(track.id)\"\n                ]\n            ]\n            print(json)\n            request.httpBody = try? JSONSerialization.data(withJSONObject: json, options: .fragmentsAllowed)\n            request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n            print(\"Adding...\")\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else{\n                    completion(false)\n                    return\n                }\n\n                do {\n                    let result = try JSONSerialization.jsonObject(with: data, options: .allowFragments)\n                        print(result)\n                    if let response = result as? [String: Any],\n                       response[\"snapshot_id\"] as? String != nil {\n                        completion(true)\n                    }\n                    else {\n                        completion(false)\n                    }\n                }\n                catch {\n                    completion(false)\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func removeTrackFromPlaylist(\n        track: AudioTrack,\n        playlist: Playlist,\n        completion: @escaping (Bool) -> Void\n    ) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/playlists/\\(playlist.id)/tracks\"),\n            type: .DELETE\n        ) { baseRequest in\n            var request = baseRequest\n            let json: [String: Any] = [\n                \"tracks\": [\n                    [\n                        \"uri\": \"spotify:track:\\(track.id)\"\n                    ]\n                ]\n            ]\n            request.httpBody = try? JSONSerialization.data(withJSONObject: json, options: .fragmentsAllowed)\n            request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else{\n                    completion(false)\n                    return\n                }\n\n                do {\n                    let result = try JSONSerialization.jsonObject(with: data, options: .allowFragments)\n                    if let response = result as? [String: Any],\n                       response[\"snapshot_id\"] as? String != nil {\n                        completion(true)\n                    }\n                    else {\n                        completion(false)\n                    }\n                }\n                catch {\n                    completion(false)\n                }\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Profile\n\n    public func getCurrentUserProfile(completion: @escaping (Result<UserProfile, Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/me\"),\n            type: .GET\n        ) { baseRequest in\n            let task = URLSession.shared.dataTask(with: baseRequest) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(UserProfile.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    print(error.localizedDescription)\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Browse\n\n    public func getNewReleases(completion: @escaping ((Result<NewReleasesResponse, Error>)) -> Void) {\n        createRequest(with: URL(string: Constants.baseAPIURL + \"/browse/new-releases?limit=50\"), type: .GET) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(NewReleasesResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func getFeaturedFlaylists(completion: @escaping ((Result<FeaturedPlaylistsResponse, Error>) -> Void)) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/browse/featured-playlists?limit=20\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(FeaturedPlaylistsResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func getRecommendations(genres: Set<String>, completion: @escaping ((Result<RecommendationsResponse, Error>) -> Void)) {\n        let seeds = genres.joined(separator: \",\")\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/recommendations?limit=40&seed_genres=\\(seeds)\"),\n            type: .GET\n        ) { request in\n        let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(RecommendationsResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func gerRecommendedGenres(completion: @escaping ((Result<RecommendedGenresResponse, Error>) -> Void)) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/recommendations/available-genre-seeds\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(RecommendedGenresResponse.self, from: data)\n                    completion(.success(result))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Category\n\n    public func getCategories(completion: @escaping (Result<[Category], Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/browse/categories?limit=50\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else{\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(AllCategoriesResponse.self,\n                                                          from: data)\n                    completion(.success(result.categories.items))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    public func getCategoryPlaylists(category: Category, completion: @escaping (Result<[Playlist], Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL + \"/browse/categories/\\(category.id)/playlists?limit=50\"),\n            type: .GET\n        ) { request in\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else{\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(CategoryPlaylistsResponse.self, from: data)\n                    let playlists = result.playlists.items\n                    completion(.success(playlists))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Search\n\n    public func search(with query: String, completion: @escaping (Result<[SearchResult], Error>) -> Void) {\n        createRequest(\n            with: URL(string: Constants.baseAPIURL+\"/search?limit=10&type=album,artist,playlist,track&q=\\(query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? \"\")\"),\n            type: .GET\n        ) { request in\n            print(request.url?.absoluteString ?? \"none\")\n            let task = URLSession.shared.dataTask(with: request) { data, _, error in\n                guard let data = data, error == nil else {\n                    completion(.failure(APIError.faileedToGetData))\n                    return\n                }\n\n                do {\n                    let result = try JSONDecoder().decode(SearchResultsResponse.self, from: data)\n\n                    var searchResults: [SearchResult] = []\n                    searchResults.append(contentsOf: result.tracks.items.compactMap({ .track(model: $0) }))\n                    searchResults.append(contentsOf: result.albums.items.compactMap({ .album(model: $0) }))\n                    searchResults.append(contentsOf: result.artists.items.compactMap({ .artist(model: $0) }))\n                    searchResults.append(contentsOf: result.playlists.items.compactMap({ .playlist(model: $0) }))\n\n                    completion(.success(searchResults))\n                }\n                catch {\n                    completion(.failure(error))\n                }\n            }\n            task.resume()\n        }\n    }\n\n    // MARK: - Private\n\n    enum HTTPMethod: String {\n        case GET\n        case PUT\n        case POST\n        case DELETE\n    }\n\n    private func createRequest(\n        with url: URL?,\n        type: HTTPMethod,\n        completion: @escaping (URLRequest) -> Void\n    ) {\n        AuthManager.shared.withValidToken { token in\n            guard let apiURL = url else {\n                return\n            }\n            var request = URLRequest(url: apiURL)\n            request.setValue(\"Bearer \\(token)\",\n                             forHTTPHeaderField: \"Authorization\")\n            request.httpMethod = type.rawValue\n            request.timeoutInterval = 30\n            completion(request)\n        }\n    }\n}\n"
  },
  {
    "path": "Spotify/Managers/AuthManager.swift",
    "content": "//\n//  AuthManager.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nfinal class AuthManager {\n    static let shared = AuthManager()\n\n    private var refreshingToken = false\n\n    struct Constants {\n        static let clientID = \"ADD_YOUR_CLIENT_ID_HERE\"\n        static let clientSecret = \"ADD_YOUR_CLIENT_SECRET_HERE\"\n        static let tokenAPIURL = \"https://accounts.spotify.com/api/token\"\n        static let redirectURI = \"https://www.iosacademy.io\"\n        static let scopes = \"user-read-private%20playlist-modify-public%20playlist-read-private%20playlist-modify-private%20user-follow-read%20user-library-modify%20user-library-read%20user-read-email\"\n    }\n\n    private init() {}\n\n    public var signInURL: URL? {\n        let base = \"https://accounts.spotify.com/authorize\"\n        let string = \"\\(base)?response_type=code&client_id=\\(Constants.clientID)&scope=\\(Constants.scopes)&redirect_uri=\\(Constants.redirectURI)&show_dialog=TRUE\"\n        return URL(string: string)\n    }\n\n    var isSignedIn: Bool {\n        return accessToken != nil\n    }\n\n    private var accessToken: String? {\n        return UserDefaults.standard.string(forKey: \"access_token\")\n    }\n\n    private var refreshToken: String? {\n        return UserDefaults.standard.string(forKey: \"refresh_token\")\n    }\n\n    private var tokenExpirationDate: Date? {\n        return UserDefaults.standard.object(forKey: \"expirationDate\") as? Date\n    }\n\n    private var shouldRefreshToken: Bool {\n        guard let expirationDate = tokenExpirationDate else {\n            return false\n        }\n        let currentDate = Date()\n        let fiveMinutes: TimeInterval = 300\n        return currentDate.addingTimeInterval(fiveMinutes) >= expirationDate\n    }\n\n    public func exchangeCodeForToken(\n        code: String,\n        completion: @escaping ((Bool) -> Void)\n    ) {\n        // Get Token\n        guard let url = URL(string: Constants.tokenAPIURL) else {\n            return\n        }\n\n        var components = URLComponents()\n        components.queryItems = [\n            URLQueryItem(name: \"grant_type\",\n                         value: \"authorization_code\"),\n            URLQueryItem(name: \"code\",\n                         value: code),\n            URLQueryItem(name: \"redirect_uri\",\n                         value: Constants.redirectURI),\n        ]\n\n        var request = URLRequest(url: url)\n        request.httpMethod = \"POST\"\n        request.setValue(\"application/x-www-form-urlencoded \",\n                         forHTTPHeaderField: \"Content-Type\")\n        request.httpBody = components.query?.data(using: .utf8)\n\n        let basicToken = Constants.clientID+\":\"+Constants.clientSecret\n        let data = basicToken.data(using: .utf8)\n        guard let base64String = data?.base64EncodedString() else {\n            print(\"Failure to get base64\")\n            completion(false)\n            return\n        }\n\n        request.setValue(\"Basic \\(base64String)\",\n                         forHTTPHeaderField: \"Authorization\")\n\n        let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in\n            guard let data = data,\n                  error == nil else {\n                completion(false)\n                return\n            }\n\n            do {\n                let result = try JSONDecoder().decode(AuthResponse.self, from: data)\n                self?.cacheToken(result: result)\n                completion(true)\n            }\n            catch {\n                print(error.localizedDescription)\n                completion(false)\n            }\n        }\n        task.resume()\n    }\n\n    private var onRefreshBlocks = [((String) -> Void)]()\n\n    /// Supplies valid token to be used with API Calls\n    public func withValidToken(completion: @escaping (String) -> Void) {\n        guard !refreshingToken else {\n            // Append the compleiton\n            onRefreshBlocks.append(completion)\n            return\n        }\n\n        if shouldRefreshToken {\n            // Refresh\n            refreshIfNeeded { [weak self] success in\n                if let token = self?.accessToken, success {\n                    completion(token)\n                }\n            }\n        }\n        else if let token = accessToken {\n            completion(token)\n        }\n    }\n\n    public func refreshIfNeeded(completion: ((Bool) -> Void)?) {\n        guard !refreshingToken else {\n            return\n        }\n\n        guard shouldRefreshToken else {\n            completion?(true)\n            return\n        }\n\n        guard let refreshToken = self.refreshToken else{\n            return\n        }\n\n        // Refresh the token\n        guard let url = URL(string: Constants.tokenAPIURL) else {\n            return\n        }\n\n        refreshingToken = true\n\n        var components = URLComponents()\n        components.queryItems = [\n            URLQueryItem(name: \"grant_type\",\n                         value: \"refresh_token\"),\n            URLQueryItem(name: \"refresh_token\",\n                         value: refreshToken),\n        ]\n\n        var request = URLRequest(url: url)\n        request.httpMethod = \"POST\"\n        request.setValue(\"application/x-www-form-urlencoded \",\n                         forHTTPHeaderField: \"Content-Type\")\n        request.httpBody = components.query?.data(using: .utf8)\n\n        let basicToken = Constants.clientID+\":\"+Constants.clientSecret\n        let data = basicToken.data(using: .utf8)\n        guard let base64String = data?.base64EncodedString() else {\n            print(\"Failure to get base64\")\n            completion?(false)\n            return\n        }\n\n        request.setValue(\"Basic \\(base64String)\",\n                         forHTTPHeaderField: \"Authorization\")\n\n        let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in\n            self?.refreshingToken = false\n            guard let data = data,\n                  error == nil else {\n                completion?(false)\n                return\n            }\n\n            do {\n                let result = try JSONDecoder().decode(AuthResponse.self, from: data)\n                self?.onRefreshBlocks.forEach { $0(result.access_token) }\n                self?.onRefreshBlocks.removeAll()\n                self?.cacheToken(result: result)\n                completion?(true)\n            }\n            catch {\n                print(error.localizedDescription)\n                completion?(false)\n            }\n        }\n        task.resume()\n    }\n\n    private func cacheToken(result: AuthResponse) {\n        UserDefaults.standard.setValue(result.access_token,\n                                       forKey: \"access_token\")\n        if let refresh_token = result.refresh_token {\n            UserDefaults.standard.setValue(refresh_token,\n                                           forKey: \"refresh_token\")\n        }\n        UserDefaults.standard.setValue(Date().addingTimeInterval(TimeInterval(result.expires_in)),\n                                       forKey: \"expirationDate\")\n    }\n\n    public func signOut(completion: (Bool) -> Void) {\n        UserDefaults.standard.setValue(nil,\n                                       forKey: \"access_token\")\n        UserDefaults.standard.setValue(nil,\n                                       forKey: \"refresh_token\")\n        UserDefaults.standard.setValue(nil,\n                                       forKey: \"expirationDate\")\n\n        completion(true)\n    }\n}\n"
  },
  {
    "path": "Spotify/Managers/HapticsManager.swift",
    "content": "//\n//  HapticsManager.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\nimport UIKit\n\nfinal class HapticsManager {\n    static let shared = HapticsManager()\n\n    private init() {}\n\n    public func vibrateForSelection() {\n        DispatchQueue.main.async {\n            let generator = UISelectionFeedbackGenerator()\n            generator.prepare()\n            generator.selectionChanged()\n        }\n    }\n\n    public func vibrate(for type: UINotificationFeedbackGenerator.FeedbackType) {\n        DispatchQueue.main.async {\n            let generator = UINotificationFeedbackGenerator()\n            generator.prepare()\n            generator.notificationOccurred(type)\n        }\n    }\n}\n"
  },
  {
    "path": "Spotify/Models/APIImage.swift",
    "content": "//\n//  UserImage.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct APIImage: Codable {\n    let url: String\n}\n"
  },
  {
    "path": "Spotify/Models/AlbumDetailsResponse.swift",
    "content": "//\n//  AlbumDetailsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct AlbumDetailsResponse: Codable {\n    let album_type: String\n    let artists: [Artist]\n    let available_markets: [String]\n    let external_urls: [String: String]\n    let id: String\n    let images: [APIImage]\n    let label: String\n    let name: String\n    let tracks: TracksResponse\n}\n\nstruct TracksResponse: Codable {\n    let items: [AudioTrack]\n}\n"
  },
  {
    "path": "Spotify/Models/AllCategoriesResponse.swift",
    "content": "//\n//  AllCategoriesResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\n\nstruct AllCategoriesResponse: Codable {\n    let categories: Categories\n}\n\nstruct Categories: Codable {\n    let items: [Category]\n}\n\nstruct Category: Codable {\n    let id: String\n    let name: String\n    let icons: [APIImage]\n}\n"
  },
  {
    "path": "Spotify/Models/Artist.swift",
    "content": "//\n//  Artist.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nstruct Artist: Codable {\n    let id: String\n    let name: String\n    let type: String\n    let images: [APIImage]?\n    let external_urls: [String: String]\n}\n"
  },
  {
    "path": "Spotify/Models/AudioTrack.swift",
    "content": "//\n//  AudioTrack.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nstruct AudioTrack: Codable {\n    var album: Album?\n    let artists: [Artist]\n    let available_markets: [String]\n    let disc_number: Int\n    let duration_ms: Int\n    let explicit: Bool\n    let external_urls: [String: String]\n    let id: String\n    let name: String\n    let preview_url: String?\n}\n\n\n"
  },
  {
    "path": "Spotify/Models/AuthResponse.swift",
    "content": "//\n//  AuthResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nstruct AuthResponse: Codable {\n    let access_token: String\n    let expires_in: Int\n    let refresh_token: String?\n    let scope: String\n    let token_type: String\n}\n"
  },
  {
    "path": "Spotify/Models/FeaturedPlaylistsResponse.swift",
    "content": "//\n//  FeaturedPlaylistsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct FeaturedPlaylistsResponse: Codable {\n    let playlists: PlaylistResponse\n}\n\nstruct CategoryPlaylistsResponse: Codable {\n    let playlists: PlaylistResponse\n}\n\nstruct PlaylistResponse: Codable {\n    let items: [Playlist]\n}\n\nstruct User: Codable {\n    let display_name: String\n    let external_urls: [String: String]\n    let id: String\n}\n"
  },
  {
    "path": "Spotify/Models/LibraryAlbumsResponse.swift",
    "content": "//\n//  LibraryAlbumsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport Foundation\n\nstruct LibraryAlbumsResponse: Codable {\n    let items: [SavedAlbum]\n}\n\nstruct SavedAlbum: Codable {\n    let added_at: String\n    let album: Album\n}\n"
  },
  {
    "path": "Spotify/Models/LibraryPlaylistsResponse.swift",
    "content": "//\n//  LibraryPlaylistsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport Foundation\n\nstruct LibraryPlaylistsResponse: Codable {\n    let items: [Playlist]\n}\n"
  },
  {
    "path": "Spotify/Models/NewReleasesResponse.swift",
    "content": "//\n//  NewReleasesResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct NewReleasesResponse: Codable {\n    let albums: AlbumsResponse\n}\n\nstruct AlbumsResponse: Codable {\n    let items: [Album]\n}\n\nstruct Album: Codable {\n    let album_type: String\n    let available_markets: [String]\n    let id: String\n    var images: [APIImage]\n    let name: String\n    let release_date: String\n    let total_tracks: Int\n    let artists: [Artist]\n}\n"
  },
  {
    "path": "Spotify/Models/Playlist.swift",
    "content": "//\n//  Playlist.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nstruct Playlist: Codable {\n    let description: String\n    let external_urls: [String: String]\n    let id: String\n    let images: [APIImage]\n    let name: String\n    let owner: User\n}\n"
  },
  {
    "path": "Spotify/Models/PlaylistDetailsResponse.swift",
    "content": "//\n//  PlaylistDetailsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct PlaylistDetailsResponse: Codable {\n    let description: String\n    let external_urls: [String: String]\n    let id: String\n    let images: [APIImage]\n    let name: String\n    let tracks: PlaylistTracksResponse\n}\n\nstruct PlaylistTracksResponse: Codable {\n    let items: [PlaylistItem]\n}\n\nstruct PlaylistItem: Codable {\n    let track: AudioTrack\n}\n"
  },
  {
    "path": "Spotify/Models/RecommendationsResponse.swift",
    "content": "//\n//  RecommendationsResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct RecommendationsResponse: Codable {\n    let tracks: [AudioTrack]\n}\n\n\n"
  },
  {
    "path": "Spotify/Models/RecommendedGenresResponse.swift",
    "content": "//\n//  RecommendedGenresResponse.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct RecommendedGenresResponse: Codable {\n    let genres: [String]\n}\n"
  },
  {
    "path": "Spotify/Models/SearchResult.swift",
    "content": "//\n//  SearchResult.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\n\nenum SearchResult {\n    case artist(model: Artist)\n    case album(model: Album)\n    case track(model: AudioTrack)\n    case playlist(model: Playlist)\n}\n"
  },
  {
    "path": "Spotify/Models/SearchResultResponse.swift",
    "content": "//\n//  SearchResult.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\n\nstruct SearchResultsResponse: Codable {\n    let albums: SearchAlbumResponse\n    let artists: SearchArtistsResponse\n    let playlists: SearchPlaylistsResponse\n    let tracks: SearchTrackssResponse\n}\n\nstruct SearchAlbumResponse: Codable {\n    let items: [Album]\n}\n\nstruct SearchArtistsResponse: Codable {\n    let items: [Artist]\n}\n\nstruct SearchPlaylistsResponse: Codable {\n    let items: [Playlist]\n}\n\nstruct SearchTrackssResponse: Codable {\n    let items: [AudioTrack]\n}\n"
  },
  {
    "path": "Spotify/Models/SettingsModels.swift",
    "content": "//\n//  SettingsModels.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct Section {\n    let title: String\n    let options: [Option]\n}\n\nstruct Option {\n    let title: String\n    let handler: () -> Void\n}\n"
  },
  {
    "path": "Spotify/Models/UserProfile.swift",
    "content": "//\n//  UserProfile.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\n\nstruct UserProfile: Codable {\n    let country: String\n    let display_name: String\n    let email: String\n    let explicit_content: [String: Bool]\n    let external_urls: [String: String]\n    let id: String\n    let product: String\n    let images: [APIImage]\n}\n"
  },
  {
    "path": "Spotify/Presenter/PlaybackPresenter.swift",
    "content": "//\n//  PlaybackPresenter.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport AVFoundation\nimport Foundation\nimport UIKit\n\nprotocol PlayerDataSource: AnyObject {\n    var songName: String? { get }\n    var subtitle: String? { get }\n    var imageURL: URL? { get }\n}\n\nfinal class PlaybackPresenter {\n    static let shared = PlaybackPresenter()\n\n    private var track: AudioTrack?\n    private var tracks = [AudioTrack]()\n\n    var index = 0\n\n    var currentTrack: AudioTrack? {\n        if let track = track, tracks.isEmpty {\n            return track\n        }\n        else if let player = self.playerQueue, !tracks.isEmpty {\n            return tracks[index]\n        }\n\n        return nil\n    }\n\n    var playerVC: PlayerViewController?\n\n    var player: AVPlayer?\n    var playerQueue: AVQueuePlayer?\n\n    func startPlayback(\n        from viewController: UIViewController,\n        track: AudioTrack\n    ) {\n        guard let url = URL(string: track.preview_url ?? \"\") else {\n            return\n        }\n        player = AVPlayer(url: url)\n        player?.volume = 0.5\n\n        self.track = track\n        self.tracks = []\n        let vc = PlayerViewController()\n        vc.title = track.name\n        vc.dataSource = self\n        vc.delegate = self\n        viewController.present(UINavigationController(rootViewController: vc), animated: true) { [weak self] in\n            self?.player?.play()\n        }\n        self.playerVC = vc\n    }\n\n    func startPlayback(\n        from viewController: UIViewController,\n        tracks: [AudioTrack]\n    ) {\n        self.tracks = tracks\n        self.track = nil\n\n        self.playerQueue = AVQueuePlayer(items: tracks.compactMap({\n            guard let url = URL(string: $0.preview_url ?? \"\") else {\n                return nil\n            }\n            return AVPlayerItem(url: url)\n        }))\n        self.playerQueue?.volume = 0.5\n        self.playerQueue?.play()\n\n        let vc = PlayerViewController()\n        vc.dataSource = self\n        vc.delegate = self\n        viewController.present(UINavigationController(rootViewController: vc), animated: true, completion: nil)\n        self.playerVC = vc\n    }\n}\n\nextension PlaybackPresenter: PlayerViewControllerDelegate {\n    func didTapPlayPause() {\n        if let player = player {\n            if player.timeControlStatus == .playing {\n                player.pause()\n            }\n            else if player.timeControlStatus == .paused {\n                player.play()\n            }\n        }\n        else if let player = playerQueue {\n            if player.timeControlStatus == .playing {\n                player.pause()\n            }\n            else if player.timeControlStatus == .paused {\n                player.play()\n            }\n        }\n    }\n\n    func didTapForward() {\n        if tracks.isEmpty {\n            // Not playlist or album\n            player?.pause()\n        }\n        else if let player = playerQueue {\n            player.advanceToNextItem()\n            index += 1\n            print(index)\n            playerVC?.refreshUI()\n        }\n    }\n\n    func didTapBackward() {\n        if tracks.isEmpty {\n            // Not playlist or album\n            player?.pause()\n            player?.play()\n        }\n        else if let firstItem = playerQueue?.items().first {\n            playerQueue?.pause()\n            playerQueue?.removeAllItems()\n            playerQueue = AVQueuePlayer(items: [firstItem])\n            playerQueue?.play()\n            playerQueue?.volume = 0.5\n        }\n    }\n\n    func didSlideSlider(_ value: Float) {\n        player?.volume = value\n    }\n}\n\nextension PlaybackPresenter: PlayerDataSource {\n    var songName: String? {\n        return currentTrack?.name\n    }\n\n    var subtitle: String? {\n        return currentTrack?.artists.first?.name\n    }\n\n    var imageURL: URL? {\n        return URL(string: currentTrack?.album?.images.first?.url ?? \"\")\n    }\n}\n"
  },
  {
    "path": "Spotify/Resources/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\n@main\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n\n        let window = UIWindow(frame: UIScreen.main.bounds)\n\n        if AuthManager.shared.isSignedIn {\n            AuthManager.shared.refreshIfNeeded(completion: nil)\n            window.rootViewController = TabBarViewController()\n        }\n        else {\n            let navVC = UINavigationController(rootViewController: WelcomeViewController())\n            navVC.navigationBar.prefersLargeTitles = true\n            navVC.viewControllers.first?.navigationItem.largeTitleDisplayMode = .always\n            window.rootViewController = navVC\n        }\n\n        window.makeKeyAndVisible()\n        self.window = window\n\n        return true\n    }\n\n    // MARK: UISceneSession Lifecycle\n\n    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {\n        // Called when a new scene session is being created.\n        // Use this method to select a configuration to create the new scene with.\n        return UISceneConfiguration(name: \"Default Configuration\", sessionRole: connectingSceneSession.role)\n    }\n\n    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {\n        // Called when the user discards a scene session.\n        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.\n        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Spotify/Resources/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Spotify/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"notification-icon@2x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"notification-icon@3x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"icon-small.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"1x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"icon-small@2x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"icon-small@3x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"icon-40@2x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"icon-40@3x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"icon.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"1x\",\n      \"size\" : \"57x57\"\n    },\n    {\n      \"filename\" : \"icon@2x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"57x57\"\n    },\n    {\n      \"filename\" : \"icon-60@2x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"60x60\"\n    },\n    {\n      \"filename\" : \"icon-60@3x.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"60x60\"\n    },\n    {\n      \"filename\" : \"notification-icon~ipad.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"notification-icon~ipad@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"icon-small.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"icon-small@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"icon-40.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"icon-40@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"icon-small-50.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"50x50\"\n    },\n    {\n      \"filename\" : \"icon-small-50@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"50x50\"\n    },\n    {\n      \"filename\" : \"icon-72.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"72x72\"\n    },\n    {\n      \"filename\" : \"icon-72@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"72x72\"\n    },\n    {\n      \"filename\" : \"icon-76.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"76x76\"\n    },\n    {\n      \"filename\" : \"icon-76@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"76x76\"\n    },\n    {\n      \"filename\" : \"icon-83.5@2x.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"83.5x83.5\"\n    },\n    {\n      \"filename\" : \"ios-marketing.png\",\n      \"idiom\" : \"ios-marketing\",\n      \"scale\" : \"1x\",\n      \"size\" : \"1024x1024\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Spotify/Resources/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Spotify/Resources/Assets.xcassets/albums_background.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"albums.jpg\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Spotify/Resources/Assets.xcassets/logo.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"logo.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Spotify/Resources/Extensions.swift",
    "content": "//\n//  Extensions.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport Foundation\nimport UIKit\n\nextension UIView {\n    var width: CGFloat {\n        return frame.size.width\n    }\n\n    var height: CGFloat {\n        return frame.size.height\n    }\n\n    var left: CGFloat {\n        return frame.origin.x\n    }\n\n    var right: CGFloat {\n        return left + width\n    }\n\n    var top: CGFloat {\n        return frame.origin.y\n    }\n\n    var bottom: CGFloat {\n        return top + height\n    }\n}\n\nextension DateFormatter {\n    static let dateFormatter: DateFormatter = {\n        let dateFormatter = DateFormatter()\n        dateFormatter.dateFormat = \"YYYY-MM-dd\"\n        return dateFormatter\n    }()\n\n    static let displayDateFormatter: DateFormatter = {\n        let dateFormatter = DateFormatter()\n        dateFormatter.dateStyle = .medium\n        return dateFormatter\n    }()\n}\n\nextension String {\n    static func formattedDate(string: String) -> String {\n        guard let date = DateFormatter.dateFormatter.date(from: string) else {\n            return string\n        }\n        return DateFormatter.displayDateFormatter.string(from: date)\n    }\n}\n\nextension Notification.Name {\n    static let albumSavedNotification = Notification.Name(\"albumSavedNotification\")\n}\n"
  },
  {
    "path": "Spotify/Resources/SceneDelegate.swift",
    "content": "//\n//  SceneDelegate.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/14/21.\n//\n\nimport UIKit\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n    var window: UIWindow?\n\n\n    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n        guard let windowScene = (scene as? UIWindowScene) else { return }\n\n        let window = UIWindow(windowScene: windowScene)\n\n        if AuthManager.shared.isSignedIn {\n            window.rootViewController = TabBarViewController()\n        }\n        else {\n            let navVC = UINavigationController(rootViewController: WelcomeViewController())\n            navVC.navigationBar.prefersLargeTitles = true\n            navVC.viewControllers.first?.navigationItem.largeTitleDisplayMode = .always\n            window.rootViewController = navVC\n        }\n\n        window.makeKeyAndVisible()\n        self.window = window\n    }\n\n    func sceneDidDisconnect(_ scene: UIScene) {\n        // Called as the scene is being released by the system.\n        // This occurs shortly after the scene enters the background, or when its session is discarded.\n        // Release any resources associated with this scene that can be re-created the next time the scene connects.\n        // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).\n    }\n\n    func sceneDidBecomeActive(_ scene: UIScene) {\n        // Called when the scene has moved from an inactive state to an active state.\n        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n    }\n\n    func sceneWillResignActive(_ scene: UIScene) {\n        // Called when the scene will move from an active state to an inactive state.\n        // This may occur due to temporary interruptions (ex. an incoming phone call).\n    }\n\n    func sceneWillEnterForeground(_ scene: UIScene) {\n        // Called as the scene transitions from the background to the foreground.\n        // Use this method to undo the changes made on entering the background.\n    }\n\n    func sceneDidEnterBackground(_ scene: UIScene) {\n        // Called as the scene transitions from the foreground to the background.\n        // Use this method to save data, release shared resources, and store enough scene-specific state information\n        // to restore the scene back to its current state.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Spotify/ViewModels/AlbumCollectionViewCellViewModel.swift",
    "content": "//\n//  AlbumCollectionViewCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\n\nstruct AlbumCollectionViewCellViewModel {\n    let name: String\n    let artistName: String\n}\n"
  },
  {
    "path": "Spotify/ViewModels/CategoryCollectionViewCellViewModel.swift",
    "content": "//\n//  CategoryCollectionViewCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\n\nstruct CategoryCollectionViewCellViewModel {\n    let title: String\n    let artworkURL: URL?\n}\n"
  },
  {
    "path": "Spotify/ViewModels/FeaturedPlaylistCellViewModel.swift",
    "content": "//\n//  FeaturedPlaylistCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct FeaturedPlaylistCellViewModel {\n    let name: String\n    let artworkURL: URL?\n    let creatorName: String\n}\n"
  },
  {
    "path": "Spotify/ViewModels/NewReleasesCellViewModel.swift",
    "content": "//\n//  NewReleasesCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct NewReleasesCellViewModel {\n    let name: String\n    let artworkURL: URL?\n    let numberOfTracks: Int\n    let artistName: String\n}\n"
  },
  {
    "path": "Spotify/ViewModels/PlaylistHeaderViewViewModel.swift",
    "content": "//\n//  PlaylistHeaderViewViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/18/21.\n//\n\nimport Foundation\n\nstruct PlaylistHeaderViewViewModel {\n    let name: String?\n    let ownerName: String?\n    let description: String?\n    let artworkURL: URL?\n}\n"
  },
  {
    "path": "Spotify/ViewModels/RecommendedTrackCellViewModel.swift",
    "content": "//\n//  RecommendedTrackCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport Foundation\n\nstruct RecommendedTrackCellViewModel {\n    let name: String\n    let artistName: String\n    let artworkURL: URL?\n}\n"
  },
  {
    "path": "Spotify/ViewModels/SearchResultDefaultTableViewCellViewModel.swift",
    "content": "//\n//  SearchResultDefaultTableViewCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport Foundation\n\nstruct SearchResultDefaultTableViewCellViewModel {\n    let title: String\n    let imageURL: URL?\n}\n"
  },
  {
    "path": "Spotify/ViewModels/SearchResultSubtitleTableViewCellViewModel.swift",
    "content": "//\n//  SearchResultSubtitleTableViewCellViewModel.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport Foundation\n\nstruct SearchResultSubtitleTableViewCellViewModel {\n    let title: String\n    let subtitle: String\n    let imageURL: URL?\n}\n"
  },
  {
    "path": "Spotify/Views/ActionLabelView.swift",
    "content": "//\n//  ActionLabelView.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport UIKit\n\nstruct ActionLabelViewViewModel {\n    let text: String\n    let actionTitle: String\n}\n\nprotocol ActionLabelViewDelegate: AnyObject {\n    func actionLabelViewDidTapButton(_ actionView: ActionLabelView)\n}\n\nclass ActionLabelView: UIView {\n\n    weak var delegate: ActionLabelViewDelegate?\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.textAlignment = .center\n        label.numberOfLines = 0\n        label.textColor = .secondaryLabel\n        return label\n    }()\n\n    private let button: UIButton = {\n        let button = UIButton()\n        button.setTitleColor(.link, for: .normal)\n        return button\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        clipsToBounds = true\n        isHidden = true\n        addSubview(button)\n        addSubview(label)\n        button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    @objc func didTapButton() {\n        delegate?.actionLabelViewDidTapButton(self)\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        button.frame = CGRect(x: 0, y: height-40, width: width, height: 40)\n        label.frame = CGRect(x: 0, y: 0, width: width, height: height-45)\n    }\n\n    func configure(with viewModel: ActionLabelViewViewModel) {\n        label.text = viewModel.text\n        button.setTitle(viewModel.actionTitle, for: .normal)\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/AlbumTrackCollectionViewCell.swift",
    "content": "//\n//  AlbumTrackCollectionViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport Foundation\nimport UIKit\n\nclass AlbumTrackCollectionViewCell: UICollectionViewCell {\n    static let identifier = \"AlbumTrackCollectionViewCell\"\n\n    private let trackNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 18, weight: .regular)\n        return label\n    }()\n\n    private let artistNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 15, weight: .thin)\n        return label\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        backgroundColor = .secondarySystemBackground\n        contentView.backgroundColor = .secondarySystemBackground\n        contentView.addSubview(trackNameLabel)\n        contentView.addSubview(artistNameLabel)\n        contentView.clipsToBounds = true\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        trackNameLabel.frame = CGRect(\n            x: 10,\n            y: 0,\n            width: contentView.width-15,\n            height: contentView.height/2\n        )\n        artistNameLabel.frame = CGRect(\n            x: 10,\n            y: contentView.height/2,\n            width: contentView.width-15,\n            height: contentView.height/2\n        )\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        trackNameLabel.text = nil\n        artistNameLabel.text = nil\n    }\n\n    func configure(with viewModel: AlbumCollectionViewCellViewModel) {\n        trackNameLabel.text = viewModel.name\n        artistNameLabel.text = viewModel.artistName\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"17701\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"17703\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"scaleAspectFit\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"logo\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GZl-O4-dz5\">\n                                <rect key=\"frame\" x=\"107\" y=\"348\" width=\"200\" height=\"200\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"200\" id=\"YCC-oB-q6z\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"200\" id=\"cre-ZN-wyv\"/>\n                                </constraints>\n                            </imageView>\n                        </subviews>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                        <color key=\"backgroundColor\" white=\"0.056141548416241471\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                        <constraints>\n                            <constraint firstItem=\"GZl-O4-dz5\" firstAttribute=\"centerX\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerX\" id=\"66X-a6-Xpo\"/>\n                            <constraint firstItem=\"GZl-O4-dz5\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerY\" id=\"qrk-Zs-bAe\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"logo\" width=\"150\" height=\"150\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Spotify/Views/Browse/FeaturedPlaylistCollectionViewCell.swift",
    "content": "//\n//  FeaturedPlaylistCollectionViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport UIKit\n\nclass FeaturedPlaylistCollectionViewCell: UICollectionViewCell {\n    static let identifier = \"FeaturedPlaylistCollectionViewCell\"\n\n    private let playlistCoverImageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.layer.masksToBounds = true\n        imageView.layer.cornerRadius = 4\n        imageView.image = UIImage(systemName: \"photo\")\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    private let playlistNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.textAlignment = .center\n        label.font = .systemFont(ofSize: 18, weight: .regular)\n        return label\n    }()\n\n    private let creatorNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.textAlignment = .center\n        label.font = .systemFont(ofSize: 15, weight: .thin)\n        return label\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        contentView.addSubview(playlistCoverImageView)\n        contentView.addSubview(playlistNameLabel)\n        contentView.addSubview(creatorNameLabel)\n        contentView.clipsToBounds = true\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        creatorNameLabel.frame = CGRect(\n            x: 3,\n            y: contentView.height-30,\n            width: contentView.width-6,\n            height: 30\n        )\n        playlistNameLabel.frame = CGRect(\n            x: 3,\n            y: contentView.height-60,\n            width: contentView.width-6,\n            height: 30\n        )\n        let imageSize = contentView.height-70\n        playlistCoverImageView.frame = CGRect(\n            x: (contentView.width-imageSize)/2,\n            y: 3,\n            width: imageSize,\n            height: imageSize\n        )\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        playlistNameLabel.text = nil\n        playlistCoverImageView.image = nil\n        creatorNameLabel.text = nil\n    }\n\n    func configure(with viewModel: FeaturedPlaylistCellViewModel) {\n        playlistNameLabel.text = viewModel.name\n        playlistCoverImageView.sd_setImage(with: viewModel.artworkURL, completed: nil)\n        creatorNameLabel.text = viewModel.creatorName\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/Browse/NewReleaseCollectionViewCell.swift",
    "content": "//\n//  NewReleaseCollectionViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport UIKit\nimport SDWebImage\n\nclass NewReleaseCollectionViewCell: UICollectionViewCell {\n    static let identifier = \"NewReleaseCollectionViewCell\"\n\n    private let albumCoverImageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.image = UIImage(systemName: \"photo\")\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    private let albumNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 20, weight: .semibold)\n        return label\n    }()\n\n    private let numberOfTracksLabel: UILabel = {\n        let label = UILabel()\n        label.font = .systemFont(ofSize: 18, weight: .thin)\n        label.numberOfLines = 0\n        return label\n    }()\n\n    private let artistNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 18, weight: .light)\n        return label\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        contentView.backgroundColor = .secondarySystemBackground\n        contentView.addSubview(albumCoverImageView)\n        contentView.addSubview(albumNameLabel)\n        contentView.addSubview(artistNameLabel)\n        contentView.clipsToBounds = true\n        contentView.addSubview(numberOfTracksLabel)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        let imageSize: CGFloat = contentView.height-10\n        let albumLabelSize = albumNameLabel.sizeThatFits(\n            CGSize(\n                width: contentView.width-imageSize-10,\n                height: contentView.height-10\n            )\n        )\n        artistNameLabel.sizeToFit()\n        numberOfTracksLabel.sizeToFit()\n\n        // Image\n        albumCoverImageView.frame = CGRect(x: 5, y: 5, width: imageSize, height: imageSize)\n\n        // Album name label\n        let albumLabelHeight = min(60, albumLabelSize.height)\n        albumNameLabel.frame = CGRect(\n            x: albumCoverImageView.right+10,\n            y: 5,\n            width: albumLabelSize.width,\n            height: albumLabelHeight\n        )\n\n        artistNameLabel.frame = CGRect(\n            x: albumCoverImageView.right+10,\n            y: albumNameLabel.bottom,\n            width: contentView.width - albumCoverImageView.right-10,\n            height: 30\n        )\n\n        numberOfTracksLabel.frame = CGRect(\n            x: albumCoverImageView.right+10,\n            y: contentView.bottom-44,\n            width: numberOfTracksLabel.width,\n            height: 44\n        )\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        albumNameLabel.text = nil\n        artistNameLabel.text = nil\n        numberOfTracksLabel.text = nil\n        albumCoverImageView.image = nil\n    }\n\n    func configure(with viewModel: NewReleasesCellViewModel) {\n        albumNameLabel.text = viewModel.name\n        artistNameLabel.text = viewModel.artistName\n        numberOfTracksLabel.text = \"Tracks: \\(viewModel.numberOfTracks)\"\n        albumCoverImageView.sd_setImage(with: viewModel.artworkURL, completed: nil)\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/Browse/RecommendedTrackCollectionViewCell.swift",
    "content": "//\n//  RecommendedTrackCollectionViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/15/21.\n//\n\nimport UIKit\n\nclass RecommendedTrackCollectionViewCell: UICollectionViewCell {\n    static let identifier = \"RecommendedTrackCollectionViewCell\"\n\n    private let albumCoverImageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.image = UIImage(systemName: \"photo\")\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    private let trackNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 18, weight: .regular)\n        return label\n    }()\n\n    private let artistNameLabel: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 0\n        label.font = .systemFont(ofSize: 15, weight: .thin)\n        return label\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        backgroundColor = .secondarySystemBackground\n        contentView.backgroundColor = .secondarySystemBackground\n        contentView.addSubview(albumCoverImageView)\n        contentView.addSubview(trackNameLabel)\n        contentView.addSubview(artistNameLabel)\n        contentView.clipsToBounds = true\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        albumCoverImageView.frame = CGRect(x: 5, y: 2, width: contentView.height-4, height: contentView.height-4)\n        trackNameLabel.frame = CGRect(\n            x: albumCoverImageView.right+10,\n            y: 0,\n            width: contentView.width-albumCoverImageView.right-15,\n            height: contentView.height/2\n        )\n        artistNameLabel.frame = CGRect(\n            x: albumCoverImageView.right+10,\n            y: contentView.height/2,\n            width: contentView.width-albumCoverImageView.right-15,\n            height: contentView.height/2\n        )\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        trackNameLabel.text = nil\n        albumCoverImageView.image = nil\n        artistNameLabel.text = nil\n    }\n\n    func configure(with viewModel: RecommendedTrackCellViewModel) {\n        trackNameLabel.text = viewModel.name\n        albumCoverImageView.sd_setImage(with: viewModel.artworkURL, completed: nil)\n        artistNameLabel.text = viewModel.artistName\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/GenreCollectionViewCell.swift",
    "content": "//\n//  CategoryCollectionViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport UIKit\nimport SDWebImage\n\nclass CategoryCollectionViewCell: UICollectionViewCell {\n    static let identifier = \"CategoryCollectionViewCell\"\n\n    private let imageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFit\n        imageView.tintColor = .white\n        imageView.image = UIImage(systemName: \"music.quarternote.3\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .regular))\n        return imageView\n    }()\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.textColor = .white\n        label.font = .systemFont(ofSize: 22, weight: .semibold)\n        return label\n    }()\n\n    private let colors: [UIColor] = [\n        .systemPink,\n        .systemBlue,\n        .systemPurple,\n        .systemOrange,\n        .systemGreen,\n        .systemRed,\n        .systemYellow,\n        .darkGray,\n        .systemTeal\n    ]\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        contentView.layer.cornerRadius = 8\n        contentView.layer.masksToBounds = true\n        contentView.addSubview(label)\n        contentView.addSubview(imageView)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        label.text = nil\n        imageView.image = UIImage(systemName: \"music.quarternote.3\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .regular))\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n\n        label.frame = CGRect(x: 10, y: contentView.height/2, width: contentView.width-20, height: contentView.height/2)\n        imageView.frame = CGRect(x: contentView.width/2, y: 10, width: contentView.width/2, height: contentView.height/2)\n    }\n\n    func configure(with viewModel: CategoryCollectionViewCellViewModel) {\n        label.text = viewModel.title\n        imageView.sd_setImage(with: viewModel.artworkURL, completed: nil)\n        contentView.backgroundColor = colors.randomElement()\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/LibraryToggleView.swift",
    "content": "//\n//  LibraryToggleView.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/21/21.\n//\n\nimport UIKit\n\nprotocol LibraryToggleViewDelegate: AnyObject {\n    func libraryToggleViewDidTapPlaylists(_ toggleView: LibraryToggleView)\n    func libraryToggleViewDidTapAlbums(_ toggleView: LibraryToggleView)\n}\n\nclass LibraryToggleView: UIView {\n\n    enum State {\n        case playlist\n        case album\n    }\n\n    var state: State = .playlist\n\n    weak var delegate: LibraryToggleViewDelegate?\n\n    private let playlistButton: UIButton = {\n        let button = UIButton()\n        button.setTitleColor(.label, for: .normal)\n        button.setTitle(\"Playlists\", for: .normal)\n        return button\n    }()\n\n    private let albumsButton: UIButton = {\n        let button = UIButton()\n        button.setTitleColor(.label, for: .normal)\n        button.setTitle(\"Albums\", for: .normal)\n        return button\n    }()\n\n    private let indicatorView: UIView = {\n        let view = UIView()\n        view.backgroundColor = .systemGreen\n        view.layer.masksToBounds = true\n        view.layer.cornerRadius = 4\n        return view\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        addSubview(playlistButton)\n        addSubview(albumsButton)\n        addSubview(indicatorView)\n        playlistButton.addTarget(self, action: #selector(didTapPlaylists), for: .touchUpInside)\n        albumsButton.addTarget(self, action: #selector(didTapAlbums), for: .touchUpInside)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    @objc private func didTapPlaylists() {\n        state = .playlist\n        UIView.animate(withDuration: 0.2) {\n            self.layoutIndicator()\n        }\n        delegate?.libraryToggleViewDidTapPlaylists(self)\n    }\n\n    @objc private func didTapAlbums() {\n        state = .album\n        UIView.animate(withDuration: 0.2) {\n            self.layoutIndicator()\n        }\n        delegate?.libraryToggleViewDidTapAlbums(self)\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        playlistButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40)\n        albumsButton.frame = CGRect(x: playlistButton.right, y: 0, width: 100, height: 40)\n        layoutIndicator()\n    }\n\n    func layoutIndicator() {\n        switch state {\n        case .playlist:\n            indicatorView.frame = CGRect(\n                x: 0,\n                y: playlistButton.bottom,\n                width: 100,\n                height: 3\n            )\n        case .album:\n            indicatorView.frame = CGRect(\n                x: 100,\n                y: playlistButton.bottom,\n                width: 100,\n                height: 3\n            )\n        }\n    }\n\n    func update(for state: State) {\n        self.state = state\n        UIView.animate(withDuration: 0.2) {\n            self.layoutIndicator()\n        }\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/PlayerControlsView.swift",
    "content": "//\n//  PlayerControlsView.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport Foundation\nimport UIKit\n\nprotocol PlayerControlsViewDelegate: AnyObject {\n    func playerControlsViewDidTapPlayPauseButton(_ playerControlsView: PlayerControlsView)\n    func playerControlsViewDidTapForwardButton(_ playerControlsView: PlayerControlsView)\n    func playerControlsViewDidTapBackwardsButton(_ playerControlsView: PlayerControlsView)\n    func playerControlsView(_ playerControlsView: PlayerControlsView, didSlideSlider value: Float)\n}\n\nstruct PlayerControlsViewViewModel {\n    let title: String?\n    let subtitle: String?\n}\n\nfinal class PlayerControlsView: UIView {\n\n    private var isPlaying = true\n\n    weak var delegate: PlayerControlsViewDelegate?\n\n    private let volumeSlider: UISlider = {\n        let slider = UISlider()\n        slider.value = 0.5\n        return slider\n    }()\n\n    private let nameLabel: UILabel = {\n        let label = UILabel()\n        label.text = \"This Is My Song\"\n        label.numberOfLines = 1\n        label.font = .systemFont(ofSize: 20, weight: .semibold)\n        return label\n    }()\n\n    private let subtitleLabel: UILabel = {\n        let label = UILabel()\n        label.text = \"Drake (feat. Some Other Artist)\"\n        label.numberOfLines = 1\n        label.font = .systemFont(ofSize: 18, weight: .regular)\n        label.textColor = .secondaryLabel\n        return label\n    }()\n\n    private let backButton: UIButton = {\n        let button = UIButton()\n        button.tintColor = .label\n        let image = UIImage(systemName: \"backward.fill\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))\n        button.setImage(image, for: .normal)\n        return button\n    }()\n\n    private let nextButton: UIButton = {\n        let button = UIButton()\n        button.tintColor = .label\n        let image = UIImage(systemName: \"forward.fill\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))\n        button.setImage(image, for: .normal)\n        return button\n    }()\n\n    private let playPauseButton: UIButton = {\n        let button = UIButton()\n        button.tintColor = .label\n        let image = UIImage(systemName: \"pause\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))\n        button.setImage(image, for: .normal)\n        return button\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        backgroundColor = .clear\n        addSubview(nameLabel)\n        addSubview(subtitleLabel)\n\n        addSubview(volumeSlider)\n        volumeSlider.addTarget(self, action: #selector(didSlideSlider(_:)), for: .valueChanged)\n\n        addSubview(backButton)\n        addSubview(nextButton)\n        addSubview(playPauseButton)\n\n        backButton.addTarget(self, action: #selector(didTapBack), for: .touchUpInside)\n        nextButton.addTarget(self, action: #selector(didTapNext), for: .touchUpInside)\n        playPauseButton.addTarget(self, action: #selector(didTapPlayPause), for: .touchUpInside)\n\n        clipsToBounds = true\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    @objc func didSlideSlider(_ slider: UISlider) {\n        let value = slider.value\n        delegate?.playerControlsView(self, didSlideSlider: value)\n    }\n\n    @objc private func didTapBack() {\n        delegate?.playerControlsViewDidTapBackwardsButton(self)\n    }\n\n    @objc private func didTapNext() {\n        delegate?.playerControlsViewDidTapForwardButton(self)\n    }\n\n    @objc private func didTapPlayPause() {\n        self.isPlaying = !isPlaying\n        delegate?.playerControlsViewDidTapPlayPauseButton(self)\n\n        // Update icon\n        let pause = UIImage(systemName: \"pause\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))\n        let play = UIImage(systemName: \"play.fill\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))\n\n        playPauseButton.setImage(isPlaying ? pause : play, for: .normal)\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        nameLabel.frame = CGRect(x: 0, y: 0, width: width, height: 50)\n        subtitleLabel.frame = CGRect(x: 0, y: nameLabel.bottom+10, width: width, height: 50)\n\n        volumeSlider.frame = CGRect(x: 10, y: subtitleLabel.bottom+20, width: width-20, height: 44)\n\n        let buttonSize: CGFloat = 60\n        playPauseButton.frame = CGRect(x: (width - buttonSize)/2, y: volumeSlider.bottom + 30, width: buttonSize, height: buttonSize)\n        backButton.frame = CGRect(x: playPauseButton.left-80-buttonSize, y: playPauseButton.top, width: buttonSize, height: buttonSize)\n        nextButton.frame = CGRect(x: playPauseButton.right+80, y: playPauseButton.top, width: buttonSize, height: buttonSize)\n    }\n\n    func configure(with viewModel: PlayerControlsViewViewModel) {\n        nameLabel.text = viewModel.title\n        subtitleLabel.text = viewModel.subtitle\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/PlaylistHeaderCollectionReusableView.swift",
    "content": "//\n//  PlaylistHeaderCollectionReusableView.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/18/21.\n//\n\nimport SDWebImage\nimport UIKit\n\nprotocol PlaylistHeaderCollectionReusableViewDelegate: AnyObject {\n    func playlistHeaderCollectionReusableViewDidTapPlayAll(_ header: PlaylistHeaderCollectionReusableView)\n}\n\nfinal class PlaylistHeaderCollectionReusableView: UICollectionReusableView {\n    static let identifier = \"PlaylistHeaderCollectionReusableView\"\n\n    weak var delegate: PlaylistHeaderCollectionReusableViewDelegate?\n\n    private let nameLabel: UILabel = {\n        let label = UILabel()\n        label.font = .systemFont(ofSize: 22, weight: .semibold)\n        return label\n    }()\n\n    private let descriptionLabel: UILabel = {\n        let label = UILabel()\n        label.textColor = .secondaryLabel\n        label.font = .systemFont(ofSize: 18, weight: .regular)\n        label.numberOfLines = 0\n        return label\n    }()\n\n    private let ownerLabel: UILabel = {\n        let label = UILabel()\n        label.textColor = .secondaryLabel\n        label.font = .systemFont(ofSize: 18, weight: .light)\n        return label\n    }()\n\n    private let imageView: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFill\n        imageView.image = UIImage(systemName: \"photo\")\n        return imageView\n    }()\n\n    private let playAllButton: UIButton = {\n        let button = UIButton()\n        button.backgroundColor = .systemGreen\n        let image = UIImage(systemName: \"play.fill\", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .regular))\n        button.setImage(image, for: .normal)\n        button.tintColor = .white\n        button.layer.cornerRadius = 30\n        button.layer.masksToBounds = true\n        return button\n    }()\n\n    // MARK: - Init\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        backgroundColor = .systemBackground\n        addSubview(imageView)\n        addSubview(nameLabel)\n        addSubview(descriptionLabel)\n        addSubview(ownerLabel)\n        addSubview(playAllButton)\n        playAllButton.addTarget(self, action: #selector(didTapPlayAll), for: .touchUpInside)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    @objc private func didTapPlayAll() {\n        delegate?.playlistHeaderCollectionReusableViewDidTapPlayAll(self)\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        let imageSize: CGFloat = height/1.8\n        imageView.frame = CGRect(x: (width-imageSize)/2, y: 20, width: imageSize, height: imageSize)\n\n        nameLabel.frame = CGRect(x: 10, y: imageView.bottom, width: width-20, height: 44)\n        descriptionLabel.frame = CGRect(x: 10, y: nameLabel.bottom, width: width-20, height: 44)\n        ownerLabel.frame = CGRect(x: 10, y: descriptionLabel.bottom, width: width-20, height: 44)\n\n        playAllButton.frame = CGRect(x: width-80, y: height-80, width: 60, height: 60)\n    }\n\n    func configure(with viewModel: PlaylistHeaderViewViewModel) {\n        nameLabel.text = viewModel.name\n        ownerLabel.text = viewModel.ownerName\n        descriptionLabel.text = viewModel.description\n        imageView.sd_setImage(with: viewModel.artworkURL, placeholderImage: UIImage(systemName: \"photo\"), completed: nil)\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/SearchResultCells/SearchResultDefaultTableViewCell.swift",
    "content": "//\n//  SearchResultDefaultTableViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport UIKit\nimport SDWebImage\n\nclass SearchResultDefaultTableViewCell: UITableViewCell {\n    static let identfier = \"SearchResultDefaultTableViewCell\"\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 1\n        return label\n    }()\n\n    private let iconImageViewe: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {\n        super.init(style: style, reuseIdentifier: reuseIdentifier)\n        contentView.addSubview(label)\n        contentView.addSubview(iconImageViewe)\n        contentView.clipsToBounds = true\n        accessoryType = .disclosureIndicator\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        let imageSize: CGFloat = contentView.height-10\n        iconImageViewe.frame = CGRect(\n            x: 10,\n            y: 5,\n            width: imageSize,\n            height: imageSize\n        )\n        iconImageViewe.layer.cornerRadius = imageSize/2\n        iconImageViewe.layer.masksToBounds = true\n        label.frame = CGRect(x: iconImageViewe.right+10, y: 0, width: contentView.width-iconImageViewe.right-15, height: contentView.height)\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        iconImageViewe.image = nil\n        label.text = nil\n    }\n\n    func configure(with viewModel: SearchResultDefaultTableViewCellViewModel) {\n        label.text = viewModel.title\n        iconImageViewe.sd_setImage(with: viewModel.imageURL, completed: nil)\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/SearchResultCells/SearchResultSubtitleTableViewCell.swift",
    "content": "//\n//  SearchResultSubtitleTableViewCell.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/20/21.\n//\n\nimport UIKit\nimport SDWebImage\n\nclass SearchResultSubtitleTableViewCell: UITableViewCell {\n    static let identfier = \"SearchResultSubtitleTableViewCell\"\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.numberOfLines = 1\n        return label\n    }()\n\n    private let subtitleLabel: UILabel = {\n        let label = UILabel()\n        label.textColor = .secondaryLabel\n        label.numberOfLines = 1\n        return label\n    }()\n\n    private let iconImageViewe: UIImageView = {\n        let imageView = UIImageView()\n        imageView.contentMode = .scaleAspectFill\n        return imageView\n    }()\n\n    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {\n        super.init(style: style, reuseIdentifier: reuseIdentifier)\n        contentView.addSubview(label)\n        contentView.addSubview(subtitleLabel)\n        contentView.addSubview(iconImageViewe)\n        contentView.clipsToBounds = true\n        accessoryType = .disclosureIndicator\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        let imageSize: CGFloat = contentView.height-10\n        iconImageViewe.frame = CGRect(\n            x: 10,\n            y: 5,\n            width: imageSize,\n            height: imageSize\n        )\n        let labelHeight = contentView.height/2\n        label.frame = CGRect(\n            x: iconImageViewe.right+10,\n            y: 0,\n            width: contentView.width-iconImageViewe.right-15,\n            height: labelHeight\n        )\n\n        subtitleLabel.frame = CGRect(\n            x: iconImageViewe.right+10,\n            y: label.bottom,\n            width: contentView.width-iconImageViewe.right-15,\n            height: labelHeight\n        )\n    }\n\n    override func prepareForReuse() {\n        super.prepareForReuse()\n        iconImageViewe.image = nil\n        label.text = nil\n        subtitleLabel.text = nil\n    }\n\n    func configure(with viewModel: SearchResultSubtitleTableViewCellViewModel) {\n        label.text = viewModel.title\n        subtitleLabel.text = viewModel.subtitle\n        iconImageViewe.sd_setImage(with: viewModel.imageURL, placeholderImage: UIImage(systemName: \"photo\"), completed: nil)\n    }\n}\n"
  },
  {
    "path": "Spotify/Views/TitleHeaderCollectionReusableView.swift",
    "content": "//\n//  TitleHeaderCollectionReusableView.swift\n//  Spotify\n//\n//  Created by Afraz Siddiqui on 2/19/21.\n//\n\nimport UIKit\n\nclass TitleHeaderCollectionReusableView: UICollectionReusableView {\n    static let identifier = \"TitleHeaderCollectionReusableView\"\n\n    private let label: UILabel = {\n        let label = UILabel()\n        label.textColor = .label\n        label.numberOfLines = 1\n        label.font = .systemFont(ofSize: 22, weight: .regular)\n        return label\n    }()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        backgroundColor = .systemBackground\n        addSubview(label)\n    }\n\n    required init?(coder: NSCoder) {\n        fatalError()\n    }\n\n    override func layoutSubviews() {\n        super.layoutSubviews()\n        label.frame = CGRect(x: 15, y: 0, width: width-30, height: height)\n    }\n\n    func configure(with title: String) {\n        label.text = title\n    }\n}\n"
  },
  {
    "path": "Spotify.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t8305D6E626E172CE006C162D /* SpotifyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8305D6E526E172CE006C162D /* SpotifyTests.swift */; };\n\t\t8309BFC325E0555500767482 /* AllCategoriesResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8309BFC225E0555500767482 /* AllCategoriesResponse.swift */; };\n\t\t8309BFC625E0582300767482 /* CategoryCollectionViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8309BFC525E0582300767482 /* CategoryCollectionViewCellViewModel.swift */; };\n\t\t8309BFC925E058F700767482 /* CategoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8309BFC825E058F700767482 /* CategoryViewController.swift */; };\n\t\t8309C02C25E082E300767482 /* SearchResultResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8309C02B25E082E300767482 /* SearchResultResponse.swift */; };\n\t\t8309C03025E083DF00767482 /* SearchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8309C02F25E083DF00767482 /* SearchResult.swift */; };\n\t\t830A09E925E1ABBF00D37663 /* SearchResultDefaultTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09E825E1ABBF00D37663 /* SearchResultDefaultTableViewCell.swift */; };\n\t\t830A09EC25E1ACEA00D37663 /* SearchResultDefaultTableViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09EB25E1ACEA00D37663 /* SearchResultDefaultTableViewCellViewModel.swift */; };\n\t\t830A09EF25E1AEE400D37663 /* SearchResultSubtitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09EE25E1AEE400D37663 /* SearchResultSubtitleTableViewCell.swift */; };\n\t\t830A09F225E1AF8B00D37663 /* SearchResultSubtitleTableViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09F125E1AF8B00D37663 /* SearchResultSubtitleTableViewCellViewModel.swift */; };\n\t\t830A09F625E1B2D000D37663 /* PlaybackPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09F525E1B2D000D37663 /* PlaybackPresenter.swift */; };\n\t\t830A09FA25E1B72E00D37663 /* PlayerControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830A09F925E1B72E00D37663 /* PlayerControlsView.swift */; };\n\t\t8325981C25E01BA600A091F6 /* TitleHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325981B25E01BA600A091F6 /* TitleHeaderCollectionReusableView.swift */; };\n\t\t8325981F25E01F4900A091F6 /* AlbumTrackCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325981E25E01F4900A091F6 /* AlbumTrackCollectionViewCell.swift */; };\n\t\t8325982225E01FF300A091F6 /* AlbumCollectionViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325982125E01FF300A091F6 /* AlbumCollectionViewCellViewModel.swift */; };\n\t\t8325982525E0294D00A091F6 /* GenreCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325982425E0294D00A091F6 /* GenreCollectionViewCell.swift */; };\n\t\t834DA84325DAAD36003CF18B /* SettingsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA84225DAAD36003CF18B /* SettingsModels.swift */; };\n\t\t834DA85525DAD4A7003CF18B /* NewReleasesResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA85425DAD4A7003CF18B /* NewReleasesResponse.swift */; };\n\t\t834DA85825DAD574003CF18B /* APIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA85725DAD574003CF18B /* APIImage.swift */; };\n\t\t834DA85C25DAD73A003CF18B /* FeaturedPlaylistsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA85B25DAD73A003CF18B /* FeaturedPlaylistsResponse.swift */; };\n\t\t834DA85F25DADA39003CF18B /* RecommendedGenresResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA85E25DADA39003CF18B /* RecommendedGenresResponse.swift */; };\n\t\t834DA86225DADD41003CF18B /* RecommendationsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA86125DADD41003CF18B /* RecommendationsResponse.swift */; };\n\t\t834DA86625DAE8DE003CF18B /* NewReleaseCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA86525DAE8DE003CF18B /* NewReleaseCollectionViewCell.swift */; };\n\t\t834DA86A25DAE8F1003CF18B /* FeaturedPlaylistCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA86925DAE8F1003CF18B /* FeaturedPlaylistCollectionViewCell.swift */; };\n\t\t834DA86D25DAE908003CF18B /* RecommendedTrackCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA86C25DAE908003CF18B /* RecommendedTrackCollectionViewCell.swift */; };\n\t\t834DA87025DB0BED003CF18B /* NewReleasesCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA86F25DB0BED003CF18B /* NewReleasesCellViewModel.swift */; };\n\t\t834DA87325DB1904003CF18B /* FeaturedPlaylistCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA87225DB1904003CF18B /* FeaturedPlaylistCellViewModel.swift */; };\n\t\t834DA87625DB1942003CF18B /* RecommendedTrackCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA87525DB1942003CF18B /* RecommendedTrackCellViewModel.swift */; };\n\t\t834DA87925DB2FF7003CF18B /* AlbumViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA87825DB2FF7003CF18B /* AlbumViewController.swift */; };\n\t\t834DA87C25DB3235003CF18B /* AlbumDetailsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA87B25DB3235003CF18B /* AlbumDetailsResponse.swift */; };\n\t\t834DA87F25DB3528003CF18B /* PlaylistDetailsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834DA87E25DB3528003CF18B /* PlaylistDetailsResponse.swift */; };\n\t\t83962E3925D96D4400A0F09E /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E3825D96D4400A0F09E /* TabBarViewController.swift */; };\n\t\t83962E3D25D96D6200A0F09E /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E3C25D96D6200A0F09E /* SearchViewController.swift */; };\n\t\t83962E4025D96D7000A0F09E /* LibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E3F25D96D7000A0F09E /* LibraryViewController.swift */; };\n\t\t83962E4625D96D9400A0F09E /* AuthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E4525D96D9400A0F09E /* AuthViewController.swift */; };\n\t\t83962E4A25D96D9F00A0F09E /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E4925D96D9F00A0F09E /* WelcomeViewController.swift */; };\n\t\t83962E4D25D96DB000A0F09E /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E4C25D96DB000A0F09E /* SettingsViewController.swift */; };\n\t\t83962E5025D96DBB00A0F09E /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E4F25D96DBB00A0F09E /* ProfileViewController.swift */; };\n\t\t83962E5325D96DC500A0F09E /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E5225D96DC500A0F09E /* PlayerViewController.swift */; };\n\t\t83962E5625D96DD300A0F09E /* PlaylistViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E5525D96DD300A0F09E /* PlaylistViewController.swift */; };\n\t\t83962E5925D96DE600A0F09E /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E5825D96DE600A0F09E /* SearchResultsViewController.swift */; };\n\t\t83962E5C25D96E0400A0F09E /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E5B25D96E0400A0F09E /* AuthManager.swift */; };\n\t\t83962E5F25D96E1000A0F09E /* APICaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E5E25D96E1000A0F09E /* APICaller.swift */; };\n\t\t83962E6225D96E1E00A0F09E /* HapticsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E6125D96E1E00A0F09E /* HapticsManager.swift */; };\n\t\t83962E6525D96E3500A0F09E /* Playlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E6425D96E3500A0F09E /* Playlist.swift */; };\n\t\t83962E6825D96E4100A0F09E /* AudioTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E6725D96E4100A0F09E /* AudioTrack.swift */; };\n\t\t83962E6B25D96E4E00A0F09E /* Artist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E6A25D96E4E00A0F09E /* Artist.swift */; };\n\t\t83962E6E25D96E5800A0F09E /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83962E6D25D96E5800A0F09E /* UserProfile.swift */; };\n\t\t839BA20625D96C1500BA56A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839BA20525D96C1500BA56A5 /* AppDelegate.swift */; };\n\t\t839BA20825D96C1500BA56A5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839BA20725D96C1500BA56A5 /* SceneDelegate.swift */; };\n\t\t839BA20A25D96C1500BA56A5 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839BA20925D96C1500BA56A5 /* HomeViewController.swift */; };\n\t\t839BA20F25D96C1600BA56A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 839BA20E25D96C1600BA56A5 /* Assets.xcassets */; };\n\t\t839BA21225D96C1600BA56A5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 839BA21025D96C1600BA56A5 /* LaunchScreen.storyboard */; };\n\t\t83C02EA125DEA7D5009DC56A /* PlaylistHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C02EA025DEA7D5009DC56A /* PlaylistHeaderCollectionReusableView.swift */; };\n\t\t83C02EA425DEA97A009DC56A /* PlaylistHeaderViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C02EA325DEA97A009DC56A /* PlaylistHeaderViewViewModel.swift */; };\n\t\t83DAECA225D9751500A55E5A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DAECA125D9751500A55E5A /* Extensions.swift */; };\n\t\t83DAECA525D97DC300A55E5A /* AuthResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DAECA425D97DC300A55E5A /* AuthResponse.swift */; };\n\t\t83E7A16225E2BBE7007EF414 /* LibraryPlaylistsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A16125E2BBE7007EF414 /* LibraryPlaylistsViewController.swift */; };\n\t\t83E7A16625E2BC00007EF414 /* LibraryAlbumsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A16525E2BC00007EF414 /* LibraryAlbumsViewController.swift */; };\n\t\t83E7A16925E2BE0F007EF414 /* LibraryToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A16825E2BE0F007EF414 /* LibraryToggleView.swift */; };\n\t\t83E7A16C25E2C4C3007EF414 /* LibraryPlaylistsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A16B25E2C4C3007EF414 /* LibraryPlaylistsResponse.swift */; };\n\t\t83E7A16F25E2C5C0007EF414 /* ActionLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A16E25E2C5C0007EF414 /* ActionLabelView.swift */; };\n\t\t83E7A17225E3022F007EF414 /* LibraryAlbumsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E7A17125E3022F007EF414 /* LibraryAlbumsResponse.swift */; };\n\t\tB155E499983AD7C0E9CC2978 /* Pods_Spotify.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B58F92C4DA5A3AFC0EF74F2 /* Pods_Spotify.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t8305D6E726E172CE006C162D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 839BA1FA25D96C1500BA56A5 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 839BA20125D96C1500BA56A5;\n\t\t\tremoteInfo = Spotify;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t26823DE37DC5DC6B3B050E92 /* Pods-Spotify.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Spotify.release.xcconfig\"; path = \"Target Support Files/Pods-Spotify/Pods-Spotify.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t8305D6E326E172CE006C162D /* SpotifyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpotifyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t8305D6E526E172CE006C162D /* SpotifyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpotifyTests.swift; sourceTree = \"<group>\"; };\n\t\t8309BFC225E0555500767482 /* AllCategoriesResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllCategoriesResponse.swift; sourceTree = \"<group>\"; };\n\t\t8309BFC525E0582300767482 /* CategoryCollectionViewCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryCollectionViewCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t8309BFC825E058F700767482 /* CategoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryViewController.swift; sourceTree = \"<group>\"; };\n\t\t8309C02B25E082E300767482 /* SearchResultResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultResponse.swift; sourceTree = \"<group>\"; };\n\t\t8309C02F25E083DF00767482 /* SearchResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResult.swift; sourceTree = \"<group>\"; };\n\t\t830A09E825E1ABBF00D37663 /* SearchResultDefaultTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultDefaultTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t830A09EB25E1ACEA00D37663 /* SearchResultDefaultTableViewCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultDefaultTableViewCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t830A09EE25E1AEE400D37663 /* SearchResultSubtitleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultSubtitleTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t830A09F125E1AF8B00D37663 /* SearchResultSubtitleTableViewCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultSubtitleTableViewCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t830A09F525E1B2D000D37663 /* PlaybackPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackPresenter.swift; sourceTree = \"<group>\"; };\n\t\t830A09F925E1B72E00D37663 /* PlayerControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsView.swift; sourceTree = \"<group>\"; };\n\t\t8325981B25E01BA600A091F6 /* TitleHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleHeaderCollectionReusableView.swift; sourceTree = \"<group>\"; };\n\t\t8325981E25E01F4900A091F6 /* AlbumTrackCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumTrackCollectionViewCell.swift; sourceTree = \"<group>\"; };\n\t\t8325982125E01FF300A091F6 /* AlbumCollectionViewCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumCollectionViewCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t8325982425E0294D00A091F6 /* GenreCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenreCollectionViewCell.swift; sourceTree = \"<group>\"; };\n\t\t834DA84225DAAD36003CF18B /* SettingsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsModels.swift; sourceTree = \"<group>\"; };\n\t\t834DA85425DAD4A7003CF18B /* NewReleasesResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewReleasesResponse.swift; sourceTree = \"<group>\"; };\n\t\t834DA85725DAD574003CF18B /* APIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIImage.swift; sourceTree = \"<group>\"; };\n\t\t834DA85B25DAD73A003CF18B /* FeaturedPlaylistsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedPlaylistsResponse.swift; sourceTree = \"<group>\"; };\n\t\t834DA85E25DADA39003CF18B /* RecommendedGenresResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedGenresResponse.swift; sourceTree = \"<group>\"; };\n\t\t834DA86125DADD41003CF18B /* RecommendationsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendationsResponse.swift; sourceTree = \"<group>\"; };\n\t\t834DA86525DAE8DE003CF18B /* NewReleaseCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewReleaseCollectionViewCell.swift; sourceTree = \"<group>\"; };\n\t\t834DA86925DAE8F1003CF18B /* FeaturedPlaylistCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedPlaylistCollectionViewCell.swift; sourceTree = \"<group>\"; };\n\t\t834DA86C25DAE908003CF18B /* RecommendedTrackCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedTrackCollectionViewCell.swift; sourceTree = \"<group>\"; };\n\t\t834DA86F25DB0BED003CF18B /* NewReleasesCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewReleasesCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t834DA87225DB1904003CF18B /* FeaturedPlaylistCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedPlaylistCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t834DA87525DB1942003CF18B /* RecommendedTrackCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedTrackCellViewModel.swift; sourceTree = \"<group>\"; };\n\t\t834DA87825DB2FF7003CF18B /* AlbumViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumViewController.swift; sourceTree = \"<group>\"; };\n\t\t834DA87B25DB3235003CF18B /* AlbumDetailsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailsResponse.swift; sourceTree = \"<group>\"; };\n\t\t834DA87E25DB3528003CF18B /* PlaylistDetailsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistDetailsResponse.swift; sourceTree = \"<group>\"; };\n\t\t83776ED7A5A9E57291488C82 /* Pods-Spotify.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Spotify.debug.xcconfig\"; path = \"Target Support Files/Pods-Spotify/Pods-Spotify.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t83962E3825D96D4400A0F09E /* TabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E3C25D96D6200A0F09E /* SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E3F25D96D7000A0F09E /* LibraryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E4525D96D9400A0F09E /* AuthViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E4925D96D9F00A0F09E /* WelcomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E4C25D96DB000A0F09E /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E4F25D96DBB00A0F09E /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E5225D96DC500A0F09E /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E5525D96DD300A0F09E /* PlaylistViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E5825D96DE600A0F09E /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = \"<group>\"; };\n\t\t83962E5B25D96E0400A0F09E /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = \"<group>\"; };\n\t\t83962E5E25D96E1000A0F09E /* APICaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APICaller.swift; sourceTree = \"<group>\"; };\n\t\t83962E6125D96E1E00A0F09E /* HapticsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticsManager.swift; sourceTree = \"<group>\"; };\n\t\t83962E6425D96E3500A0F09E /* Playlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Playlist.swift; sourceTree = \"<group>\"; };\n\t\t83962E6725D96E4100A0F09E /* AudioTrack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioTrack.swift; sourceTree = \"<group>\"; };\n\t\t83962E6A25D96E4E00A0F09E /* Artist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Artist.swift; sourceTree = \"<group>\"; };\n\t\t83962E6D25D96E5800A0F09E /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = \"<group>\"; };\n\t\t839BA20225D96C1500BA56A5 /* Spotify.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Spotify.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t839BA20525D96C1500BA56A5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t839BA20725D96C1500BA56A5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = \"<group>\"; };\n\t\t839BA20925D96C1500BA56A5 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = \"<group>\"; };\n\t\t839BA20E25D96C1600BA56A5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t839BA21125D96C1600BA56A5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t839BA21325D96C1600BA56A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83C02EA025DEA7D5009DC56A /* PlaylistHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistHeaderCollectionReusableView.swift; sourceTree = \"<group>\"; };\n\t\t83C02EA325DEA97A009DC56A /* PlaylistHeaderViewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistHeaderViewViewModel.swift; sourceTree = \"<group>\"; };\n\t\t83DAECA125D9751500A55E5A /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = \"<group>\"; };\n\t\t83DAECA425D97DC300A55E5A /* AuthResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthResponse.swift; sourceTree = \"<group>\"; };\n\t\t83E7A16125E2BBE7007EF414 /* LibraryPlaylistsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryPlaylistsViewController.swift; sourceTree = \"<group>\"; };\n\t\t83E7A16525E2BC00007EF414 /* LibraryAlbumsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryAlbumsViewController.swift; sourceTree = \"<group>\"; };\n\t\t83E7A16825E2BE0F007EF414 /* LibraryToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryToggleView.swift; sourceTree = \"<group>\"; };\n\t\t83E7A16B25E2C4C3007EF414 /* LibraryPlaylistsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryPlaylistsResponse.swift; sourceTree = \"<group>\"; };\n\t\t83E7A16E25E2C5C0007EF414 /* ActionLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionLabelView.swift; sourceTree = \"<group>\"; };\n\t\t83E7A17125E3022F007EF414 /* LibraryAlbumsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryAlbumsResponse.swift; sourceTree = \"<group>\"; };\n\t\t9B58F92C4DA5A3AFC0EF74F2 /* Pods_Spotify.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Spotify.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t8305D6E026E172CE006C162D /* 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\t\t839BA1FF25D96C1500BA56A5 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB155E499983AD7C0E9CC2978 /* Pods_Spotify.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t55C258CBA1FF639EF844CC45 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9B58F92C4DA5A3AFC0EF74F2 /* Pods_Spotify.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8305D6E426E172CE006C162D /* SpotifyTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8305D6E526E172CE006C162D /* SpotifyTests.swift */,\n\t\t\t);\n\t\t\tpath = SpotifyTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t830A09E725E1AB9E00D37663 /* SearchResultCells */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830A09E825E1ABBF00D37663 /* SearchResultDefaultTableViewCell.swift */,\n\t\t\t\t830A09EE25E1AEE400D37663 /* SearchResultSubtitleTableViewCell.swift */,\n\t\t\t);\n\t\t\tpath = SearchResultCells;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t830A09F425E1B2BD00D37663 /* Presenter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830A09F525E1B2D000D37663 /* PlaybackPresenter.swift */,\n\t\t\t);\n\t\t\tpath = Presenter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t834DA86425DAE8CC003CF18B /* Browse */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t834DA86525DAE8DE003CF18B /* NewReleaseCollectionViewCell.swift */,\n\t\t\t\t834DA86925DAE8F1003CF18B /* FeaturedPlaylistCollectionViewCell.swift */,\n\t\t\t\t834DA86C25DAE908003CF18B /* RecommendedTrackCollectionViewCell.swift */,\n\t\t\t);\n\t\t\tpath = Browse;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83962E4225D96D7600A0F09E /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83962E3825D96D4400A0F09E /* TabBarViewController.swift */,\n\t\t\t\t839BA20925D96C1500BA56A5 /* HomeViewController.swift */,\n\t\t\t\t83962E3C25D96D6200A0F09E /* SearchViewController.swift */,\n\t\t\t\t83962E3F25D96D7000A0F09E /* LibraryViewController.swift */,\n\t\t\t);\n\t\t\tpath = Core;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83962E4425D96D8000A0F09E /* Other */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E7A16025E2BBD3007EF414 /* Library */,\n\t\t\t\t83962E4525D96D9400A0F09E /* AuthViewController.swift */,\n\t\t\t\t83962E4925D96D9F00A0F09E /* WelcomeViewController.swift */,\n\t\t\t\t83962E4C25D96DB000A0F09E /* SettingsViewController.swift */,\n\t\t\t\t83962E4F25D96DBB00A0F09E /* ProfileViewController.swift */,\n\t\t\t\t83962E5225D96DC500A0F09E /* PlayerViewController.swift */,\n\t\t\t\t83962E5525D96DD300A0F09E /* PlaylistViewController.swift */,\n\t\t\t\t83962E5825D96DE600A0F09E /* SearchResultsViewController.swift */,\n\t\t\t\t834DA87825DB2FF7003CF18B /* AlbumViewController.swift */,\n\t\t\t\t8309BFC825E058F700767482 /* CategoryViewController.swift */,\n\t\t\t);\n\t\t\tpath = Other;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA1F925D96C1500BA56A5 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t839BA20425D96C1500BA56A5 /* Spotify */,\n\t\t\t\t8305D6E426E172CE006C162D /* SpotifyTests */,\n\t\t\t\t839BA20325D96C1500BA56A5 /* Products */,\n\t\t\t\t8E19A93F9CD9274F548B6CAA /* Pods */,\n\t\t\t\t55C258CBA1FF639EF844CC45 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA20325D96C1500BA56A5 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t839BA20225D96C1500BA56A5 /* Spotify.app */,\n\t\t\t\t8305D6E326E172CE006C162D /* SpotifyTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA20425D96C1500BA56A5 /* Spotify */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830A09F425E1B2BD00D37663 /* Presenter */,\n\t\t\t\t839BA21F25D96C5400BA56A5 /* Resources */,\n\t\t\t\t839BA21E25D96C4C00BA56A5 /* Managers */,\n\t\t\t\t839BA21D25D96C4600BA56A5 /* ViewModels */,\n\t\t\t\t839BA21C25D96C4200BA56A5 /* Models */,\n\t\t\t\t839BA21B25D96C3D00BA56A5 /* Views */,\n\t\t\t\t839BA21A25D96C3600BA56A5 /* Controllers */,\n\t\t\t\t839BA21325D96C1600BA56A5 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = Spotify;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21A25D96C3600BA56A5 /* Controllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83962E4425D96D8000A0F09E /* Other */,\n\t\t\t\t83962E4225D96D7600A0F09E /* Core */,\n\t\t\t);\n\t\t\tpath = Controllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21B25D96C3D00BA56A5 /* Views */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830A09E725E1AB9E00D37663 /* SearchResultCells */,\n\t\t\t\t834DA86425DAE8CC003CF18B /* Browse */,\n\t\t\t\t839BA21025D96C1600BA56A5 /* LaunchScreen.storyboard */,\n\t\t\t\t83C02EA025DEA7D5009DC56A /* PlaylistHeaderCollectionReusableView.swift */,\n\t\t\t\t8325981B25E01BA600A091F6 /* TitleHeaderCollectionReusableView.swift */,\n\t\t\t\t8325981E25E01F4900A091F6 /* AlbumTrackCollectionViewCell.swift */,\n\t\t\t\t8325982425E0294D00A091F6 /* GenreCollectionViewCell.swift */,\n\t\t\t\t830A09F925E1B72E00D37663 /* PlayerControlsView.swift */,\n\t\t\t\t83E7A16825E2BE0F007EF414 /* LibraryToggleView.swift */,\n\t\t\t\t83E7A16E25E2C5C0007EF414 /* ActionLabelView.swift */,\n\t\t\t);\n\t\t\tpath = Views;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21C25D96C4200BA56A5 /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83962E6425D96E3500A0F09E /* Playlist.swift */,\n\t\t\t\t83962E6725D96E4100A0F09E /* AudioTrack.swift */,\n\t\t\t\t83962E6A25D96E4E00A0F09E /* Artist.swift */,\n\t\t\t\t83962E6D25D96E5800A0F09E /* UserProfile.swift */,\n\t\t\t\t83DAECA425D97DC300A55E5A /* AuthResponse.swift */,\n\t\t\t\t834DA84225DAAD36003CF18B /* SettingsModels.swift */,\n\t\t\t\t834DA85425DAD4A7003CF18B /* NewReleasesResponse.swift */,\n\t\t\t\t834DA85725DAD574003CF18B /* APIImage.swift */,\n\t\t\t\t834DA85B25DAD73A003CF18B /* FeaturedPlaylistsResponse.swift */,\n\t\t\t\t834DA85E25DADA39003CF18B /* RecommendedGenresResponse.swift */,\n\t\t\t\t834DA86125DADD41003CF18B /* RecommendationsResponse.swift */,\n\t\t\t\t834DA87B25DB3235003CF18B /* AlbumDetailsResponse.swift */,\n\t\t\t\t834DA87E25DB3528003CF18B /* PlaylistDetailsResponse.swift */,\n\t\t\t\t8309BFC225E0555500767482 /* AllCategoriesResponse.swift */,\n\t\t\t\t8309C02B25E082E300767482 /* SearchResultResponse.swift */,\n\t\t\t\t8309C02F25E083DF00767482 /* SearchResult.swift */,\n\t\t\t\t83E7A16B25E2C4C3007EF414 /* LibraryPlaylistsResponse.swift */,\n\t\t\t\t83E7A17125E3022F007EF414 /* LibraryAlbumsResponse.swift */,\n\t\t\t);\n\t\t\tpath = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21D25D96C4600BA56A5 /* ViewModels */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t834DA86F25DB0BED003CF18B /* NewReleasesCellViewModel.swift */,\n\t\t\t\t834DA87225DB1904003CF18B /* FeaturedPlaylistCellViewModel.swift */,\n\t\t\t\t834DA87525DB1942003CF18B /* RecommendedTrackCellViewModel.swift */,\n\t\t\t\t83C02EA325DEA97A009DC56A /* PlaylistHeaderViewViewModel.swift */,\n\t\t\t\t8325982125E01FF300A091F6 /* AlbumCollectionViewCellViewModel.swift */,\n\t\t\t\t8309BFC525E0582300767482 /* CategoryCollectionViewCellViewModel.swift */,\n\t\t\t\t830A09EB25E1ACEA00D37663 /* SearchResultDefaultTableViewCellViewModel.swift */,\n\t\t\t\t830A09F125E1AF8B00D37663 /* SearchResultSubtitleTableViewCellViewModel.swift */,\n\t\t\t);\n\t\t\tpath = ViewModels;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21E25D96C4C00BA56A5 /* Managers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83962E5B25D96E0400A0F09E /* AuthManager.swift */,\n\t\t\t\t83962E5E25D96E1000A0F09E /* APICaller.swift */,\n\t\t\t\t83962E6125D96E1E00A0F09E /* HapticsManager.swift */,\n\t\t\t);\n\t\t\tpath = Managers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t839BA21F25D96C5400BA56A5 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t839BA20E25D96C1600BA56A5 /* Assets.xcassets */,\n\t\t\t\t839BA20525D96C1500BA56A5 /* AppDelegate.swift */,\n\t\t\t\t839BA20725D96C1500BA56A5 /* SceneDelegate.swift */,\n\t\t\t\t83DAECA125D9751500A55E5A /* Extensions.swift */,\n\t\t\t);\n\t\t\tpath = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E7A16025E2BBD3007EF414 /* Library */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E7A16125E2BBE7007EF414 /* LibraryPlaylistsViewController.swift */,\n\t\t\t\t83E7A16525E2BC00007EF414 /* LibraryAlbumsViewController.swift */,\n\t\t\t);\n\t\t\tpath = Library;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8E19A93F9CD9274F548B6CAA /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83776ED7A5A9E57291488C82 /* Pods-Spotify.debug.xcconfig */,\n\t\t\t\t26823DE37DC5DC6B3B050E92 /* Pods-Spotify.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t8305D6E226E172CE006C162D /* SpotifyTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 8305D6EB26E172CE006C162D /* Build configuration list for PBXNativeTarget \"SpotifyTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t8305D6DF26E172CE006C162D /* Sources */,\n\t\t\t\t8305D6E026E172CE006C162D /* Frameworks */,\n\t\t\t\t8305D6E126E172CE006C162D /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t8305D6E826E172CE006C162D /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = SpotifyTests;\n\t\t\tproductName = SpotifyTests;\n\t\t\tproductReference = 8305D6E326E172CE006C162D /* SpotifyTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t839BA20125D96C1500BA56A5 /* Spotify */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 839BA21625D96C1600BA56A5 /* Build configuration list for PBXNativeTarget \"Spotify\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t19E7EAA90164C6F7BB5DDBC8 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t839BA1FE25D96C1500BA56A5 /* Sources */,\n\t\t\t\t839BA1FF25D96C1500BA56A5 /* Frameworks */,\n\t\t\t\t839BA20025D96C1500BA56A5 /* Resources */,\n\t\t\t\t7A1EE8C8D3B5091BF3FE3F35 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Spotify;\n\t\t\tproductName = Spotify;\n\t\t\tproductReference = 839BA20225D96C1500BA56A5 /* Spotify.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t839BA1FA25D96C1500BA56A5 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1300;\n\t\t\t\tLastUpgradeCheck = 1240;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t8305D6E226E172CE006C162D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 13.0;\n\t\t\t\t\t\tTestTargetID = 839BA20125D96C1500BA56A5;\n\t\t\t\t\t};\n\t\t\t\t\t839BA20125D96C1500BA56A5 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.4;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 839BA1FD25D96C1500BA56A5 /* Build configuration list for PBXProject \"Spotify\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\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 = 839BA1F925D96C1500BA56A5;\n\t\t\tproductRefGroup = 839BA20325D96C1500BA56A5 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t839BA20125D96C1500BA56A5 /* Spotify */,\n\t\t\t\t8305D6E226E172CE006C162D /* SpotifyTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t8305D6E126E172CE006C162D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t839BA20025D96C1500BA56A5 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t839BA21225D96C1600BA56A5 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t839BA20F25D96C1600BA56A5 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t19E7EAA90164C6F7BB5DDBC8 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-Spotify-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t7A1EE8C8D3B5091BF3FE3F35 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-Spotify/Pods-Spotify-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t8305D6DF26E172CE006C162D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8305D6E626E172CE006C162D /* SpotifyTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t839BA1FE25D96C1500BA56A5 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83962E3D25D96D6200A0F09E /* SearchViewController.swift in Sources */,\n\t\t\t\t834DA87F25DB3528003CF18B /* PlaylistDetailsResponse.swift in Sources */,\n\t\t\t\t83962E6525D96E3500A0F09E /* Playlist.swift in Sources */,\n\t\t\t\t83962E5C25D96E0400A0F09E /* AuthManager.swift in Sources */,\n\t\t\t\t83E7A16925E2BE0F007EF414 /* LibraryToggleView.swift in Sources */,\n\t\t\t\t834DA87025DB0BED003CF18B /* NewReleasesCellViewModel.swift in Sources */,\n\t\t\t\t8325982225E01FF300A091F6 /* AlbumCollectionViewCellViewModel.swift in Sources */,\n\t\t\t\t834DA87625DB1942003CF18B /* RecommendedTrackCellViewModel.swift in Sources */,\n\t\t\t\t83E7A16F25E2C5C0007EF414 /* ActionLabelView.swift in Sources */,\n\t\t\t\t83962E5925D96DE600A0F09E /* SearchResultsViewController.swift in Sources */,\n\t\t\t\t83E7A17225E3022F007EF414 /* LibraryAlbumsResponse.swift in Sources */,\n\t\t\t\t8309BFC925E058F700767482 /* CategoryViewController.swift in Sources */,\n\t\t\t\t8309BFC325E0555500767482 /* AllCategoriesResponse.swift in Sources */,\n\t\t\t\t8325981C25E01BA600A091F6 /* TitleHeaderCollectionReusableView.swift in Sources */,\n\t\t\t\t834DA87925DB2FF7003CF18B /* AlbumViewController.swift in Sources */,\n\t\t\t\t8309C02C25E082E300767482 /* SearchResultResponse.swift in Sources */,\n\t\t\t\t83C02EA425DEA97A009DC56A /* PlaylistHeaderViewViewModel.swift in Sources */,\n\t\t\t\t834DA87325DB1904003CF18B /* FeaturedPlaylistCellViewModel.swift in Sources */,\n\t\t\t\t830A09F225E1AF8B00D37663 /* SearchResultSubtitleTableViewCellViewModel.swift in Sources */,\n\t\t\t\t83962E4A25D96D9F00A0F09E /* WelcomeViewController.swift in Sources */,\n\t\t\t\t83962E5025D96DBB00A0F09E /* ProfileViewController.swift in Sources */,\n\t\t\t\t83962E3925D96D4400A0F09E /* TabBarViewController.swift in Sources */,\n\t\t\t\t830A09E925E1ABBF00D37663 /* SearchResultDefaultTableViewCell.swift in Sources */,\n\t\t\t\t83962E6225D96E1E00A0F09E /* HapticsManager.swift in Sources */,\n\t\t\t\t834DA86D25DAE908003CF18B /* RecommendedTrackCollectionViewCell.swift in Sources */,\n\t\t\t\t83DAECA525D97DC300A55E5A /* AuthResponse.swift in Sources */,\n\t\t\t\t830A09FA25E1B72E00D37663 /* PlayerControlsView.swift in Sources */,\n\t\t\t\t8325982525E0294D00A091F6 /* GenreCollectionViewCell.swift in Sources */,\n\t\t\t\t834DA85525DAD4A7003CF18B /* NewReleasesResponse.swift in Sources */,\n\t\t\t\t830A09EF25E1AEE400D37663 /* SearchResultSubtitleTableViewCell.swift in Sources */,\n\t\t\t\t834DA85825DAD574003CF18B /* APIImage.swift in Sources */,\n\t\t\t\t83E7A16625E2BC00007EF414 /* LibraryAlbumsViewController.swift in Sources */,\n\t\t\t\t83E7A16C25E2C4C3007EF414 /* LibraryPlaylistsResponse.swift in Sources */,\n\t\t\t\t8325981F25E01F4900A091F6 /* AlbumTrackCollectionViewCell.swift in Sources */,\n\t\t\t\t834DA86225DADD41003CF18B /* RecommendationsResponse.swift in Sources */,\n\t\t\t\t83962E6825D96E4100A0F09E /* AudioTrack.swift in Sources */,\n\t\t\t\t839BA20A25D96C1500BA56A5 /* HomeViewController.swift in Sources */,\n\t\t\t\t830A09EC25E1ACEA00D37663 /* SearchResultDefaultTableViewCellViewModel.swift in Sources */,\n\t\t\t\t834DA86625DAE8DE003CF18B /* NewReleaseCollectionViewCell.swift in Sources */,\n\t\t\t\t83962E4625D96D9400A0F09E /* AuthViewController.swift in Sources */,\n\t\t\t\t834DA86A25DAE8F1003CF18B /* FeaturedPlaylistCollectionViewCell.swift in Sources */,\n\t\t\t\t839BA20625D96C1500BA56A5 /* AppDelegate.swift in Sources */,\n\t\t\t\t83962E6E25D96E5800A0F09E /* UserProfile.swift in Sources */,\n\t\t\t\t83DAECA225D9751500A55E5A /* Extensions.swift in Sources */,\n\t\t\t\t8309C03025E083DF00767482 /* SearchResult.swift in Sources */,\n\t\t\t\t83C02EA125DEA7D5009DC56A /* PlaylistHeaderCollectionReusableView.swift in Sources */,\n\t\t\t\t830A09F625E1B2D000D37663 /* PlaybackPresenter.swift in Sources */,\n\t\t\t\t83962E4025D96D7000A0F09E /* LibraryViewController.swift in Sources */,\n\t\t\t\t83962E6B25D96E4E00A0F09E /* Artist.swift in Sources */,\n\t\t\t\t834DA84325DAAD36003CF18B /* SettingsModels.swift in Sources */,\n\t\t\t\t83962E5625D96DD300A0F09E /* PlaylistViewController.swift in Sources */,\n\t\t\t\t839BA20825D96C1500BA56A5 /* SceneDelegate.swift in Sources */,\n\t\t\t\t83E7A16225E2BBE7007EF414 /* LibraryPlaylistsViewController.swift in Sources */,\n\t\t\t\t83962E5325D96DC500A0F09E /* PlayerViewController.swift in Sources */,\n\t\t\t\t834DA87C25DB3235003CF18B /* AlbumDetailsResponse.swift in Sources */,\n\t\t\t\t83962E5F25D96E1000A0F09E /* APICaller.swift in Sources */,\n\t\t\t\t834DA85C25DAD73A003CF18B /* FeaturedPlaylistsResponse.swift in Sources */,\n\t\t\t\t83962E4D25D96DB000A0F09E /* SettingsViewController.swift in Sources */,\n\t\t\t\t8309BFC625E0582300767482 /* CategoryCollectionViewCellViewModel.swift in Sources */,\n\t\t\t\t834DA85F25DADA39003CF18B /* RecommendedGenresResponse.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t8305D6E826E172CE006C162D /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 839BA20125D96C1500BA56A5 /* Spotify */;\n\t\t\ttargetProxy = 8305D6E726E172CE006C162D /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t839BA21025D96C1600BA56A5 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t839BA21125D96C1600BA56A5 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t8305D6E926E172CE006C162D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 3798Z36XLV;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.5;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = io.iosacademy.SpotifyTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Spotify.app/Spotify\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t8305D6EA26E172CE006C162D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 3798Z36XLV;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.5;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = io.iosacademy.SpotifyTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Spotify.app/Spotify\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t839BA21425D96C1600BA56A5 /* 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++14\";\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 = 14.4;\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\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t839BA21525D96C1600BA56A5 /* 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++14\";\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 = 14.4;\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\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t839BA21725D96C1600BA56A5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 83776ED7A5A9E57291488C82 /* Pods-Spotify.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_TEAM = 3798Z36XLV;\n\t\t\t\tINFOPLIST_FILE = Spotify/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = io.iosacademy.Spotify;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t839BA21825D96C1600BA56A5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 26823DE37DC5DC6B3B050E92 /* Pods-Spotify.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_TEAM = 3798Z36XLV;\n\t\t\t\tINFOPLIST_FILE = Spotify/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = io.iosacademy.Spotify;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\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\t8305D6EB26E172CE006C162D /* Build configuration list for PBXNativeTarget \"SpotifyTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t8305D6E926E172CE006C162D /* Debug */,\n\t\t\t\t8305D6EA26E172CE006C162D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t839BA1FD25D96C1500BA56A5 /* Build configuration list for PBXProject \"Spotify\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t839BA21425D96C1600BA56A5 /* Debug */,\n\t\t\t\t839BA21525D96C1600BA56A5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t839BA21625D96C1600BA56A5 /* Build configuration list for PBXNativeTarget \"Spotify\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t839BA21725D96C1600BA56A5 /* Debug */,\n\t\t\t\t839BA21825D96C1600BA56A5 /* 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 = 839BA1FA25D96C1500BA56A5 /* Project object */;\n}\n"
  },
  {
    "path": "Spotify.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Spotify.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": "Spotify.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   uuid = \"DCC67948-CCD7-4D2E-BA37-6531E83B16CA\"\n   type = \"1\"\n   version = \"2.0\">\n</Bucket>\n"
  },
  {
    "path": "Spotify.xcodeproj/xcuserdata/afrazsiddiqui.xcuserdatad/xcschemes/xcschememanagement.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>SchemeUserState</key>\n\t<dict>\n\t\t<key>Spotify.xcscheme_^#shared#^_</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>14</integer>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "Spotify.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Spotify.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Pods/Pods.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Spotify.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": "Spotify.xcworkspace/xcuserdata/afrazsiddiqui.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   uuid = \"ACD9AFF3-0AF9-499E-8EF7-EAE1FD0E891D\"\n   type = \"0\"\n   version = \"2.0\">\n</Bucket>\n"
  },
  {
    "path": "SpotifyTests/SpotifyTests.swift",
    "content": "//\n//  SpotifyTests.swift\n//  SpotifyTests\n//\n//  Created by Afraz Siddiqui on 9/2/21.\n//\n\n@testable import Spotify\nimport XCTest\n\nclass SpotifyTests: XCTestCase {\n    func testNewReleasesCellViewModel() {\n        let viewModel = NewReleasesCellViewModel(\n            name: \"Album Title\",\n            artworkURL: nil,\n            numberOfTracks: 12,\n            artistName: \"Drake\"\n        )\n        XCTAssertNotNil(viewModel)\n        XCTAssertEqual(viewModel.name, \"Album Title\")\n        XCTAssertNil(viewModel.artworkURL)\n        XCTAssertEqual(viewModel.numberOfTracks, 12)\n        XCTAssertEqual(viewModel.artistName, \"Drake\")\n    }\n\n    func testFeaturedPlaylistCellViewModel() {\n        let viewModel = FeaturedPlaylistCellViewModel(\n            name: \"Summer Vibes\",\n            artworkURL: nil,\n            creatorName: \"All American\"\n        )\n        XCTAssertEqual(viewModel.name, \"Summer Vibes\")\n        XCTAssertEqual(viewModel.creatorName, \"All American\")\n        XCTAssertNil(viewModel.artworkURL)\n    }\n\n    func testMath() {\n        XCTAssertEqual(7+2, 9)\n        XCTAssertEqual(12 - 2, 10)\n    }\n}\n"
  },
  {
    "path": "codemagic.yaml",
    "content": "# Customize the codemagic.yaml file according to your project and commit it to the root of your repository\n# Check out https://docs.codemagic.io/getting-started/yaml/ for more information\nworkflows:\n  spotify-workflow:\n    name: Spotify Pipeline\n    scripts:\n      - name: iOS test\n        script: |\n          xcode-project run-tests \\\n              --workspace Spotify.xcworkspace \\\n              --scheme Spotify\n    publishing:\n      email:\n        recipients:\n          - hello@iosacademy.io\n"
  },
  {
    "path": "codemagic.yml",
    "content": "# Customize the codemagic.yaml file according to your project and commit it to the root of your repository\n# Check out https://docs.codemagic.io/getting-started/yaml/ for more information\nworkflows:\n  spotify-workflow:\n    name: Spotify Pipeline\n    scripts:\n      - name: iOS test\n        script: |\n          xcode-project run-tests \\\n              --workspace Spotify.xcworkspace \\\n              --scheme Spotify \\\n              --device \"iPhone 11\"\n    publishing:\n      email:\n        recipients:\n          - hello@iosacademy.io\n"
  }
]