2
0

Lots of UI improvements and tips + parental gate, guide update.

[IMPROVED]  Emergency VC can now scroll when keyboard is up.
[IMPROVED]  Language of the guide + new updated screenshots.
[FIXED]     Size of guide cells on different devices.
[IMPROVED]  Don't show messages claiming login name was updated when nothing changed.
[FIXED]     Weird back-toggle bug when toggling site settings.
[ADDED]     Lots of handy tips throughout.
[ADDED]     Notification of new store features.
[FIXED]     Weird sizing issue & animation with store cells.
[ADDED]     Loading spinner while loading store products.
[ADDED]     Thanks link to store footer.
[FIXED]     Bought products should not respond to click, non-bought ones should.
[FIXED]     Fuel elapsed time counter was backward.
[ADDED]     Parental gate when deleting or resetting users.
[UPDATED]   App Icon background texture.
This commit is contained in:
Maarten Billemont 2014-09-28 22:15:55 -04:00
parent 5e8810c535
commit 41b3964363
102 changed files with 1108 additions and 466 deletions

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "External/KCOrderedAccessorFix"]
path = External/KCOrderedAccessorFix
url = https://github.com/CFKevinRef/KCOrderedAccessorFix.git
[submodule "External/AttributedMarkdown"]
path = External/AttributedMarkdown
url = https://github.com/dreamwieber/AttributedMarkdown.git

1
External/AttributedMarkdown vendored Submodule

@ -0,0 +1 @@
Subproject commit d598fb4f5e29f5aaa66e7e880a9857019865881b

View File

@ -22,6 +22,8 @@
<string>https://github.com/CFKevinRef/KCOrderedAccessorFix.git</string>
<key>3E67FB08419C920516AAC3B00DAAF23073B8CF77</key>
<string>git://github.com/lhunath/RHStatusItemView.git</string>
<key>3ED8592497DB6A564366943C9AAD5A46341B5076</key>
<string>https://github.com/dreamwieber/AttributedMarkdown.git</string>
<key>4DDCFFD91B41F00326AD14553BD66CFD366ABD91</key>
<string>ssh://github.com/Lyndir/Pearl.git</string>
<key>8A15A8EA0B3D0B497C4883425BC74DF995224BB3</key>
@ -47,6 +49,8 @@
<string>../External/KCOrderedAccessorFix</string>
<key>3E67FB08419C920516AAC3B00DAAF23073B8CF77</key>
<string>../External/RHStatusItemView</string>
<key>3ED8592497DB6A564366943C9AAD5A46341B5076</key>
<string>../External/AttributedMarkdown/</string>
<key>4DDCFFD91B41F00326AD14553BD66CFD366ABD91</key>
<string>../External/Pearl</string>
<key>8A15A8EA0B3D0B497C4883425BC74DF995224BB3</key>
@ -72,6 +76,14 @@
<key>IDESourceControlWCCName</key>
<string></string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>3ED8592497DB6A564366943C9AAD5A46341B5076</string>
<key>IDESourceControlWCCName</key>
<string>AttributedMarkdown</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>

View File

@ -11,6 +11,8 @@
#define MPProductGenerateLogins @"com.lyndir.masterpassword.products.generatelogins"
#define MPProductGenerateAnswers @"com.lyndir.masterpassword.products.generateanswers"
#define MPProductOSIntegration @"com.lyndir.masterpassword.products.osintegration"
#define MPProductTouchID @"com.lyndir.masterpassword.products.touchid"
#define MPProductFuel @"com.lyndir.masterpassword.products.fuel"
#define MP_FUEL_HOURLY_RATE 30.f /* Tier 1 purchases/h ~> USD/h */

View File

@ -81,6 +81,16 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
- (void)purchaseProductWithIdentifier:(NSString *)productIdentifier quantity:(NSInteger)quantity {
#if TARGET_OS_IPHONE
if (![[MPAppDelegate_Shared get] canMakePayments]) {
[PearlAlert showAlertWithTitle:@"Store Not Set Up" message:
@"Try logging using the App Store or from Settings."
viewStyle:UIAlertViewStyleDefault initAlert:nil
tappedButtonBlock:nil cancelTitle:@"Thanks" otherTitles:nil];
return;
}
#endif
for (SKProduct *product in self.products)
if ([product.productIdentifier isEqualToString:productIdentifier]) {
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];

View File

@ -0,0 +1,13 @@
//
// AttributedMarkdown.h
// AttributedMarkdown
//
// Created by Maarten Billemont on 2014-09-28.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface AttributedMarkdown : NSObject
@end

View File

@ -0,0 +1,13 @@
//
// AttributedMarkdown.m
// AttributedMarkdown
//
// Created by Maarten Billemont on 2014-09-28.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import "AttributedMarkdown.h"
@implementation AttributedMarkdown
@end

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.lyndir.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -19,6 +19,7 @@
@interface MPEmergencyViewController : UIViewController <UITextFieldDelegate>
@property(weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property(weak, nonatomic) IBOutlet UIView *dialogView;
@property(weak, nonatomic) IBOutlet UIView *containerView;
@property(weak, nonatomic) IBOutlet UITextField *userNameField;

View File

@ -45,6 +45,8 @@
^(MPEmergencyViewController *self, NSNotification *note) {
[self performSegueWithIdentifier:@"unwind-popover" sender:self];
} );
[self.scrollView automaticallyAdjustInsetsForKeyboard];
}
- (void)viewDidDisappear:(BOOL)animated {
@ -52,6 +54,7 @@
[super viewDidDisappear:animated];
PearlRemoveNotificationObservers();
PearlRemoveNotificationObserversFrom( self.scrollView );
[self reset];
}

View File

@ -7,6 +7,8 @@
//
#import "MPGuideViewController.h"
#import "markdown_lib.h"
#import "NSString+MPMarkDown.h"
@interface MPGuideStep : NSObject
@ -37,28 +39,50 @@
[super viewDidLoad];
self.steps = @[
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-0"] caption:
@"To begin, tap the \"New User\" icon and add yourself as a user to the application."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-1"] caption:
@"Enter your full name. Double-check that you have spelled your name correctly and capitalized it appropriately. Your passwords will depend on it."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-2"] caption:
@"Choose a master password: Use something new and long. A short sentence is ideal.\nDO NOT FORGET THIS ONE PASSWORD."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-3"] caption:
@"After logging in, you'll see an empty screen with a search box.\nTap the search box to begin adding sites."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-4"] caption:
@"To add a site, just enter its name fully and tap the result. Names can be anything, but we recommend using a site's bare domain name."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-5"] caption:
@"Your sites are easy to find and sorted by recency.\nTap any site to copy its password.\nYou can now switch and paste it in another app."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-6"] caption:
@"The user icon lets you save your site's login.\nThis is useful if you find it hard to remember the user name for this site."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-7"] caption:
[MPGuideStep stepWithImage:[UIImage imageNamed:@"initial"] caption:
@"To begin, tap the *New User* icon and add yourself as a user to the application."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"name_new"] caption:
@"Enter your full name. \n"
@"**Double-check** that you have spelled your name correctly and capitalized it appropriately. \n"
@"Your passwords will depend on it."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"mpw_new"] caption:
@"Choose a master password: Make it *new* and *long*. \n"
@"A short phrase makes a great password. \n"
@"**DO NOT FORGET THIS ONE PASSWORD**."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"login_new"] caption:
@"After logging in, you'll see an empty screen with a search box. \n"
@"Tap the search box to begin adding sites."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"site_new"] caption:
@"To add a site, just enter its name and tap the result. \n"
@"*We recommend* always using a site's **bare** domain name: eg. *apple.com*. \n"
@"(NOT *www.*apple.com or *store.*apple.com)"],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"copy_pw"] caption:
@"Tap any site to copy its password. \n"
@"The first time, change your site's old password into this new one."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"settings"] caption:
@"To make changes to the site password, tap the settings icon or swipe left to reveal extra buttons."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-8"] caption:
@"If you ever need a new password for the site, just tap the plus icon to increment its counter.\nYou can hold down to reset it back to 1."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-9"] caption:
@"Use the list icon to upgrade or downgrade your password's complexity.\nSome sites won't let you use complex passwords."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"image-10"] caption:
@"If you have a password that you cannot change, you can save it as a Personal password. Device Private means the site will not be backed up."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"login_name"] caption:
@"You can save the login name for the site. \n"
@"This is useful if you find it hard to remember your user name for this site."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"counter"] caption:
@"If you ever need a new password for the site, just tap the plus icon to increment its counter. \n"
@"You can hold down to reset it back to 1."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"choose_type"] caption:
@"Use the list icon to upgrade or downgrade your password's complexity. \n"
@"Some sites won't let you use complex passwords."],
[MPGuideStep stepWithImage:[UIImage imageNamed:@"personal_pw"] caption:
@"If you have a password that you cannot change, you can save it as a *personal* password. "
@"*Device private* means the site will not be backed up."],
];
}
@ -68,9 +92,10 @@
[self.pageControl observeKeyPath:@"currentPage"
withBlock:^(id from, id to, NSKeyValueChange cause, UIPageControl *pageControl) {
MPGuideStep *activeStep = self.steps[pageControl.currentPage];
self.captionLabel.text = activeStep.caption;
}];
MPGuideStep *activeStep = self.steps[pageControl.currentPage];
self.captionLabel.attributedText =
[activeStep.caption attributedMarkdownStringWithFontSize:self.captionLabel.font.pointSize];
}];
[self.collectionView setContentOffset:CGPointZero];
self.pageControl.currentPage = 0;
@ -117,6 +142,7 @@
MPGuideStepCell *cell = [MPGuideStepCell dequeueCellFromCollectionView:collectionView indexPath:indexPath];
cell.imageView.image = ((MPGuideStep *)self.steps[indexPath.item]).image;
cell.contentView.frame = cell.bounds;
return cell;
}

