From 0f356059e01f2239d1724dac5e3ea2a1837ffd3f Mon Sep 17 00:00:00 2001 From: Eddie Ehlin Date: Sun, 6 Jan 2013 01:04:54 +0100 Subject: BeanCollectionList and BeanCollectionInfo is now fully implemented. Next: BeanList --- iBean/iBean.xcodeproj/project.pbxproj | 40 +++++- .../UserInterfaceState.xcuserstate | Bin 26695 -> 30432 bytes .../xcdebugger/Breakpoints.xcbkptlist | 5 + iBean/iBean/AppDelegate+Storage.h | 4 + iBean/iBean/AppDelegate+Storage.m | 27 +++- iBean/iBean/BeanCollectionBeanListViewController.h | 26 ++++ iBean/iBean/BeanCollectionBeanListViewController.m | 80 +++++++++++ iBean/iBean/BeanCollectionInfoViewController.h | 36 +++++ iBean/iBean/BeanCollectionInfoViewController.m | 150 +++++++++++++++++++++ iBean/iBean/BeanCollectionListViewController.h | 4 +- iBean/iBean/BeanCollectionListViewController.m | 61 ++++++--- iBean/iBean/iPhoneStoryboard.storyboard | 67 +++++++-- 12 files changed, 467 insertions(+), 33 deletions(-) create mode 100644 iBean/iBean.xcodeproj/xcuserdata/eddiex.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist create mode 100644 iBean/iBean/BeanCollectionBeanListViewController.h create mode 100644 iBean/iBean/BeanCollectionBeanListViewController.m create mode 100644 iBean/iBean/BeanCollectionInfoViewController.h create mode 100644 iBean/iBean/BeanCollectionInfoViewController.m diff --git a/iBean/iBean.xcodeproj/project.pbxproj b/iBean/iBean.xcodeproj/project.pbxproj index d859d0c..d67b623 100644 --- a/iBean/iBean.xcodeproj/project.pbxproj +++ b/iBean/iBean.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 020C55FA16983E9900D8224C /* BeanCollectionListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 020C55F916983E9900D8224C /* BeanCollectionListViewController.m */; }; 020C55FD16983F7400D8224C /* Bean.m in Sources */ = {isa = PBXBuildFile; fileRef = 020C55FC16983F7400D8224C /* Bean.m */; }; 020C560016983F7400D8224C /* BeanCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 020C55FF16983F7400D8224C /* BeanCollection.m */; }; + 020C560316989D4500D8224C /* BeanCollectionInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 020C560216989D4500D8224C /* BeanCollectionInfoViewController.m */; }; + 020C56061698A85000D8224C /* BeanCollectionBeanListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 020C56051698A85000D8224C /* BeanCollectionBeanListViewController.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -56,6 +58,10 @@ 020C55FC16983F7400D8224C /* Bean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Bean.m; sourceTree = ""; }; 020C55FE16983F7400D8224C /* BeanCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeanCollection.h; sourceTree = ""; }; 020C55FF16983F7400D8224C /* BeanCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BeanCollection.m; sourceTree = ""; }; + 020C560116989D4500D8224C /* BeanCollectionInfoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeanCollectionInfoViewController.h; sourceTree = ""; }; + 020C560216989D4500D8224C /* BeanCollectionInfoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BeanCollectionInfoViewController.m; sourceTree = ""; }; + 020C56041698A85000D8224C /* BeanCollectionBeanListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeanCollectionBeanListViewController.h; sourceTree = ""; }; + 020C56051698A85000D8224C /* BeanCollectionBeanListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BeanCollectionBeanListViewController.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -153,8 +159,9 @@ 020C55D31695C2C800D8224C /* iBean */ = { isa = PBXGroup; children = ( - 020C55F816983E9900D8224C /* BeanCollectionListViewController.h */, - 020C55F916983E9900D8224C /* BeanCollectionListViewController.m */, + 020C56081698F58900D8224C /* BeanCollectionList */, + 020C56091698F59F00D8224C /* BeanCollectionInfo */, + 020C56071698F4DC00D8224C /* BeanCollectionBeanList */, 020C55DF169792F800D8224C /* Data */, ); name = iBean; @@ -171,6 +178,33 @@ name = Data; sourceTree = ""; }; + 020C56071698F4DC00D8224C /* BeanCollectionBeanList */ = { + isa = PBXGroup; + children = ( + 020C56041698A85000D8224C /* BeanCollectionBeanListViewController.h */, + 020C56051698A85000D8224C /* BeanCollectionBeanListViewController.m */, + ); + name = BeanCollectionBeanList; + sourceTree = ""; + }; + 020C56081698F58900D8224C /* BeanCollectionList */ = { + isa = PBXGroup; + children = ( + 020C55F816983E9900D8224C /* BeanCollectionListViewController.h */, + 020C55F916983E9900D8224C /* BeanCollectionListViewController.m */, + ); + name = BeanCollectionList; + sourceTree = ""; + }; + 020C56091698F59F00D8224C /* BeanCollectionInfo */ = { + isa = PBXGroup; + children = ( + 020C560116989D4500D8224C /* BeanCollectionInfoViewController.h */, + 020C560216989D4500D8224C /* BeanCollectionInfoViewController.m */, + ); + name = BeanCollectionInfo; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -246,6 +280,8 @@ 020C55FA16983E9900D8224C /* BeanCollectionListViewController.m in Sources */, 020C55FD16983F7400D8224C /* Bean.m in Sources */, 020C560016983F7400D8224C /* BeanCollection.m in Sources */, + 020C560316989D4500D8224C /* BeanCollectionInfoViewController.m in Sources */, + 020C56061698A85000D8224C /* BeanCollectionBeanListViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iBean/iBean.xcodeproj/project.xcworkspace/xcuserdata/eddiex.xcuserdatad/UserInterfaceState.xcuserstate b/iBean/iBean.xcodeproj/project.xcworkspace/xcuserdata/eddiex.xcuserdatad/UserInterfaceState.xcuserstate index 3b8c0b6..0fe9ebe 100644 Binary files a/iBean/iBean.xcodeproj/project.xcworkspace/xcuserdata/eddiex.xcuserdatad/UserInterfaceState.xcuserstate and b/iBean/iBean.xcodeproj/project.xcworkspace/xcuserdata/eddiex.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iBean/iBean.xcodeproj/xcuserdata/eddiex.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/iBean/iBean.xcodeproj/xcuserdata/eddiex.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist new file mode 100644 index 0000000..05301bc --- /dev/null +++ b/iBean/iBean.xcodeproj/xcuserdata/eddiex.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/iBean/iBean/AppDelegate+Storage.h b/iBean/iBean/AppDelegate+Storage.h index 09ef412..effcd92 100644 --- a/iBean/iBean/AppDelegate+Storage.h +++ b/iBean/iBean/AppDelegate+Storage.h @@ -8,6 +8,7 @@ #import "AppDelegate.h" @class InstaBeanConfiguration; +@class BeanCollection; /* Main purpose of this category is to have all storage (core data) related @@ -19,6 +20,8 @@ #pragma mark - Common storage related methods - (NSError*) save; - (NSError*) deleteObject: (NSManagedObject*) managedObject; +- (void) rollback; + #pragma mark - InstaBean related storage methods - (InstaBeanConfiguration*) getInstaBeanConfiguration; @@ -26,6 +29,7 @@ #pragma mark - iBean related storage methods - (NSArray*) getBeanCollections; +- (BeanCollection*) createBeanCollection; diff --git a/iBean/iBean/AppDelegate+Storage.m b/iBean/iBean/AppDelegate+Storage.m index 6d4288a..9acaeb2 100644 --- a/iBean/iBean/AppDelegate+Storage.m +++ b/iBean/iBean/AppDelegate+Storage.m @@ -8,6 +8,7 @@ #import "AppDelegate+Storage.h" #import "InstaBeanConfiguration.h" +#import "BeanCollection.h" @implementation AppDelegate (Storage) @@ -31,6 +32,14 @@ return error; } +- (void) rollback +{ + if (self.managedObjectContext != nil) + { + [self.managedObjectContext rollback]; + } +} + #pragma mark - InstaBean related storage methods - (InstaBeanConfiguration*) getInstaBeanConfiguration { @@ -86,7 +95,23 @@ return fetchRequestResult; } - +- (BeanCollection*) createBeanCollection +{ + BeanCollection* bc = nil; + + if (self.managedObjectContext != nil) + { + bc = [NSEntityDescription insertNewObjectForEntityForName:@"BeanCollection" inManagedObjectContext:self.managedObjectContext]; + + //Set default values + if (bc != nil) + { + bc.created = [NSDate date]; + } + } + + return bc; +} diff --git a/iBean/iBean/BeanCollectionBeanListViewController.h b/iBean/iBean/BeanCollectionBeanListViewController.h new file mode 100644 index 0000000..2441a48 --- /dev/null +++ b/iBean/iBean/BeanCollectionBeanListViewController.h @@ -0,0 +1,26 @@ +// +// BeanCollectionBeanListViewController.h +// iBean +// +// Created by Eddie Ehlin on 2013-01-05. +// Copyright (c) 2013 Eddie Ehlin. All rights reserved. +// + +#import +@class BeanCollection; + +@interface BeanCollectionBeanListViewController : UIViewController + +@property (nonatomic, strong) BeanCollection *beanCollection; +@property (nonatomic, assign) BOOL editMode; + +/* Utility methods */ +- (void) initViewController; +- (void) initWithModeAndBeanCollection:(BOOL)editMode: (BeanCollection*) bc; + +/* UI Outlets */ + + +/* UI Actions */ + +@end diff --git a/iBean/iBean/BeanCollectionBeanListViewController.m b/iBean/iBean/BeanCollectionBeanListViewController.m new file mode 100644 index 0000000..8bc5085 --- /dev/null +++ b/iBean/iBean/BeanCollectionBeanListViewController.m @@ -0,0 +1,80 @@ +// +// BeanCollectionBeanListViewController.m +// iBean +// +// Created by Eddie Ehlin on 2013-01-05. +// Copyright (c) 2013 Eddie Ehlin. All rights reserved. +// + +#import "BeanCollectionBeanListViewController.h" +#import "BeanCollection.h" + +@interface BeanCollectionBeanListViewController () + +@end + +@implementation BeanCollectionBeanListViewController + +#warning TODO: Remove this method, probably not needed when using storyboards +/* +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} +*/ + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self initViewController]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/***************************************************** + Utility methods + *****************************************************/ +- (void) initViewController +{ + NSLog(@"BeanCollectionBeanListViewController - initViewController"); + + if (self.editMode == YES) + { + //TODO: Update UI to refelect edit mode. + + //+ set UI controls with values from beanCollection. + NSLog(@"BeanCollectionBeanListViewController - in edit state"); + } + else + { + NSLog(@"BeanCollectionBeanListViewController - in add new state"); + } +} + +- (void) initWithModeAndBeanCollection:(BOOL)editMode: (BeanCollection*) bc +{ + NSLog(@"BeanCollectionBeanListViewController - initWithModeAndBeanCollection"); + self.editMode = editMode; + self.beanCollection = bc; +} + +/***************************************************** + UI Actions + *****************************************************/ +#pragma mark - IBActions + +@end diff --git a/iBean/iBean/BeanCollectionInfoViewController.h b/iBean/iBean/BeanCollectionInfoViewController.h new file mode 100644 index 0000000..391869d --- /dev/null +++ b/iBean/iBean/BeanCollectionInfoViewController.h @@ -0,0 +1,36 @@ +// +// BeanCollectionInfoViewController.h +// iBean +// +// Created by Eddie Ehlin on 2013-01-05. +// Copyright (c) 2013 Eddie Ehlin. All rights reserved. +// + +#import +@class BeanCollection; + +@interface BeanCollectionInfoViewController : UIViewController + +@property (nonatomic, strong) BeanCollection *beanCollection; +@property (nonatomic, assign) BOOL editMode; + + +/* Utility methods */ +- (void) initViewController; +- (void) initWithModeAndBeanCollection:(BOOL)editMode: (BeanCollection*) bc; + +/* UI Outlets */ +@property (weak, nonatomic) IBOutlet UITextField *beanCollectionNameTextField; +@property (weak, nonatomic) IBOutlet UITextView *beanCollectionNoteTextView; + +/* UI Actions */ +- (IBAction) beanCollectioNameChanged; +- (IBAction) beanCollectionNoteChanged; + +/* UITextFieldDelegate */ +- (BOOL)textFieldShouldReturn:(UITextField *)textField; + +/* UITextViewDelegate */ +- (void)textViewDidEndEditing:(UITextView *)textView; + +@end diff --git a/iBean/iBean/BeanCollectionInfoViewController.m b/iBean/iBean/BeanCollectionInfoViewController.m new file mode 100644 index 0000000..a246b47 --- /dev/null +++ b/iBean/iBean/BeanCollectionInfoViewController.m @@ -0,0 +1,150 @@ +// +// BeanCollectionInfoViewController.m +// iBean +// +// Created by Eddie Ehlin on 2013-01-05. +// Copyright (c) 2013 Eddie Ehlin. All rights reserved. +// + +#import "BeanCollectionInfoViewController.h" +#import "BeanCollectionBeanListViewController.h" +#import "BeanCollection.h" + +@interface BeanCollectionInfoViewController () + +@end + +@implementation BeanCollectionInfoViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void) viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self initViewController]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + //BeanInfoBeanListSegue + if ([segue.identifier isEqualToString:@"BeanInfoBeanListSegue"]) + { + //Pass on the edit/add state and bean collection + BeanCollectionBeanListViewController *beanListViewController = segue.destinationViewController; + [beanListViewController initWithModeAndBeanCollection:self.editMode :self.beanCollection]; + } +} + +//Purpose: Hide keyboard when active control looses focus. +- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + UITouch *touch = [[event allTouches] anyObject]; + if ([self.beanCollectionNoteTextView isFirstResponder] && [touch view] != self.beanCollectionNoteTextView) + { + //This will trigger textViewDidEndEditing which in turn will trigger beanCollectionNoteChanged + [self.beanCollectionNoteTextView resignFirstResponder]; + } + else if ([self.beanCollectionNameTextField isFirstResponder] && [touch view] != self.beanCollectionNameTextField) + { + [self.beanCollectionNameTextField resignFirstResponder]; + } + + [super touchesBegan:touches withEvent:event]; +} + +/***************************************************** + Utility methods + *****************************************************/ +- (void) initViewController +{ + NSLog(@"BeanCollectionInfoViewController - initViewController"); + + if (self.editMode == YES) + { + //Set values from bean collection structure. + self.beanCollectionNameTextField.text = self.beanCollection.name; + self.beanCollectionNoteTextView.text = self.beanCollection.note; + + NSLog(@"BeanCollectionInfoViewController - in edit state"); + } + else + { + NSLog(@"BeanCollectionInfoViewController - in add new state"); + } +} + +- (void) initWithModeAndBeanCollection:(BOOL)editMode :(BeanCollection *)bc +{ + self.editMode = editMode; + self.beanCollection = bc; +} + +/***************************************************** + UI Actions + *****************************************************/ +#pragma mark - IBActions + +- (void) beanCollectioNameChanged +{ + NSLog(@"BeanCollectionInfoViewController - beanCollectioNameChanged"); + if (self.beanCollection != nil) + { + self.beanCollection.name = self.beanCollectionNameTextField.text; + } +} +- (void) beanCollectionNoteChanged +{ + NSLog(@"BeanCollectionInfoViewController - beanCollectioNoteChanged"); + if (self.beanCollection != nil) + { + self.beanCollection.note = self.beanCollectionNoteTextView.text; + } +} + +/* UITextFieldDelegate */ +#pragma mark - UITextFieldDelegate methods + +//Purpose: When "return" is pressed the keyboard will go away and "change" event will be triggered. +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + //Return key makes the keyboard go away. + if (textField == self.beanCollectionNameTextField) + { + [textField resignFirstResponder]; + return YES; + } + + return NO; +} + +#pragma mark - UITextViewDelegate methods +//Purpose: Catch the event when changes have been made to the bean collection's note. +- (void)textViewDidEndEditing:(UITextView *)textView +{ + if (textView == self.beanCollectionNoteTextView) + { + //Update bean collection's note. + [self beanCollectionNoteChanged]; + } +} + +@end diff --git a/iBean/iBean/BeanCollectionListViewController.h b/iBean/iBean/BeanCollectionListViewController.h index a433417..5ac810d 100644 --- a/iBean/iBean/BeanCollectionListViewController.h +++ b/iBean/iBean/BeanCollectionListViewController.h @@ -7,10 +7,11 @@ // #import - +@class BeanCollection; @interface BeanCollectionListViewController : UITableViewController @property (nonatomic, strong) NSArray *beanCollections; +@property (nonatomic, strong) BeanCollection *beanCollection; /* Utility methods */ - (void) initViewController; @@ -19,5 +20,6 @@ /* UI Actions */ +- (IBAction) editButtonPressed: (id)sender; @end diff --git a/iBean/iBean/BeanCollectionListViewController.m b/iBean/iBean/BeanCollectionListViewController.m index 3869497..dc16847 100644 --- a/iBean/iBean/BeanCollectionListViewController.m +++ b/iBean/iBean/BeanCollectionListViewController.m @@ -7,6 +7,7 @@ // #import "BeanCollectionListViewController.h" +#import "BeanCollectionInfoViewController.h" #import "BeanCollection.h" #import "AppDelegate+Storage.h" @@ -42,18 +43,25 @@ { [super viewWillAppear:animated]; [self initViewController]; - - //TODO: Rollback if view is "backed" to from add-state, so that nothing gets saved...that shouldn't be saved. } - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - if ([segue.identifier isEqualToString:@"AddNewStep1Segue"]) + if ([segue.identifier isEqualToString:@"NewBeanCollectionInfoSegue"]) { - NSLog(@"Going to Add new - Step 1"); - //TODO: Create new bean collection object (managed context object) and push it through the segue - //to the next view controller! - //segue.destinationViewController Points to next view controller! Fetch it and add/set the bean collection object to use. + //Tell the view controller that we'll be adding/handling a new bean collection + BeanCollectionInfoViewController *infoViewController = segue.destinationViewController; + + //Create new bean collection and pass it on to the next view controller! + self.beanCollection = [(AppDelegate*) [[UIApplication sharedApplication] delegate] createBeanCollection]; + [infoViewController initWithModeAndBeanCollection:NO :self.beanCollection]; + } + else if ([segue.identifier isEqualToString:@"EditBeanCollectionInfoSegue"]) + { + //Tell the view controller that we'll be handling an existing bean collection + BeanCollectionInfoViewController *infoViewController = segue.destinationViewController; + self.beanCollection = [self.beanCollections objectAtIndex:[self.tableView indexPathForSelectedRow].row]; + [infoViewController initWithModeAndBeanCollection:YES :self.beanCollection]; } } @@ -116,7 +124,7 @@ } } [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - } + } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } @@ -139,17 +147,19 @@ */ #pragma mark - Table view delegate - +#warning TODO: Remove this method, not needed since we are using storyboard based design? +/* - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - // Navigation logic may go here. Create and push another view controller. - /* - <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; - // ... - // Pass the selected object to the new view controller. - [self.navigationController pushViewController:detailViewController animated:YES]; - */ + // Navigation logic may go here. Create and push another view controller. + + // <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; + // ... + // Pass the selected object to the new view controller. + //[self.navigationController pushViewController:detailViewController animated:YES]; + } +*/ /***************************************************** @@ -159,12 +169,22 @@ { NSLog(@"BeanCollectionListViewController - initViewController"); + //Remove "new" bean collection if it is allocated + if (self.beanCollection != nil) + { + self.beanCollection = nil; + [(AppDelegate*) [[UIApplication sharedApplication] delegate] rollback]; + } + //Load bean collections from core data storage self.beanCollections = [(AppDelegate*) [[UIApplication sharedApplication] delegate] getBeanCollections]; if (self.beanCollections != nil) { [self.tableView reloadData]; } + + //Reset editing state + self.editing = NO; } /***************************************************** @@ -172,4 +192,13 @@ *****************************************************/ #pragma mark - IBActions +- (void) editButtonPressed: (id)sender +{ + if (self.editing) + NSLog(@"Disabling editing mode!"); + else + NSLog(@"Enabling editing mode!"); + self.editing = !self.editing; +} + @end diff --git a/iBean/iBean/iPhoneStoryboard.storyboard b/iBean/iBean/iPhoneStoryboard.storyboard index cfa726d..ce404ed 100644 --- a/iBean/iBean/iPhoneStoryboard.storyboard +++ b/iBean/iBean/iPhoneStoryboard.storyboard @@ -13,14 +13,14 @@ - + - + - + + + + - + + + + + - + @@ -157,15 +165,15 @@ - + - + - @@ -209,6 +224,7 @@ + @@ -217,16 +233,20 @@ - + + + + + - + - + @@ -413,7 +433,7 @@ - + @@ -422,6 +442,24 @@ + + + + + + + + + + + + + + + + + + @@ -442,4 +480,7 @@ + + + \ No newline at end of file -- cgit v1.2.3