Changeset 2aabdf3 in orbit
- Timestamp:
- 12/25/12 11:53:41 (7 years ago)
- Branches:
- master, RawEEG, Raw_EEG_Plot, Servo, Tab_Interface, pyramid
- Children:
- daf54d5
- Parents:
- eac712d
- Location:
- iOS/Orbit
- Files:
-
- 2 deleted
- 7 edited
- 7 moved
Legend:
- Unmodified
- Added
- Removed
-
iOS/Orbit/Orbit/AppDelegate.h
r66477ef r2aabdf3 4 4 // 5 5 // Created by Jonathon Horsman on 17/12/2012. 6 // Copyright (c) 2012 Jonathon Horsman. All rights reserved.6 // Copyright (c) 2012 Puzzlebox Productions, LLC. All rights reserved. 7 7 // 8 8 -
iOS/Orbit/Orbit/AppDelegate.m
r66477ef r2aabdf3 4 4 // 5 5 // Created by Jonathon Horsman on 17/12/2012. 6 // Copyright (c) 2012 Jonathon Horsman. All rights reserved.6 // Copyright (c) 2012 Puzzlebox Productions, LLC. All rights reserved. 7 7 // 8 8 -
iOS/Orbit/Orbit/Orbit-Info.plist
r66477ef r2aabdf3 49 49 <array> 50 50 <string>UIInterfaceOrientationPortrait</string> 51 <string>UIInterfaceOrientationLandscapeLeft</string>52 <string>UIInterfaceOrientationLandscapeRight</string>53 51 </array> 54 52 </dict> -
iOS/Orbit/Orbit/ViewController.h
r66477ef r2aabdf3 4 4 // 5 5 // Created by Jonathon Horsman on 17/12/2012. 6 // Copyright (c) 2012 Jonathon Horsman. All rights reserved.6 // Copyright (c) 2012 Puzzlebox Productions, LLC. All rights reserved. 7 7 // 8 8 -
iOS/Orbit/Orbit/ViewController.m
reac712d r2aabdf3 4 4 // 5 5 // Created by Jonathon Horsman on 17/12/2012. 6 // Copyright (c) 2012 Jonathon Horsman. All rights reserved.6 // Copyright (c) 2012 Puzzlebox Productions, LLC. All rights reserved. 7 7 // 8 8 … … 10 10 #import <AVFoundation/AVFoundation.h> 11 11 12 #define LOGGING true // set to false to stop each received signal being logged 12 //#define LOGGING true // set to false to stop each received signal being logged 13 #define LOGGING false // set to false to stop each received signal being logged 13 14 14 15 #define AUDIO_FILE_NAME @"throttle_hover_ios.wav" // @"iOS_noflip.wav" // 16 //#define AUDIO_FILE_NAME @"iOS_noflip.wav" 15 17 #define POOR_SIGNAL_KEY @"poorSignal" 16 18 #define ATTENTION_KEY @"eSenseAttention" … … 18 20 19 21 @implementation ViewController { 20 21 22 23 24 25 26 27 28 22 // these 2 arrays hold the values of the thrust which should be applied to the helicopter 23 // (by way of volume level through the headphones) at each level of attention and meditation. 24 // this could be calculated on the fly, but because it happens ~20 times per second, the 25 // better option is to store all the values in arrays, and recalculate when the sliders are changed. 26 float attentionPower[101]; 27 float meditationPower[101]; 28 29 int currentAttentionLevel, currentMeditationLevel; // the latest readings from the headset 30 BOOL demoRunning; 29 31 } 30 32 … … 33 35 - (void)viewDidLoad 34 36 { 35 36 37 38 39 37 [super viewDidLoad]; 38 [self prepareAudio]; 39 [self.attentionThreshold addTarget:self action:@selector(calculatePowerValues) forControlEvents:UIControlEventValueChanged]; 40 [self.meditationThreshold addTarget:self action:@selector(calculatePowerValues) forControlEvents:UIControlEventValueChanged]; 41 [self calculatePowerValues]; 40 42 } 41 43 42 44 - (void)didReceiveMemoryWarning 43 45 { 44 45 46 46 [super didReceiveMemoryWarning]; 47 // Dispose of any resources that can be recreated. 48 [self stopDemo]; 47 49 } 48 50 … … 50 52 - (void) appForegrounded 51 53 { 52 53 54 55 56 57 54 EAAccessory *accessory = [[TGAccessoryManager sharedTGAccessoryManager] accessory]; 55 if (accessory != nil) { 56 [self logMessage:[NSString stringWithFormat:@"App opened with %@ connected. Starting data stream", accessory.name]]; 57 [[TGAccessoryManager sharedTGAccessoryManager] startStream]; 58 } 59 [self resetViews]; // just in case it didn't happen on close 58 60 } 59 61 … … 61 63 - (void) resetViews 62 64 { 63 64 65 [self resetOutputToZero]; 66 self.log.text = @""; 65 67 } 66 68 67 69 - (void) resetOutputToZero 68 70 { 69 70 71 72 71 [self showSignalStrength:[NSNumber numberWithInt:200]]; 72 [self setAttentionLevel:[NSNumber numberWithInt:0]]; 73 [self setMeditationLevel:[NSNumber numberWithInt:0]]; 74 [self showPowerLevel]; 73 75 } 74 76 75 77 - (void) appClosed 76 78 { 77 78 79 80 81 79 [self stopDemo]; 80 [self resetViews]; 81 if ([[TGAccessoryManager sharedTGAccessoryManager] connected]) { 82 [[TGAccessoryManager sharedTGAccessoryManager] stopStream]; 83 } 82 84 } 83 85 84 86 - (void) prepareAudio 85 87 { 86 87 88 89 90 91 92 93 94 88 NSURL *audioFilePath = [[NSBundle mainBundle] URLForResource:AUDIO_FILE_NAME withExtension:nil]; 89 90 NSError *error; 91 audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFilePath error:&error]; 92 if (!audioPlayer) { 93 [self logMessage:[NSString stringWithFormat:@"Failed to initialize audio player: %@", [error debugDescription]]]; 94 } else { 95 [audioPlayer prepareToPlay]; 96 } 95 97 } 96 98 97 99 - (void) logMessage:(NSString *) str 98 100 { 99 101 log.text = [[NSString alloc] initWithFormat:@"%@\n%@", str, log.text]; 100 102 } 101 103 102 104 - (void) logDataReceived:(NSDictionary *) data 103 105 { 104 105 106 107 108 109 110 106 NSNumber *sig = [data valueForKey:POOR_SIGNAL_KEY]; 107 if (sig != NULL) { 108 int val = (200 - [sig intValue]) / 2; 109 [self logMessage:[NSString stringWithFormat:@"Signal strength: %u%%, Attention: %@%%, Meditation: %@%%", 110 val, [data valueForKey:ATTENTION_KEY], [data valueForKey:MEDITATION_KEY]]]; 111 } 112 111 113 } 112 114 … … 114 116 115 117 - (void)dataReceived:(NSDictionary *)data { 116 117 118 118 [self performSelectorOnMainThread:@selector(updatedSignalReceived:) 119 withObject:data 120 waitUntilDone:NO]; 119 121 } 120 122 121 123 - (void) updatedSignalReceived:(id) data 122 124 { 123 124 125 126 127 128 129 130 125 if (LOGGING) { 126 [self logDataReceived: data]; 127 } 128 [self showSignalStrength:(NSNumber *)[data valueForKey:POOR_SIGNAL_KEY]]; 129 [self setAttentionLevel:(NSNumber *)[data valueForKey:ATTENTION_KEY]]; 130 [self setMeditationLevel:(NSNumber *)[data valueForKey:MEDITATION_KEY]]; 131 [self showPowerLevel]; 132 [self playAudio]; 131 133 } 132 134 133 135 // The headset was switched on, start the data stream 134 136 - (void)accessoryDidConnect:(EAAccessory *)accessory { 135 136 137 138 137 [self logMessage:[NSString stringWithFormat:@"%@ was connected to this device. Starting data stream...", [accessory name]]]; 138 if ([[TGAccessoryManager sharedTGAccessoryManager] accessory] != nil) { 139 [[TGAccessoryManager sharedTGAccessoryManager] startStream]; 140 } 139 141 } 140 142 … … 142 144 // Reset the outputs back to zero 143 145 - (void)accessoryDidDisconnect { 144 145 146 [self logMessage:@"Accessory was disconnected."]; 147 [self resetOutputToZero]; 146 148 } 147 149 … … 151 153 - (void) calculatePowerValues 152 154 { 153 154 155 156 157 158 159 160 155 float threshold = self.attentionThreshold.value; // this is the user-selected minimum threshold - between 0 and 1 156 for (int i = 0; i < 101; i++) { 157 attentionPower[i] = [self calculatePowerAt:(float)i/100 withThreshold:threshold]; 158 } 159 threshold = self.meditationThreshold.value; // this is the user-selected minimum threshold - between 0 and 1 160 for (int i = 0; i < 101; i++) { 161 meditationPower[i] = [self calculatePowerAt:(float)i/100 withThreshold:threshold]; 162 } 161 163 } 162 164 … … 169 171 - (float) calculatePowerAt:(float)value withThreshold:(float)threshold 170 172 { 171 172 173 174 175 176 173 if (value < threshold) { // threshold not met 174 return 0; 175 } 176 // e.g. if the threshold is 0.55 and the current value is 0.7: 177 // there is 0.45 remaining of the threshold slider, and the value is 0.15 past the threshold (0.7 - 0.55), which is 0.33 (0.15 / 0.45) 178 return (value - threshold) / (1 - threshold); 177 179 } 178 180 179 181 - (void) showSignalStrength:(NSNumber *) value 180 182 { 181 182 183 183 if (value != nil) { 184 self.signal.progress = (200.0 - [value intValue]) / 200.0; 185 } 184 186 } 185 187 186 188 - (void) setAttentionLevel:(NSNumber *) value 187 189 { 188 189 190 191 }190 if (value != nil) { 191 currentAttentionLevel = [value intValue]; 192 self.attention.progress = (float)currentAttentionLevel / 100; 193 } 192 194 } 193 195 194 196 - (void) setMeditationLevel:(NSNumber *) value 195 197 { 196 197 198 199 198 if (value != nil) { 199 currentMeditationLevel = [value intValue]; 200 self.meditation.progress = (float)currentMeditationLevel / 100; 201 } 200 202 } 201 203 … … 203 205 - (void) showPowerLevel 204 206 { 205 207 self.power.progress = [self currentPowerLevel]; 206 208 } 207 209 … … 210 212 - (float) currentPowerLevel 211 213 { 212 213 214 215 216 214 float powerLevel = attentionPower[currentAttentionLevel] + meditationPower[currentMeditationLevel]; 215 if (powerLevel > 1) { 216 return 1.0; 217 } 218 return powerLevel; 217 219 } 218 220 219 221 - (void) playAudio 220 222 { 221 222 223 audioPlayer.volume = [self currentPowerLevel]; 224 [audioPlayer play]; 223 225 } 224 226 … … 228 230 - (IBAction) demoButtonPressed:(id) sender 229 231 { 230 231 232 233 234 232 if (demoRunning) { 233 [self stopDemo]; 234 } else { 235 [self startDemo]; 236 } 235 237 } 236 238 237 239 - (void) stopDemo 238 240 { 239 240 241 242 243 244 241 demoRunning = NO; 242 [self resetOutputToZero]; 243 [demoButton setTitle:@"Demo" forState:UIControlStateNormal]; 244 if (audioPlayer != NULL && [audioPlayer isPlaying]) { 245 [audioPlayer stop]; 246 } 245 247 } 246 248 247 249 - (void) startDemo 248 250 { 249 250 251 252 251 demoRunning = YES; 252 [self logMessage:@"Running demo"]; 253 [demoButton setTitle:@"Stop" forState:UIControlStateNormal]; 254 [self performSelectorInBackground:@selector(generateDemoData) withObject:nil]; 253 255 } 254 256 … … 257 259 - (void) generateDemoData 258 260 { 259 for (int i = 0; i < 100; i++) { 260 if (!demoRunning) { 261 while (demoRunning) { 262 for (int i = 0; i < 100; i++) { 263 if (!demoRunning) { 261 264 break; // break out if we stop the demo 262 } 263 NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys: 264 [NSNumber numberWithInt:i], ATTENTION_KEY, 265 [NSNumber numberWithInt:i], MEDITATION_KEY, 266 [NSNumber numberWithInt:0], POOR_SIGNAL_KEY, 267 nil]; 268 [self dataReceived:values]; 269 [NSThread sleepForTimeInterval:1]; 270 } 265 } 266 NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys: 267 [NSNumber numberWithInt:i], ATTENTION_KEY, 268 [NSNumber numberWithInt:i * 0.8], MEDITATION_KEY, 269 [NSNumber numberWithInt:0], POOR_SIGNAL_KEY, 270 nil]; 271 [self dataReceived:values]; 272 [NSThread sleepForTimeInterval:0.1]; 273 } 274 275 for (int i = 100; i > 0; i--) { 276 if (!demoRunning) { 277 break; // break out if we stop the demo 278 } 279 NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys: 280 [NSNumber numberWithInt:i], ATTENTION_KEY, 281 [NSNumber numberWithInt:i * 0.8], MEDITATION_KEY, 282 [NSNumber numberWithInt:0], POOR_SIGNAL_KEY, 283 nil]; 284 [self dataReceived:values]; 285 [NSThread sleepForTimeInterval:0.1]; 286 } 287 288 } 271 289 } 272 290 @end -
iOS/Orbit/Orbit/main.m
r66477ef r2aabdf3 4 4 // 5 5 // Created by Jonathon Horsman on 17/12/2012. 6 // Copyright (c) 2012 Jonathon Horsman. All rights reserved.6 // Copyright (c) 2012 Puzzlebox Productions, LLC. All rights reserved. 7 7 // 8 8 -
iOS/Orbit/orbit.xcodeproj/project.pbxproj
reac712d r2aabdf3 18 18 28174C6D167F2EA900104752 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 28174C6C167F2EA900104752 /* main.m */; }; 19 19 28174C71167F2EA900104752 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 28174C70167F2EA900104752 /* AppDelegate.m */; }; 20 28174C73167F2EA900104752 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 28174C72167F2EA900104752 /* Default.png */; };21 28174C75167F2EA900104752 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 28174C74167F2EA900104752 /* Default@2x.png */; };22 28174C77167F2EA900104752 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 28174C76167F2EA900104752 /* Default-568h@2x.png */; };23 20 28174C7A167F2EAA00104752 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 28174C78167F2EAA00104752 /* MainStoryboard.storyboard */; }; 24 21 28174C7D167F2EAA00104752 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28174C7C167F2EAA00104752 /* ViewController.m */; }; 25 22 28174C84167F30C400104752 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28174C83167F30C400104752 /* AVFoundation.framework */; }; 26 282F2B331681D0FC00B9A99A /* ic_launcher-57x57.png in Resources */ = {isa = PBXBuildFile; fileRef = 282F2B321681D0FC00B9A99A /* ic_launcher-57x57.png */; };27 282F2B361681D10200B9A99A /* ic_launcher-114x114.png in Resources */ = {isa = PBXBuildFile; fileRef = 282F2B351681D10200B9A99A /* ic_launcher-114x114.png */; };28 23 28C10EEC16875BC100ECFD59 /* throttle_hover_ios.wav in Resources */ = {isa = PBXBuildFile; fileRef = 28C10EEB16875BC100ECFD59 /* throttle_hover_ios.wav */; }; 29 24 28C10EEF16875C9200ECFD59 /* iOS_noflip.wav in Resources */ = {isa = PBXBuildFile; fileRef = 28C10EEE16875C9200ECFD59 /* iOS_noflip.wav */; }; 30 25 28C10EF1168760CA00ECFD59 /* HOW_TO_USE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 28C10EF0168760CA00ECFD59 /* HOW_TO_USE.txt */; }; 26 52FA364416899B5D004C280A /* ic_launcher-57x57.png in Resources */ = {isa = PBXBuildFile; fileRef = 52FA364316899B5D004C280A /* ic_launcher-57x57.png */; }; 27 52FA364616899B69004C280A /* ic_launcher-114x114.png in Resources */ = {isa = PBXBuildFile; fileRef = 52FA364516899B69004C280A /* ic_launcher-114x114.png */; }; 28 52FA364816899C63004C280A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52FA364716899C63004C280A /* Default-568h@2x.png */; }; 31 29 /* End PBXBuildFile section */ 32 30 … … 48 46 28174C6F167F2EA900104752 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 49 47 28174C70167F2EA900104752 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 50 28174C72167F2EA900104752 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };51 28174C74167F2EA900104752 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };52 28174C76167F2EA900104752 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };53 48 28174C79167F2EAA00104752 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = "<group>"; }; 54 49 28174C7B167F2EAA00104752 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; }; 55 28174C7C167F2EAA00104752 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };50 28174C7C167F2EAA00104752 /* ViewController.m */ = {isa = PBXFileReference; indentWidth = 3; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; tabWidth = 3; }; 56 51 28174C83167F30C400104752 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 57 282F2B321681D0FC00B9A99A /* ic_launcher-57x57.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ic_launcher-57x57.png"; sourceTree = "<group>"; };58 282F2B351681D10200B9A99A /* ic_launcher-114x114.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ic_launcher-114x114.png"; sourceTree = "<group>"; };59 52 28C10EEB16875BC100ECFD59 /* throttle_hover_ios.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = throttle_hover_ios.wav; sourceTree = "<group>"; }; 60 53 28C10EEE16875C9200ECFD59 /* iOS_noflip.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = iOS_noflip.wav; sourceTree = "<group>"; }; 61 54 28C10EF0168760CA00ECFD59 /* HOW_TO_USE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HOW_TO_USE.txt; sourceTree = "<group>"; }; 55 52FA364316899B5D004C280A /* ic_launcher-57x57.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ic_launcher-57x57.png"; sourceTree = "<group>"; }; 56 52FA364516899B69004C280A /* ic_launcher-114x114.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ic_launcher-114x114.png"; sourceTree = "<group>"; }; 57 52FA364716899C63004C280A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; }; 62 58 /* End PBXFileReference section */ 63 59 … … 94 90 isa = PBXGroup; 95 91 children = ( 92 52FA364716899C63004C280A /* Default-568h@2x.png */, 93 52FA364516899B69004C280A /* ic_launcher-114x114.png */, 94 52FA364316899B5D004C280A /* ic_launcher-57x57.png */, 96 95 28C10EF0168760CA00ECFD59 /* HOW_TO_USE.txt */, 97 282F2B351681D10200B9A99A /* ic_launcher-114x114.png */,98 282F2B321681D0FC00B9A99A /* ic_launcher-57x57.png */,99 96 2815BC14167F496C00F7E6DA /* QuartzCore.framework */, 100 97 28174C66167F2EA900104752 /* Orbit */, … … 146 143 28174C6C167F2EA900104752 /* main.m */, 147 144 28174C6E167F2EA900104752 /* Orbit-Prefix.pch */, 148 28174C72167F2EA900104752 /* Default.png */,149 28174C74167F2EA900104752 /* Default@2x.png */,150 28174C76167F2EA900104752 /* Default-568h@2x.png */,151 145 28C10EEB16875BC100ECFD59 /* throttle_hover_ios.wav */, 152 146 28C10EEE16875C9200ECFD59 /* iOS_noflip.wav */, … … 182 176 attributes = { 183 177 LastUpgradeCheck = 0450; 184 ORGANIZATIONNAME = " Jonathon Horsman";185 }; 186 buildConfigurationList = 28174C56167F2EA900104752 /* Build configuration list for PBXProject " Orbit" */;178 ORGANIZATIONNAME = "Puzzlebox Productions, LLC"; 179 }; 180 buildConfigurationList = 28174C56167F2EA900104752 /* Build configuration list for PBXProject "orbit" */; 187 181 compatibilityVersion = "Xcode 3.2"; 188 182 developmentRegion = English; … … 207 201 files = ( 208 202 28174C6B167F2EA900104752 /* InfoPlist.strings in Resources */, 209 28174C73167F2EA900104752 /* Default.png in Resources */,210 28174C75167F2EA900104752 /* Default@2x.png in Resources */,211 28174C77167F2EA900104752 /* Default-568h@2x.png in Resources */,212 203 28174C7A167F2EAA00104752 /* MainStoryboard.storyboard in Resources */, 213 282F2B331681D0FC00B9A99A /* ic_launcher-57x57.png in Resources */,214 282F2B361681D10200B9A99A /* ic_launcher-114x114.png in Resources */,215 204 28C10EEC16875BC100ECFD59 /* throttle_hover_ios.wav in Resources */, 216 205 28C10EEF16875C9200ECFD59 /* iOS_noflip.wav in Resources */, 217 206 28C10EF1168760CA00ECFD59 /* HOW_TO_USE.txt in Resources */, 207 52FA364416899B5D004C280A /* ic_launcher-57x57.png in Resources */, 208 52FA364616899B69004C280A /* ic_launcher-114x114.png in Resources */, 209 52FA364816899C63004C280A /* Default-568h@2x.png in Resources */, 218 210 ); 219 211 runOnlyForDeploymentPostprocessing = 0; … … 343 335 344 336 /* Begin XCConfigurationList section */ 345 28174C56167F2EA900104752 /* Build configuration list for PBXProject " Orbit" */ = {337 28174C56167F2EA900104752 /* Build configuration list for PBXProject "orbit" */ = { 346 338 isa = XCConfigurationList; 347 339 buildConfigurations = ( -
iOS/Orbit/orbit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rdccf843 r2aabdf3 3 3 version = "1.0"> 4 4 <FileRef 5 location = "self: Orbit.xcodeproj">5 location = "self:orbit.xcodeproj"> 6 6 </FileRef> 7 7 </Workspace>
Note: See TracChangeset
for help on using the changeset viewer.