View File

@ -226,12 +226,15 @@
else if (textField == self.loginNameField &&
((site.loginGenerated && ![text length]) ||
(!site.loginGenerated && ![text isEqualToString:site.loginName]))) {
site.loginName = text;
site.loginGenerated = NO;
if ([text length])
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Saved" dismissAfter:2];
else
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Cleared" dismissAfter:2];
if (site.loginGenerated || !([site.loginName isEqualToString:text] || (!text && !site.loginName))) {
site.loginGenerated = NO;
site.loginName = text;
if ([text length])
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Saved" dismissAfter:2];
else
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Cleared" dismissAfter:2];
}
}
[context saveToStore];
@ -310,8 +313,6 @@
[self setMode:MPPasswordCellModePassword animated:YES];
break;
}
[self updateAnimated:YES];
}
- (IBAction)doUpgrade:(UIButton *)sender {
@ -499,6 +500,9 @@
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *site = [self siteInContext:context];
MPKey *key = [MPiOSAppDelegate get].key;
if (!key)
return;
NSString *password, *loginName = [site resolveLoginUsingKey:key];
if (self.transientSite)
password = [MPAlgorithmDefault generatePasswordForSiteNamed:self.transientSite ofType:

View File

@ -27,6 +27,7 @@
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *passwordsToBottomConstraint;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *navigationBarToTopConstraint;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *popdownToTopConstraint;
@property(strong, nonatomic) IBOutlet UIView *badNameTipContainer;
@property(strong, nonatomic) IBOutlet UIView *popdownView;
@property(strong, nonatomic) IBOutlet UIView *popdownContainer;

View File

@ -24,6 +24,10 @@
#import "MPPasswordCell.h"
#import "MPAnswersViewController.h"
typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
MPPasswordsBadNameTip = 1 << 0,
};
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
@property(nonatomic, strong) IBOutlet UINavigationBar *navigationBar;
@ -39,6 +43,7 @@
__weak UIViewController *_popdownVC;
BOOL _showTransientItem;
NSUInteger _transientItem;
NSCharacterSet *_siteNameAcceptableCharactersSet;
}
#pragma mark - Life
@ -47,6 +52,11 @@
[super viewDidLoad];
NSMutableCharacterSet *siteNameAcceptableCharactersSet = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[siteNameAcceptableCharactersSet formIntersectionWithCharacterSet:[[NSCharacterSet uppercaseLetterCharacterSet] invertedSet]];
[siteNameAcceptableCharactersSet addCharactersInString:@"@.-+~&_;:/"];
_siteNameAcceptableCharactersSet = siteNameAcceptableCharactersSet;
_backgroundColor = self.passwordCollectionView.backgroundColor;
_darkenedBackgroundColor = [_backgroundColor colorWithAlphaComponent:0.6f];
_transientItem = NSNotFound;
@ -232,12 +242,32 @@
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchBar == self.passwordsSearchBar)
if (searchBar == self.passwordsSearchBar) {
if ([self.query length] && [[self.query stringByTrimmingCharactersInSet:_siteNameAcceptableCharactersSet] length])
[self showTips:MPPasswordsBadNameTip];
[self updatePasswords];
}
}
#pragma mark - Private
- (void)showTips:(MPPasswordsTips)showTips {
[UIView animateWithDuration:0.3f animations:^{
if (showTips & MPPasswordsBadNameTip)
self.badNameTipContainer.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
PearlMainQueueAfter( 5, ^{
[UIView animateWithDuration:0.3f animations:^{
if (showTips & MPPasswordsBadNameTip)
self.badNameTipContainer.alpha = 0;
}];
} );
}];
}
- (void)fetchedItemsDidUpdate {
NSString *query = self.query;

View File

@ -31,6 +31,7 @@
inf( @"Preferences will appear" );
[super viewWillAppear:animated];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"tipped.passwordsPreferences"];
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserForMainThread];
self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:activeUser.defaultType];

View File

@ -17,9 +17,12 @@
@property(weak, nonatomic) IBOutlet MPStoreProductCell *iOSIntegrationCell;
@property(weak, nonatomic) IBOutlet MPStoreProductCell *touchIDCell;
@property(weak, nonatomic) IBOutlet MPStoreProductCell *fuelCell;
@property(weak, nonatomic) IBOutlet UITableViewCell *loadingCell;
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *fuelMeterConstraint;
@property(weak, nonatomic) IBOutlet UIButton *fuelSpeedButton;
+ (NSString *)latestStoreFeatures;
@end
@interface MPStoreProductCell : UITableViewCell

View File

