[
  {
    "path": ".gitignore",
    "content": "# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n*.xccheckout\n*.moved-aside\nDerivedData\n*.hmap\n*.ipa\n*.xcuserstate\n*.DS_Store\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control\n#\n#Pods/\n"
  },
  {
    "path": "AvePurchaseButton.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name         = \"AvePurchaseButton\"\n  s.version      = \"1.0.6\"\n  s.summary      = \"iOS App Store Styled Purchase Button\"\n  s.description  = <<-DESC\n\tDrop In App Store Styled Purchase Button, with proper animations. Title configurable in Interface Builder.\n                   DESC\n  s.homepage     = \"https://github.com/AndreasVerhoeven/AvePurchaseButton\"\n  s.screenshots  = \"https://cloud.githubusercontent.com/assets/168214/11920880/852741d6-a77a-11e5-839d-e2f572e49475.gif\", \"https://cloud.githubusercontent.com/assets/168214/11920878/7c5d708e-a77a-11e5-8553-3806e89ba434.png\"\n  s.license      = { :type => \"MIT\", :file => \"LICENSE\" }\n  s.author            = \"Andreas Verhoeven\"\n  s.social_media_url   = \"http://twitter.com/aveapps\"\n  s.platform     = :ios, \"7.0\"\n  s.source       = { :git => \"https://github.com/AndreasVerhoeven/AvePurchaseButton.git\", :tag => \"1.0.6\" }\n  s.source_files  = \"Source\", \"Source/**/*.{h,m}\"\n  s.exclude_files = \"Example\"\n  s.public_header_files = \"Source/**/AvePurchaseButton.h\", \"Source/**/AveBorderedButton.h\", \"Source/**/AveBorderedView.h\"\n  s.requires_arc = true\nend\n"
  },
  {
    "path": "Example/PurchaseButtonExample/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  PurchaseButtonExample\n//\n//  Created by Andreas Verhoeven on 20-12-15.\n//  Copyright © 2015 AveApps. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n\n@end\n\n"
  },
  {
    "path": "Example/PurchaseButtonExample/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  PurchaseButtonExample\n//\n//  Created by Andreas Verhoeven on 20-12-15.\n//  Copyright © 2015 AveApps. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n\n@implementation AppDelegate\n\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n\t// Override point for customization after application launch.\n\treturn YES;\n}\n\n@end\n"
  },
  {
    "path": "Example/PurchaseButtonExample/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Example/PurchaseButtonExample/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"8150\" systemVersion=\"15A204g\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"8122\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Llm-lL-Icb\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xb3-aO-Qok\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <animations/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\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</document>\n"
  },
  {
    "path": "Example/PurchaseButtonExample/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"9531\" systemVersion=\"15C50\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" initialViewController=\"8kp-na-y4a\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"9529\"/>\n    </dependencies>\n    <scenes>\n        <!--Purchase Things-->\n        <scene sceneID=\"i9I-zw-9tP\">\n            <objects>\n                <tableViewController title=\"Purchase Things\" id=\"NpG-gm-3NQ\" customClass=\"TableViewController\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"plain\" rowHeight=\"44\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" id=\"tmY-SD-atP\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"NpG-gm-3NQ\" id=\"sOb-Nz-TlO\"/>\n                            <outlet property=\"delegate\" destination=\"NpG-gm-3NQ\" id=\"lBg-bt-fUQ\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" title=\"Root View Controller\" id=\"Ayi-7K-DDa\"/>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"oK7-wv-iKx\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1076\" y=\"405\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"J6c-kz-8IB\">\n            <objects>\n                <navigationController id=\"8kp-na-y4a\" sceneMemberID=\"viewController\">\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" id=\"j4p-Lu-mPD\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <connections>\n                        <segue destination=\"NpG-gm-3NQ\" kind=\"relationship\" relationship=\"rootViewController\" id=\"UsV-og-jii\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"T9p-l6-f6h\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"256\" y=\"405\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Example/PurchaseButtonExample/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>en</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>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</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": "Example/PurchaseButtonExample/TableViewController.h",
    "content": "//\n//  TableViewController.h\n//  PurchaseButtonExample\n//\n//  Created by Andreas Verhoeven on 20-12-15.\n//  Copyright © 2015 AveApps. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface TableViewController : UITableViewController\n\n@end\n"
  },
  {
    "path": "Example/PurchaseButtonExample/TableViewController.m",
    "content": "//\n//  TableViewController.m\n//  PurchaseButtonExample\n//\n//  Created by Andreas Verhoeven on 20-12-15.\n//  Copyright © 2015 AveApps. All rights reserved.\n//\n\n#import \"TableViewController.h\"\n#import \"AvePurchaseButton.h\"\n\n@implementation TableViewController\n{\n\tNSMutableIndexSet* _busyIndexes;\n}\n\n-(void)purchaseButtonTapped:(AvePurchaseButton*)button\n{\n\tNSIndexPath* indexPath = [self.tableView indexPathForCell:(UITableViewCell*)button.superview];\n\tNSInteger index = indexPath.row;\n\t\n\t// handle taps on the purchase button by\n\tswitch(button.buttonState)\n\t{\n\t\tcase AvePurchaseButtonStateNormal:\n\t\t\t// progress -> confirmation\n\t\t\t[button setButtonState:AvePurchaseButtonStateConfirmation animated:YES];\n\t\t\tbreak;\n\t\t\t\n\t\tcase AvePurchaseButtonStateConfirmation:\n\t\t\t// confirmation -> \"purchase\" progress\n\t\t\t[_busyIndexes addIndex:index];\n\t\t\t[button setButtonState:AvePurchaseButtonStateProgress animated:YES];\n\t\t\tbreak;\n\t\t\t\n\t\tcase AvePurchaseButtonStateProgress:\n\t\t\t// progress -> back to normal\n\t\t\t[_busyIndexes removeIndex:index];\n\t\t\t[button setButtonState:AvePurchaseButtonStateNormal animated:YES];\n\t\t\tbreak;\n\t}\n}\n\n-(void)viewDidLoad\n{\n\t[super viewDidLoad];\n\t\n\t_busyIndexes = [NSMutableIndexSet new];\n\t\n\tself.tableView.rowHeight = 54;\n\t\n\tself.tableView.layoutMargins = UIEdgeInsetsZero;\n\tself.tableView.separatorInset = UIEdgeInsetsZero;\n}\n\n-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section\n{\n\treturn 10;\n}\n\n-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n\tstatic NSString* const CellIdentifier = @\"Cell\";\n\t\n\tUITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];\n\tif(nil == cell)\n\t{\n\t\t// create  a cell with some nice defaults\n\t\tcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];\n\t\tcell.selectionStyle = UITableViewCellSelectionStyleNone;\n\t\tcell.layoutMargins = UIEdgeInsetsZero;\n\t\tcell.separatorInset = UIEdgeInsetsZero;\n\t\tcell.detailTextLabel.textColor = [UIColor grayColor];\n\t\t\n\t\t// add a buttons as an accessory and let it respond to touches\n\t\tAvePurchaseButton* button = [[AvePurchaseButton alloc] initWithFrame:CGRectZero];\n\t\t[button addTarget:self action:@selector(purchaseButtonTapped:) forControlEvents:UIControlEventTouchUpInside];\n\t\tcell.accessoryView = button;\n\t}\n\t\n\t// configure the cell\n\tcell.textLabel.text = @\"Some Nice Item\";\n\tcell.detailTextLabel.text = @\"Really nice!\";\n\t\n\t// configure the purchase button in state normal\n\tAvePurchaseButton* button = (AvePurchaseButton*)cell.accessoryView;\n\tbutton.buttonState = AvePurchaseButtonStateNormal;\n\tbutton.normalTitle = @\"$ 2.99\";\n\tbutton.confirmationTitle = @\"BUY\";\n\t[button sizeToFit];\n\t\n\t// if the item at this indexPath is being \"busy\" with purchasing, update the purchase\n\t// button's state to reflect so.\n\tif([_busyIndexes containsIndex:indexPath.row] == YES)\n\t{\n\t\tbutton.buttonState = AvePurchaseButtonStateProgress;\n\t}\n\t\n\t\n\treturn cell;\n}\n\n@end\n"
  },
  {
    "path": "Example/PurchaseButtonExample/main.m",
    "content": "//\n//  main.m\n//  PurchaseButtonExample\n//\n//  Created by Andreas Verhoeven on 20-12-15.\n//  Copyright © 2015 AveApps. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n\t@autoreleasepool {\n\t    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n\t}\n}\n"
  },
  {
    "path": "Example/PurchaseButtonExample.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t49324B351C275EF20007A068 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B341C275EF20007A068 /* main.m */; };\n\t\t49324B381C275EF20007A068 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B371C275EF20007A068 /* AppDelegate.m */; };\n\t\t49324B3E1C275EF20007A068 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 49324B3C1C275EF20007A068 /* Main.storyboard */; };\n\t\t49324B401C275EF20007A068 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 49324B3F1C275EF20007A068 /* Assets.xcassets */; };\n\t\t49324B431C275EF20007A068 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 49324B411C275EF20007A068 /* LaunchScreen.storyboard */; };\n\t\t49324B561C2765930007A068 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B551C2765930007A068 /* TableViewController.m */; };\n\t\t49324B761C276E420007A068 /* AveBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B6E1C276E420007A068 /* AveBorderedButton.m */; };\n\t\t49324B771C276E420007A068 /* AveBorderedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B701C276E420007A068 /* AveBorderedView.m */; };\n\t\t49324B781C276E420007A068 /* AvePurchaseActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B731C276E420007A068 /* AvePurchaseActivityIndicatorView.m */; };\n\t\t49324B791C276E420007A068 /* AvePurchaseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 49324B751C276E420007A068 /* AvePurchaseButton.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t49324B301C275EF20007A068 /* PurchaseButtonExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PurchaseButtonExample.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t49324B341C275EF20007A068 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\t49324B361C275EF20007A068 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t49324B371C275EF20007A068 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t49324B3D1C275EF20007A068 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t49324B3F1C275EF20007A068 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t49324B421C275EF20007A068 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t49324B441C275EF20007A068 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t49324B541C2765930007A068 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = \"<group>\"; };\n\t\t49324B551C2765930007A068 /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = \"<group>\"; };\n\t\t49324B6D1C276E420007A068 /* AveBorderedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AveBorderedButton.h; sourceTree = \"<group>\"; };\n\t\t49324B6E1C276E420007A068 /* AveBorderedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AveBorderedButton.m; sourceTree = \"<group>\"; };\n\t\t49324B6F1C276E420007A068 /* AveBorderedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AveBorderedView.h; sourceTree = \"<group>\"; };\n\t\t49324B701C276E420007A068 /* AveBorderedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AveBorderedView.m; sourceTree = \"<group>\"; };\n\t\t49324B721C276E420007A068 /* AvePurchaseActivityIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvePurchaseActivityIndicatorView.h; sourceTree = \"<group>\"; };\n\t\t49324B731C276E420007A068 /* AvePurchaseActivityIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AvePurchaseActivityIndicatorView.m; sourceTree = \"<group>\"; };\n\t\t49324B741C276E420007A068 /* AvePurchaseButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvePurchaseButton.h; sourceTree = \"<group>\"; };\n\t\t49324B751C276E420007A068 /* AvePurchaseButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AvePurchaseButton.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t49324B2D1C275EF20007A068 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t49324B271C275EF20007A068 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B321C275EF20007A068 /* PurchaseButtonExample */,\n\t\t\t\t49324B311C275EF20007A068 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B311C275EF20007A068 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B301C275EF20007A068 /* PurchaseButtonExample.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B321C275EF20007A068 /* PurchaseButtonExample */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B6B1C276E420007A068 /* Source */,\n\t\t\t\t49324B361C275EF20007A068 /* AppDelegate.h */,\n\t\t\t\t49324B371C275EF20007A068 /* AppDelegate.m */,\n\t\t\t\t49324B3C1C275EF20007A068 /* Main.storyboard */,\n\t\t\t\t49324B3F1C275EF20007A068 /* Assets.xcassets */,\n\t\t\t\t49324B411C275EF20007A068 /* LaunchScreen.storyboard */,\n\t\t\t\t49324B441C275EF20007A068 /* Info.plist */,\n\t\t\t\t49324B331C275EF20007A068 /* Supporting Files */,\n\t\t\t\t49324B541C2765930007A068 /* TableViewController.h */,\n\t\t\t\t49324B551C2765930007A068 /* TableViewController.m */,\n\t\t\t);\n\t\t\tpath = PurchaseButtonExample;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B331C275EF20007A068 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B341C275EF20007A068 /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B6B1C276E420007A068 /* Source */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B6C1C276E420007A068 /* BorderedButton */,\n\t\t\t\t49324B711C276E420007A068 /* PurchaseButton */,\n\t\t\t);\n\t\t\tname = Source;\n\t\t\tpath = ../../Source;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B6C1C276E420007A068 /* BorderedButton */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B6D1C276E420007A068 /* AveBorderedButton.h */,\n\t\t\t\t49324B6E1C276E420007A068 /* AveBorderedButton.m */,\n\t\t\t\t49324B6F1C276E420007A068 /* AveBorderedView.h */,\n\t\t\t\t49324B701C276E420007A068 /* AveBorderedView.m */,\n\t\t\t);\n\t\t\tpath = BorderedButton;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B711C276E420007A068 /* PurchaseButton */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B721C276E420007A068 /* AvePurchaseActivityIndicatorView.h */,\n\t\t\t\t49324B731C276E420007A068 /* AvePurchaseActivityIndicatorView.m */,\n\t\t\t\t49324B741C276E420007A068 /* AvePurchaseButton.h */,\n\t\t\t\t49324B751C276E420007A068 /* AvePurchaseButton.m */,\n\t\t\t);\n\t\t\tpath = PurchaseButton;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t49324B2F1C275EF20007A068 /* PurchaseButtonExample */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 49324B471C275EF20007A068 /* Build configuration list for PBXNativeTarget \"PurchaseButtonExample\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t49324B2C1C275EF20007A068 /* Sources */,\n\t\t\t\t49324B2D1C275EF20007A068 /* Frameworks */,\n\t\t\t\t49324B2E1C275EF20007A068 /* 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 = PurchaseButtonExample;\n\t\t\tproductName = PurchaseButtonExample;\n\t\t\tproductReference = 49324B301C275EF20007A068 /* PurchaseButtonExample.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t49324B281C275EF20007A068 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0720;\n\t\t\t\tORGANIZATIONNAME = AveApps;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t49324B2F1C275EF20007A068 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.2;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 49324B2B1C275EF20007A068 /* Build configuration list for PBXProject \"PurchaseButtonExample\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\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 = 49324B271C275EF20007A068;\n\t\t\tproductRefGroup = 49324B311C275EF20007A068 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t49324B2F1C275EF20007A068 /* PurchaseButtonExample */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t49324B2E1C275EF20007A068 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t49324B431C275EF20007A068 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t49324B401C275EF20007A068 /* Assets.xcassets in Resources */,\n\t\t\t\t49324B3E1C275EF20007A068 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t49324B2C1C275EF20007A068 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t49324B561C2765930007A068 /* TableViewController.m in Sources */,\n\t\t\t\t49324B761C276E420007A068 /* AveBorderedButton.m in Sources */,\n\t\t\t\t49324B381C275EF20007A068 /* AppDelegate.m in Sources */,\n\t\t\t\t49324B351C275EF20007A068 /* main.m in Sources */,\n\t\t\t\t49324B791C276E420007A068 /* AvePurchaseButton.m in Sources */,\n\t\t\t\t49324B771C276E420007A068 /* AveBorderedView.m in Sources */,\n\t\t\t\t49324B781C276E420007A068 /* AvePurchaseActivityIndicatorView.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t49324B3C1C275EF20007A068 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B3D1C275EF20007A068 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t49324B411C275EF20007A068 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t49324B421C275EF20007A068 /* 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\t49324B451C275EF20007A068 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\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_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\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 = gnu99;\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 = 9.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\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\t49324B461C275EF20007A068 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\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_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\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 = gnu99;\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 = 9.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\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\t49324B481C275EF20007A068 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = PurchaseButtonExample/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.aveapps.PurchaseButtonExample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t49324B491C275EF20007A068 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = PurchaseButtonExample/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.aveapps.PurchaseButtonExample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t49324B2B1C275EF20007A068 /* Build configuration list for PBXProject \"PurchaseButtonExample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t49324B451C275EF20007A068 /* Debug */,\n\t\t\t\t49324B461C275EF20007A068 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t49324B471C275EF20007A068 /* Build configuration list for PBXNativeTarget \"PurchaseButtonExample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t49324B481C275EF20007A068 /* Debug */,\n\t\t\t\t49324B491C275EF20007A068 /* 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 = 49324B281C275EF20007A068 /* Project object */;\n}\n"
  },
  {
    "path": "Example/PurchaseButtonExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:PurchaseButtonExample.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Andreas Verhoeven\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\nfurnished to 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 THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# AvePurchaseButton\nDrop In App Store Styled Purchase Button, with proper animations. Title configurable in Interface Builder.\n\n## Animations\nA gif-movie showing how the button animates from normal to confirmation to in-progress state:\n![Movie](https://cloud.githubusercontent.com/assets/168214/11920880/852741d6-a77a-11e5-839d-e2f572e49475.gif)\n\n\n## Screenshot\nA screenshot showing the different states of the button:\n![Screenshot](https://cloud.githubusercontent.com/assets/168214/11920878/7c5d708e-a77a-11e5-8553-3806e89ba434.png)\n\n## How to use\nCreate an instance of AvePurchaseButton. Set the normalTitle, confirmationTitle and handle UIControlEventTouchUpInside. To change states, use -[AvePurchaseButton setButtonState:animated:].\n\n## Example usage:\n```\n- (void)addPurchaseButton {\n  AvePurchaseButton* button = [[AvePurchaseButton alloc] initWithFrame:CGRectZero];\n\t[button addTarget:self action:@selector(purchaseButtonTapped:) forControlEvents:UIControlEventTouchUpInside];\n\tbutton.buttonState = AvePurchaseButtonStateNormal;\n\tbutton.normalTitle = @\"$ 2.99\";\n\tbutton.confirmationTitle = @\"BUY\";\n\t[button sizeToFit];\n\t[self.view addSubview:button];\n}\n\n- (void)purchaseButtonTapped:(AvePurchaseButton*)button {\n\tswitch(button.buttonState) {\n\t\tcase AvePurchaseButtonStateNormal:\n\t\t\t[button setButtonState:AvePurchaseButtonStateConfirmation animated:YES];\n\t\t\tbreak;\n\t\t\t\n\t\tcase AvePurchaseButtonStateConfirmation:\n\t\t\t// start the purchasing progress here, when done, go back to \n\t\t\t// AvePurchaseButtonStateProgress\n\t\t\t[button setButtonState:AvePurchaseButtonStateProgress animated:YES];\n\t\t\t\n\t\t\t[self startPurchaseWithCompletionHandler:^{\n\t\t\t   [button setButtonState:AvePurchaseButtonStateNormal animated:YES];\n\t\t\t}];\n\t\t\tbreak;\n\t\t\t\n\t\tcase AvePurchaseButtonStateProgress:\n\t\t\tbreak;\n\t}\n}\n\n```\n"
  },
  {
    "path": "Source/BorderedButton/AveBorderedButton.h",
    "content": "//\n// AveBorderedButton.h\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import <UIKit/UIKit.h>\n\n// defaults\nextern CGFloat kAveBorderedButtonDefaultBorderWidth;\nextern CGFloat kAveBorderedButtonDefaultCornerRadius;\n\n/*!\n @abstract Button that has a border and fills itself on highlighting.\n \n Use the .title property to change the title of this button.\n */\nIB_DESIGNABLE\n@interface AveBorderedButton : UIControl\n\n// title for this button - no differences between states\n@property (nonatomic, copy) IBInspectable NSString* title;\n@property (nonatomic, copy) IBInspectable NSAttributedString* attributedTitle;\n@property (nonatomic, strong) IBInspectable UIImage* image;\n\n// title properties\n@property (nonatomic, readonly) UILabel* titleLabel; // don't set .text property directly, use .title\n@property (nonatomic, assign) UIEdgeInsets titleEdgeInsets;\n\n// looks, animates when updated\n@property (nonatomic, assign) IBInspectable CGFloat borderWidth; // defaults to kAveBorderedButtonDefaultBorderWidth (animatable)\n@property (nonatomic, assign) IBInspectable CGFloat cornerRadius; // defaults to kAveBorderedButtonDefaultCornerRadius (animatable)\n\n@end\n"
  },
  {
    "path": "Source/BorderedButton/AveBorderedButton.m",
    "content": "//\n// AveBorderedButton.m\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import \"AveBorderedButton.h\"\n#import \"AveBorderedView.h\"\n\nCGFloat kAveBorderedButtonDefaultBorderWidth = 1.0;\nCGFloat kAveBorderedButtonDefaultCornerRadius = 4.0;\n\n@implementation AveBorderedButton\n{\n\tAveBorderedView* _borderView; // the border around the button\n\tUIImageView* _fillView; // the highlighting 'fill' when the button is tapped\n\tUIView* _labelClipView; // the title label is clipped\n\tUIImageView* _accessoryImageView; // accessoryImageView\n\tUIView* _accessoryAndLabelView;\n}\n\n#pragma mark - Initialization\n\n-(void)setup\n{\n\tif(nil == _titleLabel)\n\t{\n\t\t// defaults for properties\n\t\t_cornerRadius = kAveBorderedButtonDefaultCornerRadius;\n\t\t_borderWidth = kAveBorderedButtonDefaultBorderWidth;\n\t\t\n\t\t// view defaults\n\t\tself.backgroundColor = [UIColor clearColor];\n\t\t\n\t\t// the border view\n\t\t_borderView = [[AveBorderedView alloc] initWithFrame:self.bounds];\n\t\t_borderView.backgroundColor = [UIColor clearColor];\n\t\t_borderView.userInteractionEnabled = NO;\n\t\t_borderView.layer.cornerRadius = self.cornerRadius;\n\t\t_borderView.layer.borderWidth = self.borderWidth;\n\t\t[self addSubview:_borderView];\n\t\t\n\t\t// the title label is clipped inside this view\n\t\t_labelClipView = [[UIView alloc] initWithFrame:CGRectInset(self.bounds, 2, 2)];\n\t\t_labelClipView.backgroundColor = [UIColor clearColor];\n\t\t_labelClipView.opaque = NO;\n\t\t_labelClipView.clipsToBounds = YES;\n\t\t_labelClipView.userInteractionEnabled = NO;\n\t\t[self addSubview:_labelClipView];\n\t\t\n\t\t_accessoryAndLabelView = [[UIView alloc] initWithFrame:_labelClipView.bounds];\n\t\t_accessoryAndLabelView.backgroundColor = [UIColor clearColor];\n\t\t_accessoryAndLabelView.opaque = NO;\n\t\t[_labelClipView addSubview:_accessoryAndLabelView];\n\t\t\n\t\t_accessoryImageView = [[UIImageView alloc] initWithFrame:CGRectZero];\n\t\t[_accessoryAndLabelView addSubview:_accessoryImageView];\n\t\t\n\t\t// the title label itself\n\t\t_titleLabel = [[UILabel alloc] initWithFrame:_accessoryImageView.bounds];\n\t\t_titleLabel.opaque = NO;\n\t\t_titleLabel.backgroundColor = [UIColor clearColor];\n\t\t_titleLabel.font = [UIFont systemFontOfSize:[UIFont buttonFontSize]];\n\t\t_titleLabel.userInteractionEnabled = NO;\n\t\t_titleLabel.textAlignment = NSTextAlignmentCenter;\n\t\t[_accessoryAndLabelView addSubview:_titleLabel];\n\t\t\n\t\t[self updateTintColors];\n\t}\n}\n\n-(id)init\n{\n\tself = [super init];\n\tif(self != nil)\n\t{\n\t\t[self setup];\n\t}\n\t\n\treturn self;\n}\n\n-(id)initWithCoder:(NSCoder *)aDecoder\n{\n\tself = [super initWithCoder:aDecoder];\n\tif(self != nil)\n\t{\n\t\t[self setup];\n\t}\n\t\n\treturn self;\n}\n\n-(id)initWithFrame:(CGRect)frame\n{\n\tself = [super initWithFrame:frame];\n\tif(self != nil)\n\t{\n\t\t[self setup];\n\t}\n\t\n\treturn self;\n}\n\n-(CGSize)sizeThatFits:(CGSize)size\n{\n\tCGSize s = [self.titleLabel sizeThatFits:size];\n\tif(self.image != nil)\n\t{\n\t\ts.width += s.height - 8;\n\t}\n\t\n\ts.width += 20; // add some spacing\n\ts.height += 8;\n\ts.width = ceilf(s.width);\n\ts.height = ceilf(s.height);\n\treturn s;\n}\n\n#pragma mark - Properties\n\n-(void)setCornerRadius:(CGFloat)cornerRadius\n{\n\tif(cornerRadius != _cornerRadius)\n\t{\n\t\t_cornerRadius = cornerRadius;\n\t\t_borderView.layer.cornerRadius = self.cornerRadius;\n\t}\n}\n\n\n-(void)setBorderWidth:(CGFloat)borderWidth\n{\n\tif(borderWidth != _borderWidth)\n\t{\n\t\t_borderWidth = borderWidth;\n\t\t_borderView.layer.borderWidth = self.borderWidth;\n\t}\n}\n\n-(BOOL)shouldShowFillView\n{\n\treturn self.highlighted;\n}\n\n#pragma mark - Layout code\n-(void)layoutSubviews\n{\n\t[super layoutSubviews];\n\t_borderView.frame = self.bounds;\n\t_fillView.frame = self.bounds;\n\t_labelClipView.frame = CGRectInset(_borderView.bounds, 2, 2);\n\t_accessoryAndLabelView.frame = UIEdgeInsetsInsetRect(_labelClipView.bounds, self.titleEdgeInsets);\n\t\n\t_accessoryImageView.frame = _accessoryImageView.image != nil ? CGRectInset(CGRectMake(0, 0, CGRectGetHeight(_accessoryAndLabelView.bounds), CGRectGetHeight(_accessoryAndLabelView.bounds)), 4, 4) : CGRectZero;\n\t_titleLabel.frame = CGRectMake(CGRectGetMaxX(_accessoryImageView.frame), 0, CGRectGetWidth(_accessoryAndLabelView.bounds) - CGRectGetMaxX(_accessoryImageView.frame), CGRectGetHeight(_accessoryAndLabelView.bounds));\n}\n\n\n#pragma mark - FillView\n\n-(void)ensureFillView\n{\n\tif(nil == _fillView)\n\t{\n\t\t_fillView = [[UIImageView alloc] initWithFrame:self.bounds];\n\t\t_fillView.userInteractionEnabled = NO;\n\t\t_fillView.alpha = 0;\n\t\t_fillView.layer.cornerRadius = self.cornerRadius;\n\t\t[self insertSubview:_fillView aboveSubview:_borderView];\n\t}\n}\n\n-(UIImage*)fillViewMaskImage\n{\n\tCGFloat actualWidth = _fillView.bounds.size.width;\n\tCGFloat actualHeight = _fillView.bounds.size.height;\n\tCGFloat deviceScale = [UIScreen mainScreen].scale;\n \n\tCGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();\n\tCGContextRef context = CGBitmapContextCreate(nil, actualWidth * deviceScale, actualHeight * deviceScale, 8, 0, colorSpace, (CGBitmapInfo)kCGImageAlphaNone);\n\tCGContextScaleCTM(context, deviceScale, deviceScale);\n\tCGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);\n\tCGContextFillRect(context, _fillView.bounds);\n\t\n\tCGContextSetBlendMode(context, kCGBlendModeMultiply);\n\tCGContextDrawImage(context, [_accessoryImageView convertRect:_accessoryImageView.bounds toView:_fillView], self.image.CGImage);\n \n\tCGImageRef grayImage = CGBitmapContextCreateImage(context);\n\tCGColorSpaceRelease(colorSpace);\n\tCGContextRelease(context);\n\t\n\treturn [UIImage imageWithCGImage:grayImage scale:deviceScale orientation:UIImageOrientationUp];\n}\n\n-(UIImage*)fillViewImage\n{\n    if(_fillView.bounds.size.width <= 0 || _fillView.bounds.size.height <= 0)\n        return nil;\n    \n\tUIGraphicsBeginImageContextWithOptions(_fillView.bounds.size, NO, 0.0);\n\t\n\t[self.compatibleTintColor setFill]; // This image won't get tinted on iOS6, so pre-fill it with the right color\n\t\n\t// fill the background with a rounded corner\n\tUIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.cornerRadius];\n\t[path fill];\n\t\n\t// cut out the title by drawing the title label with a 'clear' blend mode\n\tCGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);\n\t[_titleLabel drawTextInRect:[self.titleLabel convertRect:self.titleLabel.bounds toView:_fillView]];\n\t\n\tUIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n\tUIGraphicsEndImageContext();\n\t\n\tif(self.image != nil)\n\t{\n\t\tCGImageRef cgImage = CGImageCreateWithMask(image.CGImage, self.fillViewMaskImage.CGImage);\n\t\timage = [UIImage imageWithCGImage:cgImage];\n\t}\n\t\n\treturn [image respondsToSelector:@selector(imageWithRenderingMode:)] ? [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] : image;\n}\n\n-(void)updateFillView\n{\n\t[self ensureFillView];\n\t_fillView.image = [self fillViewImage];\n}\n\n-(void)updateFillViewWhenNeeded\n{\n\t_fillView.image = nil;\n\tif(_fillView.alpha != 0)\n\t{\n\t\t[self updateFillView];\n\t}\n}\n\n#pragma mark - Highlighting\n\n-(void)updateHighlightedStateAnimated\n{\n\t[self updateFillView];\n\t\n\t[UIView animateWithDuration:0.45 animations:^{\n\t\t_fillView.alpha = [self shouldShowFillView] ? 1 : 0;\n\t\t_accessoryAndLabelView.alpha = [self shouldShowFillView] ? 0 : 1;\n\t} completion:nil];\n}\n\n-(void)setHighlighted:(BOOL)highlighted\n{\n\t[super setHighlighted:highlighted];\n\t[self updateHighlightedStateAnimated];\n}\n\n#pragma mark - set Text\n-(void)setTitle:(NSString *)title\n{\n\tself.titleLabel.text = title;\n\t[self updateFillViewWhenNeeded];\n}\n\n-(NSString*)title\n{\n\treturn self.titleLabel.text;\n}\n\n-(void)setAttributedTitle:(NSAttributedString *)attributedTitle\n{\n\tself.titleLabel.attributedText = attributedTitle;\n\t[self updateFillViewWhenNeeded];\n}\n\n-(NSAttributedString*)attributedTitle\n{\n\treturn self.titleLabel.attributedText;\n}\n\n#pragma mark - Set Image\n-(void)setImage:(UIImage *)image\n{\n\t_accessoryImageView.image = image;\n\t[self updateFillViewWhenNeeded];\n}\n\n-(UIImage*)image\n{\n\treturn _accessoryImageView.image;\n}\n\n#pragma mark - responding to updates\n-(void)setFrame:(CGRect)frame\n{\n\tBOOL sizeChanged = !CGSizeEqualToSize(frame.size, self.bounds.size);\n\t[super setFrame:frame];\n\tif(sizeChanged)\n\t{\n\t\t[self updateFillViewWhenNeeded];\n\t}\n}\n\n#pragma mark - set TintColor\n\n-(BOOL)supportsTintColor\n{\n\treturn [[[UIDevice currentDevice] systemVersion] floatValue] >= 7;\n}\n\n-(UIColor*)compatibleTintColor\n{\n\tif([self supportsTintColor])\n\t\treturn self.tintColor;\n\telse\n\t\treturn [UIColor colorWithRed:3.0/255.0 green:122.0/255.0 blue:255.0/255.0 alpha:1];\n}\n\n-(void)setTintColor:(UIColor *)tintColor\n{\n\tif([self supportsTintColor])\n\t{\n\t\t[super setTintColor:tintColor];\n\t\t[self updateTintColors];\n\t}\n}\n\n-(void)tintColorDidChange\n{\n\t[super tintColorDidChange];\n\t[self updateTintColors];\n}\n\n-(void)didMoveToWindow\n{\n\t[super didMoveToWindow];\n\t[self updateTintColors];\n}\n\n-(void)updateTintColors\n{\n\t_borderView.layer.borderColor = self.compatibleTintColor.CGColor;\n\t_titleLabel.textColor = self.compatibleTintColor;\n}\n\n@end\n"
  },
  {
    "path": "Source/BorderedButton/AveBorderedView.h",
    "content": "//\n//  AveBorderedView.h\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import <UIKit/UIKit.h>\n\n/*!\n @abstract view that has a border and a cornerRadius.\n \n Use the .title property to change the title of this button.\n */\nIB_DESIGNABLE\n@interface AveBorderedView : UIView\n\n@property (nonatomic, strong) IBInspectable UIColor* borderColor; // animatable\n@property (nonatomic, assign) IBInspectable CGFloat borderWidth; // animatable\n@property (nonatomic, assign) IBInspectable CGFloat cornerRadius; // animatable\n\n@end\n"
  },
  {
    "path": "Source/BorderedButton/AveBorderedView.m",
    "content": "//\n//  AveBorderedView.m\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import \"AveBorderedView.h\"\n\n@implementation AveBorderedView\n\n-(id)initWithCoder:(NSCoder *)aDecoder\n{\n\tself = [super initWithCoder:aDecoder];\n\tif(self != nil)\n\t{\n\t\t[self initDefaults];\n\t\t[self updateBorder];\n\t}\n\t\n\treturn self;\n}\n\n-(instancetype)initWithFrame:(CGRect)frame\n{\n\tself = [super initWithFrame:frame];\n\tif(self != nil)\n\t{\n\t\t[self initDefaults];\n\t\t[self updateBorder];\n\t}\n\t\n\treturn self;\n}\n\n-(instancetype)init\n{\n\tself = [super init];\n\tif(self != nil)\n\t{\n\t\t[self initDefaults];\n\t\t[self updateBorder];\n\t}\n\t\n\treturn self;\n}\n\n-(void)initDefaults\n{\n\t_cornerRadius = 4;\n\t_borderWidth = 1;\n\t_borderColor = [UIColor blueColor];\n}\n\n-(void)updateBorder\n{\n\tself.layer.borderWidth = self.borderWidth;\n\tself.layer.borderColor = self.borderColor.CGColor;\n\tself.layer.cornerRadius = self.cornerRadius;\n}\n\n-(void)setBorderColor:(UIColor *)borderColor\n{\n\t_borderColor = borderColor;\n\t[self updateBorder];\n}\n\n-(void)setBorderWidth:(CGFloat)borderWidth\n{\n\t_borderWidth = borderWidth;\n\t[self updateBorder];\n}\n\n-(void)setCornerRadius:(CGFloat)cornerRadius\n{\n\t_cornerRadius = cornerRadius;\n\t[self updateBorder];\n}\n\n- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key\n{\n\tif([key isEqualToString:@\"borderColor\"] || [key isEqualToString:@\"cornerRadius\"] || [key isEqualToString:@\"borderWidth\"])\n\t{\n\t\t// piggy back on the animation for opacity, which only will be non nil if we are in an animation block.\n\t\t// This way, we will only animate those properties when in an animation block.\n\t\tCABasicAnimation* animation = (CABasicAnimation*)[layer actionForKey:@\"opacity\"];\n\t\tif([animation isKindOfClass:[CABasicAnimation class]])\n\t\t{\n\t\t\tanimation.keyPath = key;\n\t\t\tanimation.fromValue = [layer valueForKey:key];\n\t\t\tanimation.toValue = nil;\n\t\t\tanimation.byValue = nil;\n\t\t\treturn animation;\n\t\t}\n\t}\n\t\n\t\n\treturn [super actionForLayer:layer forKey:key];\n}\n\n@end\n"
  },
  {
    "path": "Source/PurchaseButton/AvePurchaseActivityIndicatorView.h",
    "content": "//\n//  AvePurchaseActivityIndicatorView.h\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import <UIKit/UIKit.h>\n\n/**\n Activity indicator as used by AverPurchaseButton. Shows a rotating arc.\n */\n@interface AvePurchaseActivityIndicatorView : UIView\n\n@property (nonatomic, assign) CGFloat lineWidth;\n\n- (void)startAnimating;\n- (void)stopAnimating;\n- (BOOL)isAnimating;\n\n@end\n"
  },
  {
    "path": "Source/PurchaseButton/AvePurchaseActivityIndicatorView.m",
    "content": "//\n//  AvePurchaseActivityIndicatorView.m\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import \"AvePurchaseActivityIndicatorView.h\"\n\nstatic NSString* const kAvePurchaseActivityIndicatorViewRotationAnimationKey = @\"AvePurchaseActivityIndicatorViewRotationAnimationKey\";\n\n@implementation AvePurchaseActivityIndicatorView\n{\n\tUIImageView* _imageView;\n\tBOOL _animating;\n}\n\n-(void)dealloc\n{\n\t[[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n-(void)ensureImageView\n{\n\tif(nil == _imageView)\n\t{\n\t\t_imageView = [[UIImageView alloc] initWithFrame:self.bounds];\n\t\t_imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;\n\t\t[self addSubview:_imageView];\n\t}\n}\n\n-(void)setTintColor:(UIColor *)tintColor\n{\n\tif([self respondsToSelector:@selector(tintColor)]) // for iOS6 compatibility\n\t{\n\t\t[super setTintColor:tintColor];\n\t}\n}\n\n- (void)layoutSubviews\n{\n\t[super layoutSubviews];\n\t\n\tCGSize size = self.bounds.size;\n\t_imageView.bounds = CGRectMake(0, 0, size.width, size.height);\n\t_imageView.center = CGPointMake(size.width * 0.5, size.height * 0.5);\n}\n\n#pragma mark - Animation\n\n-(void)startAnimating\n{\n\tif(!_animating)\n\t{\n\t\t_animating = YES;\n\t\t\n\t\t// CA animations are removed when an app moves to the background, so we need to monitor for the app going to the\n\t\t// foreground in order to restart the rotation animation.\n\t\t[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];\n\t}\n\t\n\t[self ensureImageView];\n\t[self ensureImageViewImage];\n\t[self ensureRotationAnimation];\n}\n\n-(void)stopAnimating\n{\n\tif(_animating)\n\t{\n\t\t_animating = NO;\n\t\t[_imageView.layer removeAnimationForKey:kAvePurchaseActivityIndicatorViewRotationAnimationKey];\n\t\t\n\t\t// not animating anymore, so no need to know when the app goes to the foreground\n\t\t[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];\n\t}\n}\n\n-(BOOL)isAnimating\n{\n\treturn _animating;\n}\n\n-(void)ensureRotationAnimation\n{\n\tif([_imageView.layer animationForKey:kAvePurchaseActivityIndicatorViewRotationAnimationKey] == nil)\n\t{\n\t\tCABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@\"transform.rotation.z\"];\n\t\trotationAnimation.toValue = @(M_PI * 2.0);\n\t\trotationAnimation.duration = 1.0;\n\t\trotationAnimation.cumulative = YES;\n\t\trotationAnimation.repeatCount =  HUGE_VALF;\n\t\t[_imageView.layer addAnimation:rotationAnimation forKey:kAvePurchaseActivityIndicatorViewRotationAnimationKey];\n\t}\n}\n\n-(void)didMoveToWindow\n{\n\t[super didMoveToWindow];\n\t\n\t// CA animations are also removed when a view is removed from a window,\n\t// so we need to restart the rotation animation if needed\n\t[self ensureAnimatingWhenNeeded];\n}\n\n-(void)_applicationWillEnterForeground\n{\n\t[self ensureAnimatingWhenNeeded];\n}\n\n-(void)ensureAnimatingWhenNeeded\n{\n\tif(_animating && self.window != nil)\n\t{\n\t\t[self ensureImageViewImage];\n\t\t[self ensureRotationAnimation];\n\t}\n}\n\n-(void)setFrame:(CGRect)frame\n{\n\tBOOL sizeChanged = !CGSizeEqualToSize(frame.size, self.bounds.size);\n\t[super setFrame:frame];\n\tif(sizeChanged)\n\t{\n\t\t[self resetImageViewImage];\n\t}\n}\n\n-(CGFloat)lineWidth\n{\n\treturn _lineWidth == 0 ? 1 : _lineWidth;\n}\n\n#pragma mark - Image\n\n-(void)ensureImageViewImage\n{\n\tif(_imageView.image == nil)\n\t{\n\t\t_imageView.image = [self imageForAnimation];\n\t}\n}\n\n-(void)resetImageViewImage\n{\n\t_imageView.image = nil;\n\tif(_animating && self.window != nil)\n\t{\n\t\t[self ensureImageViewImage];\n\t}\n}\n\n-(UIImage*)imageForAnimation\n{\n\tCGRect rc = self.bounds;\n\tif(CGRectIsEmpty(rc) || CGRectIsNull(rc))\n\t\treturn nil;\n\t\n\tUIGraphicsBeginImageContextWithOptions(rc.size, NO, 0.0);\n\t\n\t// use blue, for iOS6 compatibility, since the image won't get tinted on iOS6\n\t[[UIColor colorWithRed:3.0/255.0 green:122.0/255.0 blue:255.0/255.0 alpha:1] setStroke];\n\t\n\t// create a circle\n\tCGContextSaveGState(UIGraphicsGetCurrentContext());\n\tUIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:rc];\n\tpath.lineWidth = self.lineWidth * 2;\n\t[path addClip];\n\t[path stroke];\n\tCGContextRestoreGState(UIGraphicsGetCurrentContext());\n\t\n\t// cut-out a hole\n\tUIRectFillUsingBlendMode(CGRectMake(rc.size.width - 6, rc.size.height / 2.0 - 2, 6, 6), kCGBlendModeClear);\n\t\n\tUIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n\tUIGraphicsEndImageContext();\n\t\n\treturn [image respondsToSelector:@selector(imageWithRenderingMode:)] ? [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] : image;\n}\n\n@end\n"
  },
  {
    "path": "Source/PurchaseButton/AvePurchaseButton.h",
    "content": "//\n//  AvePurchaseButton.h\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import <UIKit/UIKit.h>\n\ntypedef NS_ENUM(NSUInteger, AvePurchaseButtonState)\n{\n\tAvePurchaseButtonStateNormal,\t\t// normal, colored button\n\tAvePurchaseButtonStateConfirmation,\t// confirmation button, using the confirmationTitle/Color\n\tAvePurchaseButtonStateProgress,\t\t// progress indicator state\n};\n\n/**\n @abstract A button which toggles between different states\n */\nIB_DESIGNABLE\n@interface AvePurchaseButton : UIControl\n\n@property (nonatomic, assign) IBInspectable AvePurchaseButtonState buttonState;\n-(void)setButtonState:(AvePurchaseButtonState)buttonState animated:(BOOL)animated;\n\n@property (nonatomic, strong) IBInspectable UIImage* image;\n\n//Button font\n@property (nonatomic, strong) IBInspectable UIFont* titleLabelFont;\n\n// normal state colors\n@property (nonatomic, copy) IBInspectable NSString* normalTitle;\n@property (nonatomic, copy) IBInspectable NSAttributedString* attributedNormalTitle;\n@property (nonatomic, retain) IBInspectable UIColor* normalColor; // needed, equals tintColor\n\n// confirmation state colors\n@property (nonatomic, copy) IBInspectable NSString* confirmationTitle;\n@property (nonatomic, copy) IBInspectable NSAttributedString* attributedConfirmationTitle;\n@property (nonatomic, retain) IBInspectable UIColor* confirmationColor;\n\n@end\n"
  },
  {
    "path": "Source/PurchaseButton/AvePurchaseButton.m",
    "content": "//\n//  AvePurchaseButton.m\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2015 Andreas Verhoeven\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#import \"AvePurchaseButton.h\"\n#import \"AvePurchaseActivityIndicatorView.h\"\n#import \"AveBorderedButton.h\"\n\n@implementation AvePurchaseButton\n{\n\tAveBorderedButton* _button;\n\tAvePurchaseActivityIndicatorView* _activityIndicatorView;\n\t\n\tNSString* _normalTitle;\n\tNSString* _confirmationTitle;\n\t\n\tNSAttributedString* _attributedNormalTitle;\n\tNSAttributedString* _attributedConfirmationTitle;\n}\n\n-(id)initWithFrame:(CGRect)frame\n{\n\tself = [super initWithFrame:frame];\n\tif(self != nil)\n\t{\n\t\t[self setup];\n\t}\n\t\n\treturn self;\n}\n\n-(id)initWithCoder:(NSCoder *)aDecoder\n{\n\tself = [super initWithCoder:aDecoder];\n\tif(self != nil)\n\t{\n\t\t[self setup];\n\t}\n\t\n\treturn self;\n}\n\n-(void)setup\n{\n\tself.clearsContextBeforeDrawing = YES;\n\tself.backgroundColor = [UIColor clearColor];\n\n\tself.confirmationColor = [UIColor colorWithRed:0 green:0.5 blue:0 alpha:1];\n\t\n\t_button = [[AveBorderedButton alloc] initWithFrame:self.bounds];\n\t_button.titleLabel.font = [UIFont boldSystemFontOfSize:14];\n\t_button.userInteractionEnabled = NO;\n\t[self addSubview:_button];\n\t\n\t_activityIndicatorView = [[AvePurchaseActivityIndicatorView alloc] init];\n\t_activityIndicatorView.userInteractionEnabled = NO;\n\t[self addSubview:_activityIndicatorView];\n}\n\n-(void)layoutSubviews\n{\n\t[super layoutSubviews];\n\t\n\tCGFloat progressSize = self.bounds.size.height;\n\tCGRect progressFrame = CGRectMake(self.bounds.size.width - progressSize,0, progressSize, progressSize);\n\t_activityIndicatorView.frame = progressFrame;\n\t\n\tif(self.buttonState != AvePurchaseButtonStateProgress)\n\t{\n\t\t_button.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));\n\t}\n\telse\n\t{\n\t\t_button.frame = progressFrame;\n\t}\n}\n\n-(void)setImage:(UIImage *)image\n{\n\t_button.image = image;\n}\n\n-(UIImage*)image\n{\n\treturn _button.image;\n}\n\n-(void)setButtonState:(AvePurchaseButtonState)buttonState\n{\n\t[self setButtonState:buttonState animated:NO];\n}\n\n-(void)stopProgressAnimation\n{\n\t_activityIndicatorView.alpha = 0;\n\t_button.alpha = 1;\n\t[_activityIndicatorView stopAnimating];\n}\n\n-(void)configureButtonForProgressState\n{\n\t_button.cornerRadius = self.bounds.size.height / 2.0;\n\t_button.titleEdgeInsets = UIEdgeInsetsMake(0, self.bounds.size.height, 0, -(self.bounds.size.width - self.bounds.size.height) - self.bounds.size.height);\n\t_button.frame = CGRectMake(self.bounds.size.width - self.bounds.size.height, 0, self.bounds.size.height, self.bounds.size.height);\n}\n\n-(void)configureButtonForRegularState\n{\n\t_button.cornerRadius = kAveBorderedButtonDefaultCornerRadius;\n\t_button.titleEdgeInsets = UIEdgeInsetsZero;\n\t_button.frame = self.bounds;\n}\n\n-(void)setButtonState:(AvePurchaseButtonState)buttonState animated:(BOOL)animated\n{\n\tif(buttonState != self.buttonState)\n\t{\n\t\t_buttonState = buttonState;\n\t\t[self updateTintColors];\n\t\t[self updateTitle];\n\t\t\n\t\tif(self.buttonState == AvePurchaseButtonStateProgress)\n\t\t{\n\t\t\tif(animated)\n\t\t\t{\n\t\t\t\t// don't animate the button highlight state. (use iOS6 compatible transactions, instead of performWithoutAnimation:)\n\t\t\t\t[CATransaction begin];\n\t\t\t\t[CATransaction setDisableActions:YES];\n\t\t\t\t_button.highlighted = NO;\n\t\t\t\t[CATransaction commit];\n\t\t\t\t\n\t\t\t\t[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{\n\t\t\t\t\t[self configureButtonForProgressState];\n\t\t\t\t} completion:^(BOOL finished){\n\t\t\t\t\tif(self.buttonState == AvePurchaseButtonStateProgress)\n\t\t\t\t\t{\n\t\t\t\t\t\t[self updateTintColors];\n\t\t\t\t\t\t[UIView animateWithDuration:0.5 animations:^{\n\t\t\t\t\t\t\t_button.alpha = 0;\n\t\t\t\t\t\t\t_activityIndicatorView.alpha = 1;\n\t\t\t\t\t\t\t[_activityIndicatorView startAnimating];\n\t\t\t\t\t\t}];\n\t\t\t\t\t}\n\t\t\t\t}];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t[self configureButtonForProgressState];\n\t\t\t\t\n\t\t\t\t_button.alpha = 0;\n\t\t\t\t_activityIndicatorView.alpha = 1;\n\t\t\t\t[_activityIndicatorView startAnimating];\n\t\t\t\t[self setNeedsLayout];\n\t\t\t}\n\t\t}\n\t\telse if(self.buttonState == AvePurchaseButtonStateNormal)\n\t\t{\n\t\t\t_button.alpha = 1;\n\t\t\t_activityIndicatorView.alpha = 0;\n\t\t\t\n\t\t\tif(animated)\n\t\t\t{\n\t\t\t\t[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{\n\t\t\t\t\t[self configureButtonForRegularState];\n\t\t\t\t} completion:^(BOOL finished){\n\t\t\t\t\t[self updateTintColors];\n\t\t\t\t}];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t[self configureButtonForRegularState];\n\t\t\t\t[self setNeedsLayout];\n\t\t\t}\n\t\t}\n\t\telse if(self.buttonState == AvePurchaseButtonStateConfirmation)\n\t\t{\n\t\t\t[self configureButtonForRegularState];\n\t\t\t[self setNeedsLayout];\n\t\t}\n\t}\n\telse if(self.buttonState == AvePurchaseButtonStateProgress && !animated)\n\t{\n\t\t// make sure we restart animation in re-used TableViewCells: they remove\n\t\t// all subview animations when they get reused.\n\t\t[_activityIndicatorView startAnimating];\n\t}\n}\n\n\n- (void)setNormalColor:(UIColor *)normalColor\n{\n\t_normalColor = normalColor;\n\t[self updateTintColors];\n}\n\n-(void)setNormalTitle:(NSString *)normalTitle\n{\n\t_normalTitle = [normalTitle copy];\n\t_attributedNormalTitle = nil;\n\t[self updateTitle];\n}\n\n-(NSString*)normalTitle\n{\n\tif(_normalTitle != nil)\n\t\treturn _normalTitle;\n\telse if(_attributedNormalTitle != nil)\n\t\treturn _attributedNormalTitle.string;\n\telse\n\t\treturn nil;\n}\n\n-(void)setAttributedNormalTitle:(NSAttributedString *)attributedNormalTitle\n{\n\t_attributedNormalTitle = [attributedNormalTitle copy];\n\t_normalTitle = nil;\n\t[self updateTitle];\n}\n\n-(NSAttributedString*)attributedNormalTitle\n{\n\tif(_attributedNormalTitle != nil)\n\t\treturn _attributedNormalTitle;\n\telse if(_normalTitle != nil)\n\t\treturn [[NSAttributedString alloc] initWithString:_normalTitle];\n\telse\n\t\treturn nil;\n}\n\n- (void)setConfirmationColor:(UIColor *)confirmationColor\n{\n\t_confirmationColor = confirmationColor;\n\t[self updateTintColors];\n}\n\n-(void)setConfirmationTitle:(NSString *)confirmationTitle\n{\n\t_confirmationTitle = [confirmationTitle copy];\n\t_attributedConfirmationTitle = nil;\n\t[self updateTitle];\n}\n\n-(NSString*)confirmationTitle\n{\n\tif(_confirmationTitle != nil)\n\t\treturn _confirmationTitle;\n\telse if(_attributedConfirmationTitle != nil)\n\t\treturn _attributedConfirmationTitle.string;\n\telse\n\t\treturn nil;\n}\n\n-(void)setAttributedConfirmationTitle:(NSAttributedString *)attributedConfirmationTitle\n{\n\t_attributedConfirmationTitle = [attributedConfirmationTitle copy];\n\t_confirmationTitle = nil;\n\t[self updateTitle];\n}\n\n-(NSAttributedString*)attributedConfirmationTitle\n{\n\tif(_attributedConfirmationTitle != nil)\n\t\treturn _attributedConfirmationTitle.copy;\n\telse if(_confirmationTitle != nil)\n\t\treturn [[NSAttributedString alloc] initWithString:_confirmationTitle];\n\telse\n\t\treturn nil;\n}\n\n-(CGSize)sizeThatFits:(CGSize)size\n{\n\treturn [_button sizeThatFits:size];\n}\n\n-(CGSize)intrinsicContentSize\n{\n\treturn [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];\n}\n\n-(void)updateTitle\n{\n\tif(self.buttonState == AvePurchaseButtonStateConfirmation)\n\t{\n\t\tif(_attributedConfirmationTitle != nil)\n\t\t\t_button.attributedTitle = _attributedConfirmationTitle;\n\t\telse\n\t\t\t_button.title = _confirmationTitle;\n\t}\n\telse\n\t{\n\t\tif(_attributedNormalTitle != nil)\n\t\t\t_button.attributedTitle = _attributedNormalTitle;\n\t\telse\n\t\t\t_button.title = _normalTitle;\n\t}\n\t\n\t[self invalidateIntrinsicContentSize];\n}\n\n-(void)updateTintColors\n{\n\t_button.tintColor = self.buttonState == AvePurchaseButtonStateConfirmation ? self.confirmationColor : self.normalColor;\n\t_activityIndicatorView.tintColor = self.buttonState == AvePurchaseButtonStateConfirmation ? self.confirmationColor : self.normalColor;\n}\n\n-(void)setHighlighted:(BOOL)highlighted\n{\n\t[super setHighlighted:highlighted];\n\t_button.highlighted = highlighted && self.buttonState != AvePurchaseButtonStateProgress;\n}\n\n-(UIFont *)titleLabelFont\n{\n    return _button.titleLabel.font;\n}\n\n-(void)setTitleLabelFont:(UIFont *)font\n{\n    _button.titleLabel.font = font;\n    [self invalidateIntrinsicContentSize];\n}\n\n@end\n"
  }
]