@ -10,6 +10,7 @@
#import "MPiOSAppDelegate.h"
#import "UIColor+Expanded.h"
#import "MPAppDelegate_InApp.h"
#import "MPPasswordsViewController.h"
PearlEnum( MPDevelopmentFuelConsumption,
MPDevelopmentFuelConsumptionQuarterly, MPDevelopmentFuelConsumptionMonthly, MPDevelopmentFuelWeekly );
@ -23,6 +24,22 @@ PearlEnum( MPDevelopmentFuelConsumption,
@implementation MPStoreViewController
+ (NSString *)latestStoreFeatures {
NSMutableString *features = [NSMutableString string];
NSArray *storeVersions = @[
@"Generated Usernames\nSecurity Question Answers"
];
NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"];
for (; storeVersion < [storeVersions count]; ++storeVersion)
[features appendFormat:@"%@\n", storeVersions[storeVersion]];
if (![features length])
return nil;
[[NSUserDefaults standardUserDefaults] setInteger:storeVersion forKey:@"storeVersion"];
return features;
}
- (void)viewDidLoad {
[super viewDidLoad];
@ -32,7 +49,6 @@ PearlEnum( MPDevelopmentFuelConsumption,
self.tableView.tableHeaderView = [UIView new];
self.tableView.tableFooterView = [UIView new];
self.tableView.estimatedRowHeight = 400;
self.view.backgroundColor = [UIColor clearColor];
}
@ -42,7 +58,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 );
[self reloadCellsHiding:self.allCellsBySection[0] showing:nil];
[self reloadCellsHiding:self.allCellsBySection[0] showing:@[ self.loadingCell ]];
[self.allCellsBySection[0] enumerateObjectsUsingBlock:^(MPStoreProductCell *cell, NSUInteger idx, BOOL *stop) {
if ([cell isKindOfClass:[MPStoreProductCell class]]) {
cell.purchasedIndicator.alpha = 0;
@ -80,7 +96,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
if (indexPath.section == 0)
cell.selectionStyle = [[MPiOSAppDelegate get] isFeatureUnlocked:[self productForCell:cell].productIdentifier]?
UITableViewCellSelectionStyleDefault: UITableViewCellSelectionStyleNone;
UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault;
if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
@ -94,24 +110,19 @@ PearlEnum( MPDevelopmentFuelConsumption,
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
[cell layoutIfNeeded];
[cell layoutIfNeeded];
return cell.contentView.bounds.size.height;
dbg_return_tr( cell.contentView.bounds.size.height, @ );
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (![[MPAppDelegate_Shared get] canMakePayments]) {
[PearlAlert showAlertWithTitle:@"Store Not Set Up" message:
@"Try logging using the App Store or from Settings."
viewStyle:UIAlertViewStyleDefault initAlert:nil
tappedButtonBlock:nil cancelTitle:@"Thanks" otherTitles:nil];
return;
}
MPStoreProductCell *cell = (MPStoreProductCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
SKProduct *product = [self productForCell:cell];
if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
return;
if (product)
SKProduct *product = [self productForCell:cell];
if (product && ![[MPAppDelegate_Shared get] isFeatureUnlocked:product.productIdentifier])
[[MPAppDelegate_Shared get] purchaseProductWithIdentifier:product.productIdentifier
quantity:[self quantityForProductIdentifier:product.productIdentifier]];
@ -140,6 +151,12 @@ PearlEnum( MPDevelopmentFuelConsumption,
} cancelTitle:@"Cancel" otherTitles:@"Find Purchases", nil];
}
- (IBAction)sendThanks:(id)sender {
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
[NSURL URLWithString:@"http://thanks.lhunath.com"]];
}
#pragma mark - MPInAppDelegate
- (void)updateWithProducts:(NSArray *)products {
@ -176,6 +193,18 @@ PearlEnum( MPDevelopmentFuelConsumption,
#pragma mark - Private
- (MPPasswordsViewController *)dismissPopup {
for (UIViewController *vc = self; (vc = vc.parentViewController);)
if ([vc isKindOfClass:[MPPasswordsViewController class]]) {
MPPasswordsViewController *passwordsVC = (MPPasswordsViewController *)vc;
[passwordsVC dismissPopdown:self];
return passwordsVC;
}
return nil;
}
- (SKProduct *)productForCell:(MPStoreProductCell *)cell {
for (SKProduct *product in self.products)
@ -191,6 +220,10 @@ PearlEnum( MPDevelopmentFuelConsumption,
return self.generateLoginCell;
if ([productIdentifier isEqualToString:MPProductGenerateAnswers])
return self.generateAnswersCell;
if ([productIdentifier isEqualToString:MPProductOSIntegration])
return self.iOSIntegrationCell;
if ([productIdentifier isEqualToString:MPProductTouchID])
return self.touchIDCell;
if ([productIdentifier isEqualToString:MPProductFuel])
return self.fuelCell;
@ -202,18 +235,18 @@ PearlEnum( MPDevelopmentFuelConsumption,
NSMutableArray *showCells = [NSMutableArray array];
NSMutableArray *hideCells = [NSMutableArray array];
[hideCells addObjectsFromArray:self.allCellsBySection[0]];
[hideCells addObject:self.loadingCell];
for (SKProduct *product in self.products) {
[self showCellForProductWithIdentifier:MPProductGenerateLogins ifProduct:product showingCells:showCells];
[self showCellForProductWithIdentifier:MPProductGenerateAnswers ifProduct:product showingCells:showCells];
[self showCellForProductWithIdentifier:MPProductOSIntegration ifProduct:product showingCells:showCells];
[self showCellForProductWithIdentifier:MPProductTouchID ifProduct:product showingCells:showCells];
[self showCellForProductWithIdentifier:MPProductFuel ifProduct:product showingCells:showCells];
}
[hideCells removeObjectsInArray:showCells];
if ([self.tableView numberOfRowsInSection:0])
[self updateCellsHiding:hideCells showing:showCells animation:UITableViewRowAnimationAutomatic];
else
[self updateCellsHiding:hideCells showing:showCells animation:UITableViewRowAnimationNone];
[self reloadCellsHiding:hideCells showing:showCells];
}
- (void)updateFuel {
@ -221,7 +254,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
CGFloat weeklyFuelConsumption = [self weeklyFuelConsumption]; /* consume x fuel / week */
CGFloat fuel = [[MPiOSConfig get].developmentFuel floatValue]; /* x fuel left */
NSDate *now = [NSDate date];
NSTimeInterval fuelSecondsElapsed = [[MPiOSConfig get].developmentFuelChecked timeIntervalSinceDate:now];
NSTimeInterval fuelSecondsElapsed = -[[MPiOSConfig get].developmentFuelChecked timeIntervalSinceDate:now];
if (fuelSecondsElapsed > 3600 || ![MPiOSConfig get].developmentFuelChecked) {
NSTimeInterval weeksElapsed = fuelSecondsElapsed / (3600 * 24 * 7 /* 1 week */); /* x weeks elapsed */
fuel -= weeklyFuelConsumption * weeksElapsed;

View File

@ -16,25 +16,26 @@
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
@interface MPUsersViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITextFieldDelegate>
@property(weak, nonatomic) IBOutlet UIView *userSelectionContainer;
@property(weak, nonatomic) IBOutlet UIButton *marqueeButton;
@property(weak, nonatomic) IBOutlet UIView *gitTipTip;
@property(weak, nonatomic) IBOutlet UITextField *entryField;
@property(weak, nonatomic) IBOutlet UILabel *entryLabel;
@property(weak, nonatomic) IBOutlet UILabel *entryTipTitleLabel;
@property(weak, nonatomic) IBOutlet UILabel *entryTipSubtitleLabel;
@property(weak, nonatomic) IBOutlet UIView *entryTipContainer;
@property(weak, nonatomic) IBOutlet UIView *entryContainer;
@property(weak, nonatomic) IBOutlet UIView *footerContainer;
@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *storeLoadingActivity;
@property(weak, nonatomic) IBOutlet UICollectionView *avatarCollectionView;
@property (strong, nonatomic) IBOutlet UIButton *nextAvatarButton;
@property (strong, nonatomic) IBOutlet UIButton *previousAvatarButton;
@property(weak, nonatomic) IBOutlet UIView *avatarTipContainer;
@property(weak, nonatomic) IBOutlet UIView *entryTipContainer;
@property(weak, nonatomic) IBOutlet UIView *preferencesTipContainer;
@property(weak, nonatomic) IBOutlet UIView *thanksTipContainer;
@property(weak, nonatomic) IBOutlet UIButton *nextAvatarButton;
@property(weak, nonatomic) IBOutlet UIButton *previousAvatarButton;
@property(assign, nonatomic) BOOL active;
@property(assign, nonatomic, readonly) BOOL active;
- (void)setActive:(BOOL)active animated:(BOOL)animated;
- (IBAction)changeAvatar:(UIButton *)sender;

View File

@ -24,6 +24,13 @@
#import "MPAppDelegate_Key.h"
#import "MPWebViewController.h"
typedef NS_OPTIONS( NSUInteger, MPUsersTips ) {
MPUsersThanksTip = 1 << 0,
MPUsersAvatarTip = 1 << 1,
MPUsersMasterPasswordTip = 1 << 2,
MPUsersPreferencesTip = 1 << 3,
};
typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
/** The users are all inactive */
MPActiveUserStateNone,
@ -69,7 +76,10 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
self.avatarCollectionView.allowsMultipleSelection = YES;
[self.entryField addTarget:self action:@selector( textFieldEditingChanged: ) forControlEvents:UIControlEventEditingChanged];
self.preferencesTipContainer.alpha = 0;
[self setActive:YES animated:NO];
[self showTips:MPUsersThanksTip];
}
- (void)viewWillAppear:(BOOL)animated {
@ -391,34 +401,23 @@ referenceSizeForFooterInSection:(NSInteger)section {
if (buttonIndex == [sheet destructiveButtonIndex]) {
// Delete User
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
if (!user_)
return;
[context deleteObject:user_];
[context saveToStore];
[self reloadUsers]; // I do NOT understand why our ObjectsDidChangeNotification isn't firing on saveToStore.
}];
[PearlAlert showParentalGateWithTitle:@"Deleting User" message:
@"The user and its sites will be deleted.\nPlease confirm by solving:"
completion:^(BOOL continuing) {
if (continuing)
[self deleteUser:userID];
}];
return;
}
if (buttonIndex == [sheet firstOtherButtonIndex])
// Reset Password
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
if (!user_)
return;
[[MPiOSAppDelegate get] changeMasterPasswordFor:user_ saveInContext:context didResetBlock:^{
PearlMainQueue( ^{
NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell];
[self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO
scrollPosition:UICollectionViewScrollPositionNone];
[self collectionView:self.avatarCollectionView didSelectItemAtIndexPath:avatarIndexPath];
} );
}];
}];
[PearlAlert showParentalGateWithTitle:@"Resetting User" message:
@"The user's master password will be reset.\nPlease confirm by solving:"
completion:^(BOOL continuing) {
if (continuing)
[self resetUser:userID avatar:avatarCell];
}];
} cancelTitle:[PearlStrings get].commonButtonCancel
destructiveTitle:@"Delete User" otherTitles:@"Reset Password", nil];
}
@ -441,6 +440,66 @@ referenceSizeForFooterInSection:(NSInteger)section {
#pragma mark - Private
- (void)deleteUser:(NSManagedObjectID *)userID {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity
*user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
if (!user_)
return;
[context deleteObject:user_];
[context saveToStore];
[self reloadUsers]; // I do NOT understand why our ObjectsDidChangeNotification isn't firing on saveToStore.
}];
}
- (void)resetUser:(NSManagedObjectID *)userID avatar:(MPAvatarCell *)avatarCell {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
if (!user_)
return;
[[MPiOSAppDelegate get] changeMasterPasswordFor:user_ saveInContext:context didResetBlock:^{
PearlMainQueue( ^{
NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell];
[self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO
scrollPosition:UICollectionViewScrollPositionNone];
[self collectionView:self.avatarCollectionView didSelectItemAtIndexPath:avatarIndexPath];
} );
}];
}];
}
- (void)showTips:(MPUsersTips)showTips {
[UIView animateWithDuration:0.3f animations:^{
if (showTips & MPUsersThanksTip)
self.thanksTipContainer.alpha = 1;
if (showTips & MPUsersAvatarTip)
self.avatarTipContainer.alpha = 1;
if (showTips & MPUsersMasterPasswordTip)
self.entryTipContainer.alpha = 1;
if (showTips & MPUsersPreferencesTip)
self.preferencesTipContainer.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
PearlMainQueueAfter( 5, ^{
[UIView animateWithDuration:0.3f animations:^{
if (showTips & MPUsersThanksTip)
self.thanksTipContainer.alpha = 0;
if (showTips & MPUsersAvatarTip)
self.avatarTipContainer.alpha = 0;
if (showTips & MPUsersMasterPasswordTip)
self.entryTipContainer.alpha = 0;
if (showTips & MPUsersPreferencesTip)
self.preferencesTipContainer.alpha = 0;
}];
} );
}];
}
- (void)showEntryTip:(NSString *)message {
NSUInteger newlineIndex = [message rangeOfString:@"\n"].location;
@ -448,17 +507,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
NSString *messageSubtitle = newlineIndex == NSNotFound? nil: [message substringFromIndex:newlineIndex];
self.entryTipTitleLabel.text = messageTitle;
self.entryTipSubtitleLabel.text = messageSubtitle;
[UIView animateWithDuration:0.3f animations:^{
self.entryTipContainer.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
PearlMainQueueAfter( 4, ^{
[UIView animateWithDuration:0.3f animations:^{
self.entryTipContainer.alpha = 0;
}];
} );
}];
[self showTips:MPUsersMasterPasswordTip];
}
- (void)firedMarqueeTimer:(NSTimer *)timer {
@ -610,16 +659,16 @@ referenceSizeForFooterInSection:(NSInteger)section {
[self.storeLoadingActivity startAnimating];
if (mainContext)
PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey];
NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey];
if ([[NSSetUnion( insertedObjects, deletedObjects )
filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[MPUserEntity class]];
}]] count])
[self reloadUsers];
} );
PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey];
NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey];
if ([[NSSetUnion( insertedObjects, deletedObjects )
filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[MPUserEntity class]];
}]] count])
[self reloadUsers];
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
self.userIDs = nil;
@ -657,11 +706,6 @@ referenceSizeForFooterInSection:(NSInteger)section {
#pragma mark - Properties
- (void)setActive:(BOOL)active {
[self setActive:active animated:NO];
}
- (void)setActive:(BOOL)active animated:(BOOL)animated {
_active = active;
@ -777,6 +821,29 @@ referenceSizeForFooterInSection:(NSInteger)section {
}
}
// Manage tip visibility.
switch (activeUserState) {
case MPActiveUserStateNone:
case MPActiveUserStateMasterPasswordConfirmation:
case MPActiveUserStateLogin: {
break;
}
case MPActiveUserStateUserName: {
[self showTips:MPUsersAvatarTip];
break;
}
case MPActiveUserStateMasterPasswordChoice: {
[self showEntryTip:strl( @"A short phrase makes a strong, memorable password." )];
break;
}
case MPActiveUserStateMinimized: {
if (YES || ![[NSUserDefaults standardUserDefaults] boolForKey:@"tipped.passwordsPreferences"])
[self showTips:MPUsersPreferencesTip];
break;
}
}
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[_afterUpdates setSuspended:NO];

View File

@ -10,6 +10,7 @@
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "IASKSettingsReader.h"
#import "MPStoreViewController.h"
@interface MPiOSAppDelegate()<UIDocumentInteractionControllerDelegate>
@ -130,6 +131,14 @@
[self.navigationController performSegueWithIdentifier:@"setup" sender:self];
} );
NSString *latestFeatures = [MPStoreViewController latestStoreFeatures];
if (latestFeatures)
[PearlAlert showAlertWithTitle:@"New Features" message:
strf( @"The following features are now available in the store:\n\n%@•••\n\n"
@"Find the store from the user pulldown after logging in.", latestFeatures )
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil
cancelTitle:@"Thanks" otherTitles:nil];
MPCheckpoint( MPCheckpointStarted, @{
@"simulator" : PearlStringB( [PearlDeviceUtils isSimulator] ),
@"encrypted" : PearlStringB( [PearlDeviceUtils isAppEncrypted] ),

View File

@ -13,6 +13,7 @@
93D39262A8A97DB748213309 /* PearlEMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393BB973253D4BAAC84AA /* PearlEMail.m */; };
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */; };
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */; };
93D3932889B6B4206E66A6D6 /* PearlEMail.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */; };
93D39392DEDA376F93C6C718 /* MPCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39BAA71DE51B4D8A1286C /* MPCell.m */; };
93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3957D76F71A652716EECC /* MPStoreViewController.m */; };
@ -57,28 +58,6 @@
DA071BF3190187FE00179766 /* empty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA071BF1190187FE00179766 /* empty@2x.png */; };
DA071BF4190187FE00179766 /* empty.png in Resources */ = {isa = PBXBuildFile; fileRef = DA071BF2190187FE00179766 /* empty.png */; };
DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3979190DACEBD1F6AE9F4 /* MPLogsViewController.m */; };
DA2509FD1956484D00AC23F1 /* image-10@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E31956484D00AC23F1 /* image-10@2x.png */; };
DA2509FE1956484D00AC23F1 /* image-10.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E41956484D00AC23F1 /* image-10.png */; };
DA2509FF1956484D00AC23F1 /* image-9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E51956484D00AC23F1 /* image-9@2x.png */; };
DA250A001956484D00AC23F1 /* image-9.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E61956484D00AC23F1 /* image-9.png */; };
DA250A011956484D00AC23F1 /* image-8@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E71956484D00AC23F1 /* image-8@2x.png */; };
DA250A021956484D00AC23F1 /* image-8.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E81956484D00AC23F1 /* image-8.png */; };
DA250A031956484D00AC23F1 /* image-7@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509E91956484D00AC23F1 /* image-7@2x.png */; };
DA250A041956484D00AC23F1 /* image-7.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509EA1956484D00AC23F1 /* image-7.png */; };
DA250A051956484D00AC23F1 /* image-6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509EB1956484D00AC23F1 /* image-6@2x.png */; };
DA250A061956484D00AC23F1 /* image-6.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509EC1956484D00AC23F1 /* image-6.png */; };
DA250A071956484D00AC23F1 /* image-5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509ED1956484D00AC23F1 /* image-5@2x.png */; };
DA250A081956484D00AC23F1 /* image-5.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509EE1956484D00AC23F1 /* image-5.png */; };
DA250A091956484D00AC23F1 /* image-4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509EF1956484D00AC23F1 /* image-4@2x.png */; };
DA250A0A1956484D00AC23F1 /* image-4.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F01956484D00AC23F1 /* image-4.png */; };
DA250A0B1956484D00AC23F1 /* image-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F11956484D00AC23F1 /* image-3@2x.png */; };
DA250A0C1956484D00AC23F1 /* image-3.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F21956484D00AC23F1 /* image-3.png */; };
DA250A0D1956484D00AC23F1 /* image-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F31956484D00AC23F1 /* image-2@2x.png */; };
DA250A0E1956484D00AC23F1 /* image-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F41956484D00AC23F1 /* image-2.png */; };
DA250A0F1956484D00AC23F1 /* image-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F51956484D00AC23F1 /* image-1@2x.png */; };
DA250A101956484D00AC23F1 /* image-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F61956484D00AC23F1 /* image-1.png */; };
DA250A111956484D00AC23F1 /* image-0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F71956484D00AC23F1 /* image-0@2x.png */; };
DA250A121956484D00AC23F1 /* image-0.png in Resources */ = {isa = PBXBuildFile; fileRef = DA2509F81956484D00AC23F1 /* image-0.png */; };
DA250A17195665A100AC23F1 /* UITableView+PearlReloadFromArray.m in Sources */ = {isa = PBXBuildFile; fileRef = DA250A13195665A100AC23F1 /* UITableView+PearlReloadFromArray.m */; };
DA250A18195665A100AC23F1 /* UITableView+PearlReloadFromArray.h in Headers */ = {isa = PBXBuildFile; fileRef = DA250A14195665A100AC23F1 /* UITableView+PearlReloadFromArray.h */; };
DA250A19195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m in Sources */ = {isa = PBXBuildFile; fileRef = DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */; };
@ -190,6 +169,40 @@
DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; };
DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; };
DAA141221922FF020032B392 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411F1922FF020032B392 /* map-macro.h */; };
DAA175F519D86C620044227B /* markdown_lib.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA175B719D86C620044227B /* markdown_lib.m */; };
DAA175F619D86C620044227B /* markdown_output.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA175B819D86C620044227B /* markdown_output.m */; };
DAA175F719D86C620044227B /* markdown_parser.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA175BA19D86C620044227B /* markdown_parser.m */; };
DAA1760F19D86C620044227B /* README.markdown in Sources */ = {isa = PBXBuildFile; fileRef = DAA175ED19D86C620044227B /* README.markdown */; };
DAA1761019D86C620044227B /* README_PEG-MARKDWON.markdown in Sources */ = {isa = PBXBuildFile; fileRef = DAA175EE19D86C620044227B /* README_PEG-MARKDWON.markdown */; };
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAA1757D19D86BE70044227B /* libAttributedMarkdown.a */; };
DAA1762319D89B600044227B /* thumb_touch_id@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1761D19D89B600044227B /* thumb_touch_id@3x.png */; };
DAA1762419D89B610044227B /* thumb_touch_id@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1761E19D89B600044227B /* thumb_touch_id@2x.png */; };
DAA1762519D89B610044227B /* thumb_touch_id.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1761F19D89B600044227B /* thumb_touch_id.png */; };
DAA1762619D89B610044227B /* thumb_ios_integration@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762019D89B600044227B /* thumb_ios_integration@3x.png */; };
DAA1762719D89B610044227B /* thumb_ios_integration@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762119D89B600044227B /* thumb_ios_integration@2x.png */; };
DAA1762819D89B610044227B /* thumb_ios_integration.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762219D89B600044227B /* thumb_ios_integration.png */; };
DAA1763F19D8B82B0044227B /* site_new@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762919D8B82B0044227B /* site_new@2x.png */; };
DAA1764019D8B82B0044227B /* site_new.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762A19D8B82B0044227B /* site_new.png */; };
DAA1764119D8B82B0044227B /* settings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762B19D8B82B0044227B /* settings@2x.png */; };
DAA1764219D8B82B0044227B /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762C19D8B82B0044227B /* settings.png */; };
DAA1764319D8B82B0044227B /* personal_pw@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762D19D8B82B0044227B /* personal_pw@2x.png */; };
DAA1764419D8B82B0044227B /* personal_pw.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762E19D8B82B0044227B /* personal_pw.png */; };
DAA1764519D8B82B0044227B /* name_new@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1762F19D8B82B0044227B /* name_new@2x.png */; };
DAA1764619D8B82B0044227B /* name_new.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763019D8B82B0044227B /* name_new.png */; };
DAA1764719D8B82B0044227B /* mpw_new@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763119D8B82B0044227B /* mpw_new@2x.png */; };
DAA1764819D8B82B0044227B /* mpw_new.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763219D8B82B0044227B /* mpw_new.png */; };
DAA1764919D8B82B0044227B /* login_new@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763319D8B82B0044227B /* login_new@2x.png */; };
DAA1764A19D8B82B0044227B /* login_new.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763419D8B82B0044227B /* login_new.png */; };
DAA1764B19D8B82B0044227B /* login_name@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763519D8B82B0044227B /* login_name@2x.png */; };
DAA1764C19D8B82B0044227B /* login_name.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763619D8B82B0044227B /* login_name.png */; };
DAA1764D19D8B82B0044227B /* initial@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763719D8B82B0044227B /* initial@2x.png */; };
DAA1764E19D8B82B0044227B /* initial.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763819D8B82B0044227B /* initial.png */; };
DAA1764F19D8B82B0044227B /* counter@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763919D8B82B0044227B /* counter@2x.png */; };
DAA1765019D8B82B0044227B /* counter.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763A19D8B82B0044227B /* counter.png */; };
DAA1765119D8B82B0044227B /* copy_pw@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763B19D8B82B0044227B /* copy_pw@2x.png */; };
DAA1765219D8B82B0044227B /* copy_pw.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763C19D8B82B0044227B /* copy_pw.png */; };
DAA1765319D8B82B0044227B /* choose_type@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763D19D8B82B0044227B /* choose_type@2x.png */; };
DAA1765419D8B82B0044227B /* choose_type.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763E19D8B82B0044227B /* choose_type.png */; };
DABB981615100B4000B05417 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABB981515100B4000B05417 /* SystemConfiguration.framework */; };
DABD39371711E29700CF925C /* avatar-0.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366C1711E29400CF925C /* avatar-0.png */; };
DABD39381711E29700CF925C /* avatar-0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366D1711E29400CF925C /* avatar-0@2x.png */; };
@ -421,6 +434,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DAA1757B19D86BE70044227B /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@ -442,6 +464,7 @@
93D393310223DDB35218467A /* MPCombinedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCombinedViewController.m; sourceTree = "<group>"; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
93D393BB973253D4BAAC84AA /* PearlEMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlEMail.m; sourceTree = "<group>"; };
93D393CB0B1F4EC8C17CFE43 /* NSString+MPMarkDown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MPMarkDown.h"; sourceTree = "<group>"; };
93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = "<group>"; };
93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+PearlFirstResponder.h"; sourceTree = "<group>"; };
@ -478,6 +501,7 @@
93D39B381350802A194BF332 /* MPAvatarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAvatarCell.m; sourceTree = "<group>"; };
93D39B455A71EC98C749E623 /* MPOverlayViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayViewController.h; sourceTree = "<group>"; };
93D39BAA71DE51B4D8A1286C /* MPCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCell.m; sourceTree = "<group>"; };
93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MPMarkDown.m"; sourceTree = "<group>"; };
93D39C426E03358384018E85 /* MPAnswersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAnswersViewController.m; sourceTree = "<group>"; };
93D39C44361BE57AF0B3071F /* MPPasswordsSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordsSegue.h; sourceTree = "<group>"; };
93D39C86E984EC65DA5ACB1D /* MPAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppSettingsViewController.h; sourceTree = "<group>"; };
@ -497,28 +521,6 @@
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
DA071BF1190187FE00179766 /* empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "empty@2x.png"; sourceTree = "<group>"; };
DA071BF2190187FE00179766 /* empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = empty.png; sourceTree = "<group>"; };
DA2509E31956484D00AC23F1 /* image-10@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-10@2x.png"; sourceTree = "<group>"; };
DA2509E41956484D00AC23F1 /* image-10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-10.png"; sourceTree = "<group>"; };
DA2509E51956484D00AC23F1 /* image-9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-9@2x.png"; sourceTree = "<group>"; };
DA2509E61956484D00AC23F1 /* image-9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-9.png"; sourceTree = "<group>"; };
DA2509E71956484D00AC23F1 /* image-8@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-8@2x.png"; sourceTree = "<group>"; };
DA2509E81956484D00AC23F1 /* image-8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-8.png"; sourceTree = "<group>"; };
DA2509E91956484D00AC23F1 /* image-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-7@2x.png"; sourceTree = "<group>"; };
DA2509EA1956484D00AC23F1 /* image-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-7.png"; sourceTree = "<group>"; };
DA2509EB1956484D00AC23F1 /* image-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-6@2x.png"; sourceTree = "<group>"; };
DA2509EC1956484D00AC23F1 /* image-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-6.png"; sourceTree = "<group>"; };
DA2509ED1956484D00AC23F1 /* image-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-5@2x.png"; sourceTree = "<group>"; };
DA2509EE1956484D00AC23F1 /* image-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-5.png"; sourceTree = "<group>"; };
DA2509EF1956484D00AC23F1 /* image-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-4@2x.png"; sourceTree = "<group>"; };
DA2509F01956484D00AC23F1 /* image-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-4.png"; sourceTree = "<group>"; };
DA2509F11956484D00AC23F1 /* image-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-3@2x.png"; sourceTree = "<group>"; };
DA2509F21956484D00AC23F1 /* image-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-3.png"; sourceTree = "<group>"; };
DA2509F31956484D00AC23F1 /* image-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-2@2x.png"; sourceTree = "<group>"; };
DA2509F41956484D00AC23F1 /* image-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-2.png"; sourceTree = "<group>"; };
DA2509F51956484D00AC23F1 /* image-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-1@2x.png"; sourceTree = "<group>"; };
DA2509F61956484D00AC23F1 /* image-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-1.png"; sourceTree = "<group>"; };
DA2509F71956484D00AC23F1 /* image-0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-0@2x.png"; sourceTree = "<group>"; };
DA2509F81956484D00AC23F1 /* image-0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-0.png"; sourceTree = "<group>"; };
DA250A13195665A100AC23F1 /* UITableView+PearlReloadFromArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+PearlReloadFromArray.m"; sourceTree = "<group>"; };
DA250A14195665A100AC23F1 /* UITableView+PearlReloadFromArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+PearlReloadFromArray.h"; sourceTree = "<group>"; };
DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionReusableView+PearlDequeue.m"; sourceTree = "<group>"; };
@ -608,6 +610,48 @@
DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
DAA1411D1922FF020032B392 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; };
DAA1411F1922FF020032B392 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; sourceTree = "<group>"; };
DAA1757D19D86BE70044227B /* libAttributedMarkdown.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAttributedMarkdown.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAA175B119D86C620044227B /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
DAA175B619D86C620044227B /* markdown_lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markdown_lib.h; sourceTree = "<group>"; };
DAA175B719D86C620044227B /* markdown_lib.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = markdown_lib.m; sourceTree = "<group>"; };
DAA175B819D86C620044227B /* markdown_output.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = markdown_output.m; sourceTree = "<group>"; };
DAA175B919D86C620044227B /* markdown_parser.leg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = markdown_parser.leg; sourceTree = "<group>"; };
DAA175BA19D86C620044227B /* markdown_parser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = markdown_parser.m; sourceTree = "<group>"; };
DAA175BB19D86C620044227B /* markdown_peg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markdown_peg.h; sourceTree = "<group>"; };
DAA175EB19D86C620044227B /* parsing_functions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = parsing_functions.m; sourceTree = "<group>"; };
DAA175EC19D86C620044227B /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = "<group>"; };
DAA175ED19D86C620044227B /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.markdown; sourceTree = "<group>"; };
DAA175EE19D86C620044227B /* README_PEG-MARKDWON.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "README_PEG-MARKDWON.markdown"; sourceTree = "<group>"; };
DAA175EF19D86C620044227B /* utility_functions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = utility_functions.m; sourceTree = "<group>"; };
DAA1761C19D86E800044227B /* attributed-markdown.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "attributed-markdown.pch"; sourceTree = "<group>"; };
DAA1761D19D89B600044227B /* thumb_touch_id@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_touch_id@3x.png"; sourceTree = "<group>"; };
DAA1761E19D89B600044227B /* thumb_touch_id@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_touch_id@2x.png"; sourceTree = "<group>"; };
DAA1761F19D89B600044227B /* thumb_touch_id.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = thumb_touch_id.png; sourceTree = "<group>"; };
DAA1762019D89B600044227B /* thumb_ios_integration@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_ios_integration@3x.png"; sourceTree = "<group>"; };
DAA1762119D89B600044227B /* thumb_ios_integration@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_ios_integration@2x.png"; sourceTree = "<group>"; };
DAA1762219D89B600044227B /* thumb_ios_integration.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = thumb_ios_integration.png; sourceTree = "<group>"; };
DAA1762919D8B82B0044227B /* site_new@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "site_new@2x.png"; sourceTree = "<group>"; };
DAA1762A19D8B82B0044227B /* site_new.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = site_new.png; sourceTree = "<group>"; };
DAA1762B19D8B82B0044227B /* settings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings@2x.png"; sourceTree = "<group>"; };
DAA1762C19D8B82B0044227B /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = settings.png; sourceTree = "<group>"; };
DAA1762D19D8B82B0044227B /* personal_pw@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "personal_pw@2x.png"; sourceTree = "<group>"; };
DAA1762E19D8B82B0044227B /* personal_pw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = personal_pw.png; sourceTree = "<group>"; };
DAA1762F19D8B82B0044227B /* name_new@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "name_new@2x.png"; sourceTree = "<group>"; };
DAA1763019D8B82B0044227B /* name_new.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = name_new.png; sourceTree = "<group>"; };
DAA1763119D8B82B0044227B /* mpw_new@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mpw_new@2x.png"; sourceTree = "<group>"; };
DAA1763219D8B82B0044227B /* mpw_new.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mpw_new.png; sourceTree = "<group>"; };
DAA1763319D8B82B0044227B /* login_new@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "login_new@2x.png"; sourceTree = "<group>"; };
DAA1763419D8B82B0044227B /* login_new.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login_new.png; sourceTree = "<group>"; };
DAA1763519D8B82B0044227B /* login_name@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "login_name@2x.png"; sourceTree = "<group>"; };
DAA1763619D8B82B0044227B /* login_name.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login_name.png; sourceTree = "<group>"; };
DAA1763719D8B82B0044227B /* initial@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "initial@2x.png"; sourceTree = "<group>"; };
DAA1763819D8B82B0044227B /* initial.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = initial.png; sourceTree = "<group>"; };
DAA1763919D8B82B0044227B /* counter@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "counter@2x.png"; sourceTree = "<group>"; };
DAA1763A19D8B82B0044227B /* counter.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = counter.png; sourceTree = "<group>"; };
DAA1763B19D8B82B0044227B /* copy_pw@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "copy_pw@2x.png"; sourceTree = "<group>"; };
DAA1763C19D8B82B0044227B /* copy_pw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = copy_pw.png; sourceTree = "<group>"; };
DAA1763D19D8B82B0044227B /* choose_type@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "choose_type@2x.png"; sourceTree = "<group>"; };
DAA1763E19D8B82B0044227B /* choose_type.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = choose_type.png; sourceTree = "<group>"; };
DAAC35DD156BD77D00C5FD93 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
DABB981515100B4000B05417 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
DABD360F1711E29400CF925C /* ui_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ui_background.png; sourceTree = "<group>"; };
@ -1433,6 +1477,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */,
DA32D03E19D11293004F3F0E /* libKCOrderedAccessorFix.a in Frameworks */,
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */,
DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */,
@ -1457,6 +1502,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DAA1757A19D86BE70044227B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DAC6325A1486805C0075AEA5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -1498,28 +1550,28 @@
DA2509B619563E1E00AC23F1 /* Guide */ = {
isa = PBXGroup;
children = (
DA2509E31956484D00AC23F1 /* image-10@2x.png */,
DA2509E41956484D00AC23F1 /* image-10.png */,
DA2509E51956484D00AC23F1 /* image-9@2x.png */,
DA2509E61956484D00AC23F1 /* image-9.png */,
DA2509E71956484D00AC23F1 /* image-8@2x.png */,
DA2509E81956484D00AC23F1 /* image-8.png */,
DA2509E91956484D00AC23F1 /* image-7@2x.png */,
DA2509EA1956484D00AC23F1 /* image-7.png */,
DA2509EB1956484D00AC23F1 /* image-6@2x.png */,
DA2509EC1956484D00AC23F1 /* image-6.png */,
DA2509ED1956484D00AC23F1 /* image-5@2x.png */,
DA2509EE1956484D00AC23F1 /* image-5.png */,
DA2509EF1956484D00AC23F1 /* image-4@2x.png */,
DA2509F01956484D00AC23F1 /* image-4.png */,
DA2509F11956484D00AC23F1 /* image-3@2x.png */,
DA2509F21956484D00AC23F1 /* image-3.png */,
DA2509F31956484D00AC23F1 /* image-2@2x.png */,
DA2509F41956484D00AC23F1 /* image-2.png */,
DA2509F51956484D00AC23F1 /* image-1@2x.png */,
DA2509F61956484D00AC23F1 /* image-1.png */,
DA2509F71956484D00AC23F1 /* image-0@2x.png */,
DA2509F81956484D00AC23F1 /* image-0.png */,
DAA1762919D8B82B0044227B /* site_new@2x.png */,
DAA1762A19D8B82B0044227B /* site_new.png */,
DAA1762B19D8B82B0044227B /* settings@2x.png */,
DAA1762C19D8B82B0044227B /* settings.png */,
DAA1762D19D8B82B0044227B /* personal_pw@2x.png */,
DAA1762E19D8B82B0044227B /* personal_pw.png */,
DAA1762F19D8B82B0044227B /* name_new@2x.png */,
DAA1763019D8B82B0044227B /* name_new.png */,
DAA1763119D8B82B0044227B /* mpw_new@2x.png */,
DAA1763219D8B82B0044227B /* mpw_new.png */,
DAA1763319D8B82B0044227B /* login_new@2x.png */,
DAA1763419D8B82B0044227B /* login_new.png */,
DAA1763519D8B82B0044227B /* login_name@2x.png */,
DAA1763619D8B82B0044227B /* login_name.png */,
DAA1763719D8B82B0044227B /* initial@2x.png */,
DAA1763819D8B82B0044227B /* initial.png */,
DAA1763919D8B82B0044227B /* counter@2x.png */,
DAA1763A19D8B82B0044227B /* counter.png */,
DAA1763B19D8B82B0044227B /* copy_pw@2x.png */,
DAA1763C19D8B82B0044227B /* copy_pw.png */,
DAA1763D19D8B82B0044227B /* choose_type@2x.png */,
DAA1763E19D8B82B0044227B /* choose_type.png */,
);
path = Guide;
sourceTree = "<group>";
@ -1547,6 +1599,8 @@
93D39D6604447D7708039155 /* MPAnswersViewController.h */,
93D399493FEDDE74DD1A0C15 /* MPRootSegue.m */,
93D3924D6F77E6BF41AC32D3 /* MPRootSegue.h */,
93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */,
93D393CB0B1F4EC8C17CFE43 /* NSString+MPMarkDown.h */,
);
sourceTree = "<group>";
};
@ -1559,6 +1613,7 @@
DAC6326C148680650075AEA5 /* libjrswizzle.a */,
DAFC5655172C573B00CB5CC5 /* libInAppSettingsKit.a */,
DA32D02019D111C6004F3F0E /* libKCOrderedAccessorFix.a */,
DAA1757D19D86BE70044227B /* libAttributedMarkdown.a */,
);
name = Products;
sourceTree = "<group>";
@ -1625,9 +1680,35 @@
path = include;
sourceTree = "<group>";
};
DAA1759319D86C610044227B /* AttributedMarkdown */ = {
isa = PBXGroup;
children = (
DAA1761C19D86E800044227B /* attributed-markdown.pch */,
DAA175B119D86C620044227B /* LICENSE */,
DAA175B619D86C620044227B /* markdown_lib.h */,
DAA175B719D86C620044227B /* markdown_lib.m */,
DAA175B819D86C620044227B /* markdown_output.m */,
DAA175B919D86C620044227B /* markdown_parser.leg */,
DAA175BA19D86C620044227B /* markdown_parser.m */,
DAA175BB19D86C620044227B /* markdown_peg.h */,
DAA175EB19D86C620044227B /* parsing_functions.m */,
DAA175EC19D86C620044227B /* platform.h */,
DAA175EE19D86C620044227B /* README_PEG-MARKDWON.markdown */,
DAA175ED19D86C620044227B /* README.markdown */,
DAA175EF19D86C620044227B /* utility_functions.m */,
);
path = AttributedMarkdown;
sourceTree = "<group>";
};
DABD360D1711E29400CF925C /* Media */ = {
isa = PBXGroup;
children = (
DAA1761D19D89B600044227B /* thumb_touch_id@3x.png */,
DAA1761E19D89B600044227B /* thumb_touch_id@2x.png */,
DAA1761F19D89B600044227B /* thumb_touch_id.png */,
DAA1762019D89B600044227B /* thumb_ios_integration@3x.png */,
DAA1762119D89B600044227B /* thumb_ios_integration@2x.png */,
DAA1762219D89B600044227B /* thumb_ios_integration.png */,
DA32D07719D7D784004F3F0E /* background@3x.png */,
DA32D07819D7D784004F3F0E /* background@2x.png */,
DA32D07919D7D784004F3F0E /* background.png */,
@ -2446,6 +2527,7 @@
DACA22121705DDC5002C6C22 /* External */ = {
isa = PBXGroup;
children = (
DAA1759319D86C610044227B /* AttributedMarkdown */,
DA32D03719D111EB004F3F0E /* KCOrderedAccessorFix */,
DAA141181922FED80032B392 /* iOS */,
DAFC5662172C57EC00CB5CC5 /* InAppSettingsKit */,
@ -2894,6 +2976,23 @@
productReference = DA5BFA44147E415C00F98B1E /* MasterPassword.app */;
productType = "com.apple.product-type.application";
};
DAA1757C19D86BE70044227B /* AttributedMarkdown */ = {
isa = PBXNativeTarget;
buildConfigurationList = DAA1758B19D86BE80044227B /* Build configuration list for PBXNativeTarget "AttributedMarkdown" */;
buildPhases = (
DAA1757919D86BE70044227B /* Sources */,
DAA1757A19D86BE70044227B /* Frameworks */,
DAA1757B19D86BE70044227B /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = AttributedMarkdown;
productName = AttributedMarkdown;
productReference = DAA1757D19D86BE70044227B /* libAttributedMarkdown.a */;
productType = "com.apple.product-type.library.static";
};
DAC6325C1486805C0075AEA5 /* uicolor-utilities */ = {
isa = PBXNativeTarget;
buildConfigurationList = DAC632651486805C0075AEA5 /* Build configuration list for PBXNativeTarget "uicolor-utilities" */;
@ -2991,6 +3090,9 @@
};
};
};
DAA1757C19D86BE70044227B = {
CreatedOnToolsVersion = 6.0;
};
};
};
buildConfigurationList = DA5BFA3E147E415C00F98B1E /* Build configuration list for PBXProject "MasterPassword-iOS" */;
@ -3096,6 +3198,7 @@
DAC6326B148680650075AEA5 /* jrswizzle */,
DAFC5654172C573B00CB5CC5 /* InAppSettingsKit */,
DA32D01F19D111C6004F3F0E /* KCOrderedAccessorFix */,
DAA1757C19D86BE70044227B /* AttributedMarkdown */,
);
};
/* End PBXProject section */
@ -3109,7 +3212,6 @@
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */,
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
DA32D04F19D2F59B004F3F0E /* meter_fuel@2x.png in Resources */,
DA250A0F1956484D00AC23F1 /* image-1@2x.png in Resources */,
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
DA45224C190628B2008F650A /* icon_gear@2x.png in Resources */,
DA854C8318D4CFBF00106317 /* avatar-add@2x.png in Resources */,
@ -3122,14 +3224,13 @@
DA32D04919D2F417004F3F0E /* thumb_fuel@2x.png in Resources */,
DABD39371711E29700CF925C /* avatar-0.png in Resources */,
DABD39381711E29700CF925C /* avatar-0@2x.png in Resources */,
DA250A041956484D00AC23F1 /* image-7.png in Resources */,
DAA1764819D8B82B0044227B /* mpw_new.png in Resources */,
DA25C5FC197CCAF70046CDCF /* icon_list-names.png in Resources */,
DABD39391711E29700CF925C /* avatar-1.png in Resources */,
DA7304E5194E025900E72520 /* tip_basic_black.png in Resources */,
DABD393A1711E29700CF925C /* avatar-10.png in Resources */,
DABD393B1711E29700CF925C /* avatar-10@2x.png in Resources */,
DABD393C1711E29700CF925C /* avatar-11.png in Resources */,
DA250A0A1956484D00AC23F1 /* image-4.png in Resources */,
DABD393D1711E29700CF925C /* avatar-11@2x.png in Resources */,
DA73049D194E022700E72520 /* ui_spinner.png in Resources */,
DABD393E1711E29700CF925C /* avatar-12.png in Resources */,
@ -3140,67 +3241,74 @@
DABD39411711E29700CF925C /* avatar-13@2x.png in Resources */,
DABD39421711E29700CF925C /* avatar-14.png in Resources */,
DABD39431711E29700CF925C /* avatar-14@2x.png in Resources */,
DAA1764419D8B82B0044227B /* personal_pw.png in Resources */,
DABD39441711E29700CF925C /* avatar-15.png in Resources */,
DABD39451711E29700CF925C /* avatar-15@2x.png in Resources */,
DAA1762419D89B610044227B /* thumb_touch_id@2x.png in Resources */,
DABD39461711E29700CF925C /* avatar-16.png in Resources */,
DABD39471711E29700CF925C /* avatar-16@2x.png in Resources */,
DA7304E7194E027C00E72520 /* Square-bottom.png in Resources */,
DA250A091956484D00AC23F1 /* image-4@2x.png in Resources */,
DAA1762319D89B600044227B /* thumb_touch_id@3x.png in Resources */,
DAA1764E19D8B82B0044227B /* initial.png in Resources */,
DABD39481711E29700CF925C /* avatar-17.png in Resources */,
DABD39491711E29700CF925C /* avatar-17@2x.png in Resources */,
DA25C5FD197CCAF70046CDCF /* icon_list-names@2x.png in Resources */,
DAC8DF47192831E100BA7D71 /* icon_key.png in Resources */,
DA250A071956484D00AC23F1 /* image-5@2x.png in Resources */,
DAC8DF48192831E100BA7D71 /* icon_key@2x.png in Resources */,
DABD394A1711E29700CF925C /* avatar-18.png in Resources */,
DAA1764919D8B82B0044227B /* login_new@2x.png in Resources */,
DABD394B1711E29700CF925C /* avatar-18@2x.png in Resources */,
DABD394C1711E29700CF925C /* avatar-1@2x.png in Resources */,
DA32D07A19D7D784004F3F0E /* background@3x.png in Resources */,
DA32D04319D27093004F3F0E /* thumb_generated_answers@2x.png in Resources */,
DA29993319C9214600AF7DF1 /* icon_star-hollow.png in Resources */,
DAA1764D19D8B82B0044227B /* initial@2x.png in Resources */,
DA29993019C86F5700AF7DF1 /* thumb_generated_login.png in Resources */,
DAA1764319D8B82B0044227B /* personal_pw@2x.png in Resources */,
DAA1764A19D8B82B0044227B /* login_new.png in Resources */,
DA071BF3190187FE00179766 /* empty@2x.png in Resources */,
DA32D04219D27093004F3F0E /* thumb_generated_answers@3x.png in Resources */,
DAA1764119D8B82B0044227B /* settings@2x.png in Resources */,
DA67460E18DE7F0C00DFE240 /* Exo2.0-Regular.otf in Resources */,
DAA1763F19D8B82B0044227B /* site_new@2x.png in Resources */,
DABD394D1711E29700CF925C /* avatar-2.png in Resources */,
DABD394E1711E29700CF925C /* avatar-2@2x.png in Resources */,
DA250A061956484D00AC23F1 /* image-6.png in Resources */,
DA32D04A19D2F417004F3F0E /* thumb_fuel.png in Resources */,
DABD394F1711E29700CF925C /* avatar-3.png in Resources */,
DA67460F18DE7F0C00DFE240 /* Exo2.0-ExtraBold.otf in Resources */,
DAA1765019D8B82B0044227B /* counter.png in Resources */,
DABD39501711E29700CF925C /* avatar-3@2x.png in Resources */,
DAA1764719D8B82B0044227B /* mpw_new@2x.png in Resources */,
DA25C600197DBF260046CDCF /* icon_trash.png in Resources */,
DA32D05219D3D107004F3F0E /* icon_meter@2x.png in Resources */,
DABD39511711E29700CF925C /* avatar-4.png in Resources */,
DA2509FD1956484D00AC23F1 /* image-10@2x.png in Resources */,
DABD39521711E29700CF925C /* avatar-4@2x.png in Resources */,
DABD39531711E29700CF925C /* avatar-5.png in Resources */,
DA73049E194E022700E72520 /* ui_spinner@2x.png in Resources */,
DABD39541711E29700CF925C /* avatar-5@2x.png in Resources */,
DA32D05019D2F59B004F3F0E /* meter_fuel.png in Resources */,
DA250A031956484D00AC23F1 /* image-7@2x.png in Resources */,
DA25C5FA197CCAE00046CDCF /* icon_delete.png in Resources */,
DA25C601197DBF260046CDCF /* icon_trash@2x.png in Resources */,
DABD39551711E29700CF925C /* avatar-6.png in Resources */,
DAA1764C19D8B82B0044227B /* login_name.png in Resources */,
DA32D00919CF5C55004F3F0E /* icon_question.png in Resources */,
DABD39561711E29700CF925C /* avatar-6@2x.png in Resources */,
DA32D07B19D7D784004F3F0E /* background@2x.png in Resources */,
DABD39571711E29700CF925C /* avatar-7.png in Resources */,
DABD39581711E29700CF925C /* avatar-7@2x.png in Resources */,
DABD39591711E29700CF925C /* avatar-8.png in Resources */,
DA250A0D1956484D00AC23F1 /* image-2@2x.png in Resources */,
DA32D00A19CF5C55004F3F0E /* icon_question@2x.png in Resources */,
DA250A051956484D00AC23F1 /* image-6@2x.png in Resources */,
DAA1764019D8B82B0044227B /* site_new.png in Resources */,
DABD395A1711E29700CF925C /* avatar-8@2x.png in Resources */,
DABD395B1711E29700CF925C /* avatar-9.png in Resources */,
DAA1765419D8B82B0044227B /* choose_type.png in Resources */,
DABD395C1711E29700CF925C /* avatar-9@2x.png in Resources */,
DAA1762519D89B610044227B /* thumb_touch_id.png in Resources */,
DA45224719062899008F650A /* icon_settings.png in Resources */,
DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */,
DA32D04E19D2F59B004F3F0E /* meter_fuel@3x.png in Resources */,
DA250A101956484D00AC23F1 /* image-1.png in Resources */,
DA25C5FE197DBF200046CDCF /* icon_thumbs-up.png in Resources */,
DABD39871711E29700CF925C /* SourceCodePro-Black.otf in Resources */,
DA2509FE1956484D00AC23F1 /* image-10.png in Resources */,
DABD39881711E29700CF925C /* SourceCodePro-ExtraLight.otf in Resources */,
DABD39A01711E29700CF925C /* icon_action.png in Resources */,
DABD39A11711E29700CF925C /* icon_action@2x.png in Resources */,
@ -3210,28 +3318,27 @@
DA29992F19C86F5700AF7DF1 /* thumb_generated_login@2x.png in Resources */,
DA73049F194E022B00E72520 /* ui_textfield.png in Resources */,
DABD39F31711E29700CF925C /* icon_cancel@2x.png in Resources */,
DA250A0C1956484D00AC23F1 /* image-3.png in Resources */,
DABD3A261711E29700CF925C /* icon_edit.png in Resources */,
DABD3A271711E29700CF925C /* icon_edit@2x.png in Resources */,
DABD3A3A1711E29700CF925C /* icon_find.png in Resources */,
DABD3A3B1711E29700CF925C /* icon_find@2x.png in Resources */,
DAA1765319D8B82B0044227B /* choose_type@2x.png in Resources */,
DABD3AA01711E29800CF925C /* icon_pause.png in Resources */,
DABD3AA11711E29800CF925C /* icon_pause@2x.png in Resources */,
DAA1764219D8B82B0044227B /* settings.png in Resources */,
DABD3AAA1711E29800CF925C /* icon_person.png in Resources */,
DAA1762719D89B610044227B /* thumb_ios_integration@2x.png in Resources */,
DABD3AAB1711E29800CF925C /* icon_person@2x.png in Resources */,
DABD3ABC1711E29800CF925C /* icon_play.png in Resources */,
DABD3ABD1711E29800CF925C /* icon_play@2x.png in Resources */,
DABD3ABE1711E29800CF925C /* icon_plus.png in Resources */,
DA250A081956484D00AC23F1 /* image-5.png in Resources */,
DABD3ABF1711E29800CF925C /* icon_plus@2x.png in Resources */,
DA69540717D975D900BF294E /* icon_gears@2x.png in Resources */,
DABD3B1C1711E29800CF925C /* icon_up.png in Resources */,
DA32D04419D27093004F3F0E /* thumb_generated_answers.png in Resources */,
DABD3B1D1711E29800CF925C /* icon_up@2x.png in Resources */,
DA3BCFCB19BD09D5006B2681 /* SourceCodePro-Regular.otf in Resources */,
DA250A121956484D00AC23F1 /* image-0.png in Resources */,
DA4522441902355C008F650A /* icon_book.png in Resources */,
DA2509FF1956484D00AC23F1 /* image-9@2x.png in Resources */,
DABD3B8D1711E29800CF925C /* keypad.png in Resources */,
DABD3B8E1711E29800CF925C /* logo-bare.png in Resources */,
DA7304E6194E025900E72520 /* tip_basic_black@2x.png in Resources */,
@ -3243,33 +3350,35 @@
DABD3B971711E29800CF925C /* pull-up.png in Resources */,
DABD3B981711E29800CF925C /* pull-up@2x.png in Resources */,
DA7304A0194E022B00E72520 /* ui_textfield@2x.png in Resources */,
DAA1765119D8B82B0044227B /* copy_pw@2x.png in Resources */,
DA32D04819D2F417004F3F0E /* thumb_fuel@3x.png in Resources */,
DA452249190628A1008F650A /* icon_wrench.png in Resources */,
DAA1764519D8B82B0044227B /* name_new@2x.png in Resources */,
DA45224819062899008F650A /* icon_settings@2x.png in Resources */,
DA250A001956484D00AC23F1 /* image-9.png in Resources */,
DA854C8418D4CFBF00106317 /* avatar-add.png in Resources */,
DAA1764B19D8B82B0044227B /* login_name@2x.png in Resources */,
DABD3C241711E2DC00CF925C /* MasterPassword.entitlements in Resources */,
DABD3C251711E2DC00CF925C /* Settings.bundle in Resources */,
DABD3C261711E2DC00CF925C /* InfoPlist.strings in Resources */,
DA32D05119D3D107004F3F0E /* icon_meter.png in Resources */,
DAA1765219D8B82B0044227B /* copy_pw.png in Resources */,
DA25C5F8197AFFB40046CDCF /* icon_tools.png in Resources */,
DA250A0B1956484D00AC23F1 /* image-3@2x.png in Resources */,
DABD3FCA1712446200CF925C /* cloud.png in Resources */,
DABD3FCB1712446200CF925C /* cloud@2x.png in Resources */,
DABD3FCE1714F45C00CF925C /* identity.png in Resources */,
DAA1762619D89B610044227B /* thumb_ios_integration@3x.png in Resources */,
DABD3FCF1714F45C00CF925C /* identity@2x.png in Resources */,
DAA1764619D8B82B0044227B /* name_new.png in Resources */,
DA45224B190628B2008F650A /* icon_gear.png in Resources */,
DA25C5FF197DBF200046CDCF /* icon_thumbs-up@2x.png in Resources */,
DAE1EF2217E942DE00BC0086 /* Localizable.strings in Resources */,
DA38D6A318CCB5BF009AEB3E /* Storyboard.storyboard in Resources */,
DA250A021956484D00AC23F1 /* image-8.png in Resources */,
DA5A09DF171A70E4005284AB /* play.png in Resources */,
DA5A09E0171A70E4005284AB /* play@2x.png in Resources */,
DA5A09EA171BB0F7005284AB /* unlocked.png in Resources */,
DA250A0E1956484D00AC23F1 /* image-2.png in Resources */,
DAA1762819D89B610044227B /* thumb_ios_integration.png in Resources */,
DA5A09EB171BB0F7005284AB /* unlocked@2x.png in Resources */,
DA250A011956484D00AC23F1 /* image-8@2x.png in Resources */,
DA250A111956484D00AC23F1 /* image-0@2x.png in Resources */,
DAA1764F19D8B82B0044227B /* counter@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3363,6 +3472,19 @@
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */,
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */,
93D39B429C67A62E29DC02DA /* MPRootSegue.m in Sources */,
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DAA1757919D86BE70044227B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DAA175F519D86C620044227B /* markdown_lib.m in Sources */,
DAA1761019D86C620044227B /* README_PEG-MARKDWON.markdown in Sources */,
DAA1760F19D86C620044227B /* README.markdown in Sources */,
DAA175F719D86C620044227B /* markdown_parser.m in Sources */,
DAA175F619D86C620044227B /* markdown_output.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3884,6 +4006,30 @@
};
name = "AppStore-iOS";
};
DAA1758C19D86BE80044227B /* Debug-iOS */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREFIX_HEADER = "../../../External/AttributedMarkdown/attributed-markdown.pch";
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
};
name = "Debug-iOS";
};
DAA1758D19D86BE80044227B /* AdHoc-iOS */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREFIX_HEADER = "../../../External/AttributedMarkdown/attributed-markdown.pch";
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
};
name = "AdHoc-iOS";
};
DAA1758E19D86BE80044227B /* AppStore-iOS */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREFIX_HEADER = "../../../External/AttributedMarkdown/attributed-markdown.pch";
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
};
name = "AppStore-iOS";
};
DAC632661486805C0075AEA5 /* Debug-iOS */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -4013,6 +4159,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-iOS";
};
DAA1758B19D86BE80044227B /* Build configuration list for PBXNativeTarget "AttributedMarkdown" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DAA1758C19D86BE80044227B /* Debug-iOS */,
DAA1758D19D86BE80044227B /* AdHoc-iOS */,
DAA1758E19D86BE80044227B /* AppStore-iOS */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-iOS";
};
DAC632651486805C0075AEA5 /* Build configuration list for PBXNativeTarget "uicolor-utilities" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -0,0 +1,25 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// NSString(MPMarkDown).h
// NSString(MPMarkDown)
//
// Created by lhunath on 2014-09-28.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString(MPMarkDown)
- (NSAttributedString *)attributedMarkdownStringWithFontSize:(CGFloat)fontSize;
@end

View File

@ -0,0 +1,56 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// NSString(MPMarkDown).h
// NSString(MPMarkDown)
//
// Created by lhunath on 2014-09-28.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import "NSString+MPMarkDown.h"
#import "markdown_lib.h"
#import "markdown_peg.h"
@implementation NSString(MPMarkDown)
- (NSAttributedString *)attributedMarkdownStringWithFontSize:(CGFloat)fontSize {
NSMutableAttributedString *attributedString = markdown_to_attr_string( self, 0, @{
@(EMPH) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Bold" size:fontSize] },
@(STRONG) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-ExtraBold" size:fontSize] },
@(EMPH | STRONG) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-ExtraBold" size:fontSize] },
@(PLAIN) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Regular" size:fontSize] },
@(H1) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 2.f] },
@(H2) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 1.5f] },
@(H3) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 1.17f] },
@(H4) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 1.f] },
@(H5) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * .83f] },
@(H6) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * .75f] },
@(BLOCKQUOTE) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 1.17f] },
@(CODE) : @{ NSFontAttributeName : [UIFont fontWithName:@"SourceCodePro-Regular" size:fontSize] },
@(VERBATIM) : @{ NSFontAttributeName : [UIFont fontWithName:@"SourceCodePro-Regular" size:fontSize] },
@(NOTE) : @{ NSFontAttributeName : [UIFont fontWithName:@"Exo2.0-Thin" size:fontSize * 1.17f] },
} );
// Trim trailing newlines.
NSCharacterSet *trimSet = [NSCharacterSet newlineCharacterSet];
while (YES) {
NSRange range = [attributedString.string rangeOfCharacterFromSet:trimSet options:NSBackwardsSearch];
if (!range.length || NSMaxRange( range ) != attributedString.length)
break;
[attributedString replaceCharactersInRange:range withString:@""];
}
return attributedString;
}
@end

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -15,7 +15,7 @@
<string>HelveticaNeue-Medium</string>
</array>
<key>length</key>
<integer>353295</integer>
<integer>371142</integer>
<key>version</key>
<integer>37</integer>
</dict>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 891 KiB

View File

@ -11,7 +11,7 @@
<key>fonts</key>
<array/>
<key>length</key>
<integer>297465</integer>
<integer>297779</integer>
<key>version</key>
<integer>37</integer>
</dict>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Some files were not shown because too many files have changed in this diff Show More