Index: releases/AntiRSI/1.4njr3/AUTHORS
===================================================================
--- releases/AntiRSI/1.4njr3/AUTHORS	(revision 349)
+++ releases/AntiRSI/1.4njr3/AUTHORS	(revision 349)
@@ -0,0 +1,2 @@
+Onne Gorter <o.gorter@gmail.com>
+Nicholas Riley <antirsi@sabi.net>
Index: releases/AntiRSI/1.4njr3/AntiRSI.h
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSI.h	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSI.h	(revision 349)
@@ -0,0 +1,155 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "AntiRSIView.h"
+#import "CTBadge.h"
+
+#define sLatestVersionURL @"http://web.sabi.net/nriley/software/AntiRSI-version.txt"
+#define sURL @"http://web.sabi.net/nriley/software/#antirsi"
+#define sVersion @"1.4njr3"
+
+typedef enum _AntiRSIState {
+    s_normal = 0,
+    s_taking_micro_pause,
+    s_taking_work_break,
+} AntiRSIState;
+
+@interface AntiRSI : NSObject
+{
+    // views to display current status in
+    IBOutlet AntiRSIView *view;
+    IBOutlet NSLevelIndicator *progress;
+    IBOutlet NSButton *postpone;
+    IBOutlet NSTextField *time;
+    IBOutlet NSTextField *next_break;
+    IBOutlet NSTextField *session_time;
+    IBOutlet NSTextField *status;
+    IBOutlet NSTextField *version; // XXX unused?
+    IBOutlet NSDatePicker *reset_session_time;
+    
+    // dock menu
+    IBOutlet NSMenu *dock_menu;
+    IBOutlet NSMenuItem *session_time_item;
+    
+    // dock icon image
+    NSImage* dock_image;
+    NSImage* original_dock_image;
+    CTBadge* dock_badge;
+	
+    // window to display the views in
+    NSWindow *main_window;
+    
+    // timer that ticks every second to update
+    NSTimer *mtimer;
+    
+    // various timers
+    double micro_pause_t;
+    double work_break_t;
+    double micro_pause_taking_t;
+    double work_break_taking_t;
+    double work_break_taking_cached_t;
+    double work_break_taking_cached_date;
+    double session_t;
+    double date;
+    double reset_session_date;
+		
+    // various timing lengths
+    int micro_pause_period;
+    int micro_pause_duration;
+    int work_break_period;
+    int work_break_duration;
+    
+    double sample_interval;
+    
+    // verious other options
+    bool lock_focus;
+    bool draw_dock_image;
+    bool draw_dock_badge;
+    bool draw_dock_image_q;
+    bool reset_session_timer_daily;
+    bool reset_session_timer_after;
+    NSCalendarDate *reset_session_timer_time;
+    int reset_session_timer_after_hours;
+	
+    // various colors
+    NSColor* taking;
+    NSColor* elapsed;
+    NSColor* background;
+    NSColor* darkbackground;
+    
+    // state we are in
+    AntiRSIState state;
+    
+    // history filter
+    double h0;
+    double h1;
+    double h2;
+}
+
+//bindings
+- (void)setMicro_pause_duration:(float)f;
+- (void)setMicro_pause_period:(float)f;
+- (void)setWork_break_period:(float)f;
+- (void)setWork_break_period:(float)f;
+- (void)setSample_interval:(NSString *)s;
+- (void)setDraw_dock_image:(BOOL)b;
+- (void)setBackground:(NSColor *)c;
+
+// goto website button
+- (IBAction)gotoWebsite:(id)sender;
+
+// check updates
+- (IBAction)checkForUpdate:(id)sender;
+
+// postpone button
+- (IBAction)postpone:(id)sender;
+
+// workbreak now menu item
+- (IBAction)breakNow:(id)sender;
+
+// reset session time menu item
+- (IBAction)resetSession:(id)sender;
+
+// returns string of the form "Session: 12:34:56"
+- (NSString *)sessionTimeString;
+
+// one second ticks away ...
+- (void)tick:(NSTimer *)timer;
+
+// reset all timers
+- (void)resetTimers;
+
+// draw the dock icon
+- (void)drawDockImage;
+
+// run the micro pause window
+- (void)doMicroPause;
+
+// run the work break window
+- (void)doWorkBreak;
+
+// stop micro pause or work break
+- (void)endBreak;
+
+// update window
+- (void)updateBreakWindowDuration:(double)duration progress:(double)progress_t nextBreak:(double)nextBreak;
+
+@end
Index: releases/AntiRSI/1.4njr3/AntiRSI.m
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSI.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSI.m	(revision 349)
@@ -0,0 +1,738 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import "AntiRSI.h"
+
+#include <math.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+extern CFTimeInterval CGSSecondsSinceLastInputEvent(unsigned long eventType);
+
+static int badge_session_minutes = -1;
+
+@implementation AntiRSI
+
+- (void)computeResetSessionDate;
+{
+    NSCalendarDate *now = [NSCalendarDate calendarDate];
+    NSCalendarDate *reset =
+    [NSCalendarDate dateWithYear:[now yearOfCommonEra]
+			   month:[now monthOfYear]
+			     day:[now dayOfMonth]
+			    hour:[reset_session_timer_time hourOfDay]
+			  minute:[reset_session_timer_time minuteOfHour]
+			  second:0
+			timeZone:[NSTimeZone systemTimeZone]];
+    if ([now compare:reset] != NSOrderedAscending)
+        reset = [reset dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
+    reset_session_date = [reset timeIntervalSinceReferenceDate];
+}
+
+// bindings methods
+- (void)setMicro_pause_duration:(float)f
+{
+    micro_pause_duration = round(f);
+    if (s_taking_micro_pause == state) {
+	[progress setMaxValue:micro_pause_duration];
+	[progress setDoubleValue:micro_pause_taking_t];
+    }
+}
+
+- (void)setMicro_pause_period:(float)f
+{	micro_pause_period = 60 * round(f); }
+
+- (void)setWork_break_duration:(float)f
+{   
+    work_break_duration = 60 * round(f); 
+    if (s_taking_work_break == state) {
+	[progress setMaxValue:work_break_duration / 60];
+	[progress setDoubleValue:work_break_taking_t / 60 - 0.5];
+    }
+}
+
+- (void)setWork_break_period:(float)f
+{	work_break_period = 60 * round(f); }
+
+- (void)setReset_session_timer_time:(NSDate *)d;
+{
+    if (reset_session_timer_time != nil)
+        [reset_session_timer_time autorelease];
+    reset_session_timer_time = [[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:[d timeIntervalSinceReferenceDate]];
+    [reset_session_timer_time setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
+    [self computeResetSessionDate];
+}
+
+- (void)installTimer:(double)interval
+{
+    if (mtimer != nil) {
+	[mtimer invalidate];
+	[mtimer autorelease];
+    }
+    mtimer = [[NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(tick:)
+                                             userInfo:nil repeats:YES] retain];
+}
+
+- (void)setSample_interval:(NSString *)s
+{
+    sample_interval = 1;
+    if ([s isEqualToString:@"Super Smooth"]) sample_interval = 0.1;
+    if ([s isEqualToString:@"Smooth"]) sample_interval = 0.33;
+    if ([s isEqualToString:@"Normal"]) sample_interval = 1;
+    if ([s isEqualToString:@"Low"]) sample_interval = 2;
+    
+    [self installTimer:sample_interval];
+}
+
+- (void)setDraw_dock_image:(BOOL)b 
+{
+    draw_dock_image=b;
+    if (!b) {
+	[NSApp setApplicationIconImage:[NSImage imageNamed:@"AntiRSI"]];
+    } else {
+	[self drawDockImage];
+    }
+}
+
+- (void)setBackground:(NSColor *)c
+{
+    [background autorelease];
+    background=[c retain];
+    
+    // make new darkbackground color
+    float r,g,b,a;
+    [background getRed:&r green:&g blue:&b alpha:&a];
+    [darkbackground autorelease];
+    darkbackground=[[NSColor colorWithCalibratedRed:r*0.35 green:g*0.35 blue:b*0.35 alpha:a+0.2] retain];
+    
+    [self drawDockImage];
+}
+
+- (void)setElapsed:(NSColor *)c
+{
+    [elapsed autorelease];
+    elapsed=[c retain];
+    [dock_badge setBadgeColor:elapsed];
+    badge_session_minutes = -1;
+    [self drawDockImage];
+}
+
+- (void)setTaking:(NSColor *)c
+{
+    [taking autorelease];
+    taking=[c retain];
+    [self drawDockImage];
+}
+
+// end of bindings
+
+- (void)resetTimers;
+{
+    // set timers to 0
+    micro_pause_t = 0;
+    work_break_t = 0;
+    micro_pause_taking_t = 0;
+    work_break_taking_t = 0;
+    work_break_taking_cached_t = 0;
+    work_break_taking_cached_date = 0;
+    session_t = 0;
+}
+
+- (void)awakeFromNib
+{
+    // want transparancy
+    [NSColor setIgnoresAlpha:NO];
+    
+    // initial colors
+    elapsed = [[NSColor colorWithCalibratedRed:0.3 green:0.3 blue:0.9 alpha:0.95] retain];
+    taking = [[NSColor colorWithCalibratedRed:0.3 green:0.9 blue:0.3 alpha:0.90] retain];
+    background = [NSColor colorWithCalibratedRed:0.9 green:0.9 blue:0.9 alpha:0.7];
+    
+    //initial values
+    micro_pause_period = 4*60;
+    micro_pause_duration = 13;
+    work_break_period = 50*60;
+    work_break_duration = 8*60;
+    sample_interval = 1;
+    
+    // set current state
+    state = s_normal;
+    [self resetTimers];
+    
+    // initialize dock image
+    dock_image = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+    [dock_image setCacheMode:NSImageCacheNever];
+    original_dock_image = [NSImage imageNamed:@"AntiRSI"];
+    draw_dock_image_q = YES;
+    dock_badge = [[CTBadge systemBadge] retain];
+    [dock_badge setBadgeColor:elapsed];
+    
+    // setup main window that will show either micropause or workbreak
+    main_window = [[NSWindow alloc] initWithContentRect:[view frame]
+					      styleMask:NSBorderlessWindowMask
+						backing:NSBackingStoreBuffered defer:YES];
+    [main_window setBackgroundColor:[NSColor clearColor]];
+    [main_window setLevel:NSStatusWindowLevel];
+    [main_window setAlphaValue:0.85];
+    [main_window setOpaque:NO];
+    [main_window setHasShadow:NO];
+    [main_window setMovableByWindowBackground:YES];
+    [main_window center];
+    [main_window setContentView:view];
+    NSTimeZone *utcZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
+    [reset_session_time setTimeZone:utcZone];
+    [progress setEnabled:NO];
+    NSFont *myriad = [NSFont fontWithName: @"Myriad" size: 40];
+    if (myriad) [status setFont: myriad];
+    
+    // initialze history filter
+    h0 = 0;
+    h1 = 0;
+    h2 = 0;
+    
+    // initialize ticks
+    date = [NSDate timeIntervalSinceReferenceDate];
+    
+    // set background now
+    [self setBackground:background];
+    
+    // create initial values
+    NSUserDefaultsController *dc = [NSUserDefaultsController sharedUserDefaultsController];
+    NSMutableDictionary* initial = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+				    [NSNumber numberWithFloat:4], @"micro_pause_period",
+				    [NSNumber numberWithFloat:13], @"micro_pause_duration",
+				    [NSNumber numberWithFloat:50], @"work_break_period",
+				    [NSNumber numberWithFloat:8], @"work_break_duration",
+				    @"Smooth", @"sample_interval",
+				    [NSNumber numberWithBool:YES], @"draw_dock_image",
+				    [NSNumber numberWithBool:YES], @"draw_dock_badge",
+				    [NSNumber numberWithBool:NO], @"lock_focus",
+				    [NSNumber numberWithBool:NO], @"reset_session_timer_daily",
+				    [NSNumber numberWithBool:NO], @"reset_session_timer_after",
+				    [NSCalendarDate dateWithYear:2000 month:1 day:1 hour:6 minute:0 second:0 timeZone:utcZone], @"reset_session_timer_time",
+				    [NSNumber numberWithInt:8], @"reset_session_timer_after_hours",
+				    [NSArchiver archivedDataWithRootObject:elapsed], @"elapsed",
+				    [NSArchiver archivedDataWithRootObject:taking], @"taking",
+				    [NSArchiver archivedDataWithRootObject:background], @"background",
+				    nil];
+    [[NSUserDefaults standardUserDefaults] registerDefaults:initial];
+    [dc setInitialValues:initial];
+    
+    // bind to defauls controller
+    [self bind:@"micro_pause_period" toObject:dc withKeyPath:@"values.micro_pause_period" options:nil];
+    [self bind:@"micro_pause_duration" toObject:dc withKeyPath:@"values.micro_pause_duration" options:nil];
+    [self bind:@"work_break_period" toObject:dc withKeyPath:@"values.work_break_period" options:nil];
+    [self bind:@"work_break_duration" toObject:dc withKeyPath:@"values.work_break_duration" options:nil];
+    [self bind:@"sample_interval" toObject:dc withKeyPath:@"values.sample_interval" options:nil];
+    [self bind:@"draw_dock_image" toObject:dc withKeyPath:@"values.draw_dock_image" options:nil];
+    [self bind:@"draw_dock_badge" toObject:dc withKeyPath:@"values.draw_dock_badge" options:nil];
+    [self bind:@"lock_focus" toObject:dc withKeyPath:@"values.lock_focus" options:nil];
+    [self bind:@"reset_session_timer_daily" toObject:dc withKeyPath:@"values.reset_session_timer_daily" options:nil];
+    [self bind:@"reset_session_timer_after" toObject:dc withKeyPath:@"values.reset_session_timer_after" options:nil];
+    [self bind:@"reset_session_timer_time" toObject:dc withKeyPath:@"values.reset_session_timer_time" options:nil];
+    [self bind:@"reset_session_timer_after_hours" toObject:dc withKeyPath:@"values.reset_session_timer_after_hours" options:nil];
+    NSDictionary* unarchive = [NSDictionary dictionaryWithObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
+    [self bind:@"elapsed" toObject:dc withKeyPath:@"values.elapsed" options:unarchive];
+    [self bind:@"taking" toObject:dc withKeyPath:@"values.taking" options:unarchive];
+    [self bind:@"background" toObject:dc withKeyPath:@"values.background" options:unarchive];
+    
+    // alert every binding
+    [dc revert:self];
+    
+    // start the timer
+    [self installTimer:sample_interval];
+    
+    // about dialog
+    [version setStringValue:[NSString stringWithFormat:@"Version %@", sVersion]]; 
+}
+
+// tick every second and update status
+- (void)tick:(NSTimer *)timer
+{
+    // calculate time since last tick
+    NSTimeInterval new_date = [NSDate timeIntervalSinceReferenceDate];
+    NSTimeInterval tick_time = new_date - date;
+    date = new_date;
+    
+    if (reset_session_timer_daily && date >= reset_session_date) {
+        [self resetSession:nil];
+        [self computeResetSessionDate];
+        return;
+    }
+    
+    // check if we are still on track of normal time, otherwise we might have slept or something
+    if (tick_time > work_break_duration) {
+	// set timers to 0
+	micro_pause_t = 0;
+	work_break_t = 0;
+	micro_pause_taking_t = micro_pause_duration;
+	work_break_taking_t = work_break_duration;
+	if (s_normal != state) {
+	    [self endBreak];
+	}
+	// and do stuff on next tick
+	return;
+    }
+    
+    // just did a whole micropause beyond normal time
+    if (tick_time > micro_pause_duration && s_taking_work_break != state) {
+	// set micro_pause timers to 0
+	micro_pause_t = 0;
+	micro_pause_taking_t = micro_pause_duration;
+	if (s_normal != state) {
+	    [self endBreak];
+	}
+	// and do stuff on next tick
+	return;
+    }
+    
+    // get idle time in seconds
+    CFTimeInterval idle_time = CGSSecondsSinceLastInputEvent(kCGAnyInputEventType);
+    // CFTimeInterval cgs_idle_time = idle_time;
+    // from other people's reverse engineering of this function, on MDD G4s this can return a large positive number when input is in progress
+    if (idle_time >= 18446744000.0) {
+        idle_time = 0;
+    } else if (CGEventSourceSecondsSinceLastEventType != NULL) {
+	CGEventType eventTypes[] = { kCGEventLeftMouseDown, kCGEventLeftMouseUp, kCGEventRightMouseDown, kCGEventRightMouseUp, kCGEventMouseMoved, kCGEventLeftMouseDragged, kCGEventRightMouseDragged, kCGEventKeyDown, kCGEventKeyUp, kCGEventFlagsChanged, kCGEventScrollWheel, kCGEventTabletPointer, kCGEventTabletProximity, kCGEventOtherMouseDown, kCGEventOtherMouseUp, kCGEventOtherMouseDragged, kCGEventNull };
+        CFTimeInterval event_idle_time;
+        idle_time = DBL_MAX;
+        for (CGEventType *eventType = eventTypes ; *eventType != kCGEventNull ; eventType++) {
+            event_idle_time = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, *eventType);
+            if (event_idle_time < idle_time) idle_time = event_idle_time;
+        }
+    }
+    // NSLog(@"CGEventSource %.2f, CGS %.2f", idle_time, cgs_idle_time);
+    
+    if (reset_session_timer_after && idle_time > reset_session_timer_after_hours * 3600) {
+        [self resetSession:nil];
+        return;
+    }
+    
+    // calculate slack, this gives a sort of 3 history filtered idea.
+    BOOL slack = (h2 + h1 + h0 > 15);
+    
+    // if new event comes in history bumps up
+    if (h0 >= idle_time || idle_time < sample_interval) {
+	h2 = h1;
+	h1 = h0;
+    }
+    h0 = idle_time;
+    
+    switch (state) {
+	case s_normal:
+	    // idle_time needs to be at least 0.3 * micro_pause_duration before kicking in
+	    // but we cut the user some slack based on previous idle_times
+	    if (idle_time <= micro_pause_duration * 0.3 && !slack) {
+		micro_pause_t += tick_time;
+		work_break_t += tick_time;
+                if (idle_time < 1) {
+                    session_t += tick_time;
+                }
+		micro_pause_taking_t = 0;
+		if (work_break_taking_t > 0) {
+		    work_break_taking_cached_t = work_break_taking_t;
+		    work_break_taking_cached_date = date;
+		}
+		work_break_taking_t = 0;
+	    } else if (micro_pause_t > 0) {
+		// oke, leaway is over, increase micro_pause_taking_t unless micro_pause is already over
+		//micro_pause_t stays put
+		work_break_t += tick_time;
+		micro_pause_taking_t += tick_time;
+		work_break_taking_t = 0;
+	    }
+	    
+	    // if micro_pause_taking_t is above micro_pause_duration, then micro pause is over, 
+	    // if still idleing workbreak_taking_t kicks in unless it is already over
+	    if (micro_pause_taking_t >= micro_pause_duration && work_break_t > 0) {
+		work_break_taking_t += tick_time;
+		micro_pause_t = 0;
+	    }
+	    
+	    // if work_break_taking_t is above work_break_duration, then work break is over
+	    if (work_break_taking_t >= work_break_duration) {
+		micro_pause_t = 0;
+		work_break_t = 0;
+		// micro_pause_taking_t stays put
+		// work_break_taking_t stays put
+	    }
+	    
+	    // if user needs to take a micro pause
+	    if (micro_pause_t >= micro_pause_period) {
+		// anticipate next workbreak by not issuing this micro_pause ...
+		if (work_break_t > work_break_period - (micro_pause_period / 2)) {
+		    work_break_t = work_break_period;
+		    [self doWorkBreak];
+		} else {
+		    [self doMicroPause];
+		}
+	    }
+	    
+	    // if user needs to take a work break
+	    if (work_break_t >= work_break_period) {
+		// stop micro_pause stuff
+		micro_pause_t = 0;
+		micro_pause_taking_t = micro_pause_duration;
+		// and display window
+		[self doWorkBreak];
+	    }
+	    break;
+	    
+	    // taking a micro pause with window
+	    case s_taking_micro_pause:
+	    // continue updating timers
+	    micro_pause_taking_t += tick_time;
+	    work_break_t += tick_time;
+	    
+	    // if we don't break, or interrupt the break, reset it
+	    if (idle_time < 1 && !slack) {
+		micro_pause_taking_t = 0;
+                session_t += tick_time;
+	    }
+	    
+	    // update window
+            [self updateBreakWindowDuration:micro_pause_duration progress:micro_pause_taking_t
+                                  nextBreak:work_break_period - work_break_t];
+	    
+	    // check if we done enough
+	    if (micro_pause_taking_t > micro_pause_duration) {
+		micro_pause_t = 0;
+		[self endBreak];
+	    }
+	    
+	    // if workbreak must be run ...
+	    if (work_break_t >= work_break_period) {
+		// stop micro_pause stuff
+		micro_pause_t = 0;
+		micro_pause_taking_t = micro_pause_duration;
+		// and display window
+		[self doWorkBreak];
+	    } else {
+                double slip = (micro_pause_duration - micro_pause_taking_t) - (int)(micro_pause_duration - micro_pause_taking_t);
+                [self installTimer: slip < 0.1 ? 1 : slip];
+            }
+	    break;
+	    
+	    // taking a work break with window
+	    case s_taking_work_break:
+	    // increase work_break_taking_t
+	    if (idle_time >= 2 || work_break_taking_t < 3) {
+		work_break_taking_t += tick_time;
+	    } else if (idle_time < 1) {
+                session_t += tick_time;
+            }
+	    
+	    // draw window
+            [self updateBreakWindowDuration:work_break_duration progress:work_break_taking_t
+                                  nextBreak:work_break_period + work_break_duration - work_break_taking_t];
+	    
+	    // and check if we done enough
+	    if (work_break_taking_t > work_break_duration) {
+		micro_pause_t = 0;
+		micro_pause_taking_t = micro_pause_duration;
+		work_break_t = 0;
+		work_break_taking_t = work_break_duration;
+		[self endBreak];
+	    } else {
+                double slip = (work_break_duration - work_break_taking_t) - (int)(work_break_duration - work_break_taking_t);
+                [self installTimer: slip < 0.1 ? 1 : slip];
+            }
+	    break;
+    }
+    
+    // draw dock image
+    if (draw_dock_image) [self drawDockImage];
+}
+
+// dock image
+- (NSMenu *)applicationDockMenu:(NSApplication *)sender;
+{
+    [session_time_item setTitle:[self sessionTimeString]];
+    return dock_menu;
+}
+
+// draw the dock icon
+- (void)drawDockImage
+{
+    [dock_image lockFocus];
+    
+    // clear all
+    [[NSColor clearColor] set];  
+    NSRectFill(NSMakeRect(0,0,127,127));
+    
+    NSBezierPath* p;
+    float end;
+    
+    //draw background circle
+    [darkbackground set];
+    p =[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(6,6,115,115)];
+    [p setLineWidth:4];
+    [p stroke];
+    
+    //fill
+    [background set];
+    [[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(8,8,111,111)] fill];
+    
+    //put dot in middle
+    [darkbackground set];
+    [[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(59,59,9,9)] fill];
+    
+    // reuse this one
+    p = [NSBezierPath bezierPath];
+    
+    // draw work_break
+    [elapsed set];
+    end = 360 - (360.0 / work_break_period * work_break_t - 90);
+    if (end <= 90) end=90.1;
+    [p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:40 startAngle:90 endAngle:end clockwise:YES];
+    [p setLineWidth:22];
+    [p stroke];
+    
+    // draw work break taking
+    [taking set];
+    [p removeAllPoints];
+    end = 360 - (360.0 / work_break_duration * work_break_taking_t - 90);
+    if (end <= 90) end=90.1;
+    [p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:40 startAngle:90 endAngle:end clockwise:YES];
+    [p setLineWidth:18];
+    [p stroke];
+    
+    // draw micro pause
+    [elapsed set];
+    [p removeAllPoints];
+    end = 360 - (360.0 / micro_pause_period * micro_pause_t - 90);
+    if (end <= 90) end = 90.1;
+    [p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:17 startAngle:90 endAngle:end clockwise:YES];
+    [p setLineWidth:22];
+    [p stroke];
+    
+    // draw micro pause taking
+    [taking set];
+    [p removeAllPoints];
+    end = 360 - (360.0 / micro_pause_duration * micro_pause_taking_t - 90);
+    if (end <= 90) end = 90.1;
+    [p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:17 startAngle:90 endAngle:end clockwise:YES];
+    [p setLineWidth:18];
+    [p stroke];
+    
+    // draw session time
+    if (draw_dock_badge) {
+        static NSImage *badge = nil;
+        int session_minutes = (int)session_t / 60;
+        if (badge_session_minutes != session_minutes) {
+            if (badge != nil) [badge release];
+            badge = [[dock_badge badgeOverlayImageForString: [NSString stringWithFormat:@"%d:%02d", session_minutes / 60, session_minutes % 60] insetX: 3 y: 3] retain];
+            badge_session_minutes = session_minutes;
+        }
+        [badge compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];
+    }
+    
+    [dock_image unlockFocus];
+    
+    // and set it in the dock check draw_dock_image one last time ...
+    if (draw_dock_image_q) [NSApp setApplicationIconImage:dock_image];
+}
+
+// done with micro pause or work break
+- (void)endBreak
+{
+    [main_window orderOut:NULL];
+    state = s_normal;
+    // reset time interval to user's choice
+    [self installTimer:sample_interval];
+}
+
+// display micro_pause window with appropriate widgets and progress bar
+- (void)doMicroPause
+{
+    micro_pause_taking_t = 0;
+    [status setStringValue:@"Micro Pause"];
+    [progress setMaxValue:micro_pause_duration];
+    [progress setDoubleValue:micro_pause_taking_t];
+    [progress setWarningValue: 1];
+    [progress setCriticalValue: micro_pause_duration];
+    [postpone setHidden:YES];
+    state = s_taking_micro_pause;
+    [self tick: nil];
+    [main_window center];
+    [main_window orderFrontRegardless];
+}
+
+// display work_break window with appropriate widgets and progress bar
+- (void)doWorkBreak
+{
+    work_break_taking_t = 0;
+    // incase you were already having an implicit work break and clicked the take work break now button
+    // not more then 20 seconds ago we took a natural break longer then 0.2 * normal work break duration 
+    if (date - work_break_taking_cached_date < 20 && work_break_taking_cached_t > work_break_duration * 0.2) {
+	work_break_taking_t = work_break_taking_cached_t;
+    } 
+    [status setStringValue:@"Work Break"];
+    [progress setMaxValue:work_break_duration / 60];
+    [progress setDoubleValue:work_break_taking_t / 60 - 0.5];
+    [progress setWarningValue: 0];
+    [progress setCriticalValue: 0.4];
+    [postpone setHidden:NO];
+    state = s_taking_work_break;
+    [self tick: nil];
+    [main_window center];
+    [main_window orderFrontRegardless];
+}
+
+- (NSString *)sessionTimeString;
+{
+    int seconds = lrint(session_t);
+    return [NSString stringWithFormat:@"Session: %d:%02d:%02d", seconds / 3600,
+	    (seconds / 60) % 60, seconds % 60];
+}
+
+- (void)updateBreakWindowDuration:(double)duration progress:(double)progress_t nextBreak:(double)nextBreak;
+{
+    // progress
+    [progress setDoubleValue:duration >= 60 ? (progress_t / 60 - 0.5) : progress_t];
+    
+    // time left
+    int timeLeft = lrint(duration - progress_t);
+    [time setStringValue:[NSString stringWithFormat:@"%d:%02d", timeLeft / 60, timeLeft % 60]];
+    
+    // cumulative typing time in this session (e.g. today)
+    [session_time setStringValue:[self sessionTimeString]];
+    
+    // next break
+    int minutes = round(nextBreak / 60.0);
+    
+    // nice hours, minutes ... 
+    if (minutes > 60) {
+	[next_break setStringValue:[NSString stringWithFormat:@"next break in %d:%02d hours", 
+				    minutes / 60, minutes % 60]];
+    } else {
+	[next_break setStringValue:[NSString stringWithFormat:@"next break in %d minutes", minutes]];
+    }
+    
+    // if user likes to be interrupted
+    if (lock_focus) {
+        [NSApp activateIgnoringOtherApps:YES];
+        [main_window makeKeyAndOrderFront:self];
+    }
+}
+
+// goto website
+- (IBAction)gotoWebsite:(id)sender
+{
+    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:sURL]];
+}
+
+// check for update
+- (IBAction)checkForUpdate:(id)sender
+{
+    NSString *latest_version =
+    [NSString stringWithContentsOfURL: [NSURL URLWithString:sLatestVersionURL]];
+    
+    if (latest_version == Nil) latest_version = @"";
+    latest_version = [latest_version stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+    
+    if ([latest_version length] == 0) {
+	NSRunInformationalAlertPanel(
+	     @"Unable to Determine",
+	     @"Unable to determine the latest AntiRSI version number.",
+	     @"Ok", nil, nil);
+    } else if ([latest_version compare:sVersion] == NSOrderedDescending) {
+	int r = NSRunInformationalAlertPanel(
+	     @"New Version",
+	     [NSString stringWithFormat:@"A new version (%@) of AntiRSI is available; would you like to go to the website now?", latest_version],
+	     @"Goto Website", @"Cancel", nil);
+	if (r == NSOKButton) {
+	    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:sURL]];
+	}
+    } else {
+    	NSRunInformationalAlertPanel(
+	     @"No Update Available", 
+	     @"This is the latest version of AntiRSI.", 
+	     @"OK", nil, nil);
+    }
+}
+
+// stop work break and postpone by 10 minutes
+- (IBAction)postpone:(id)sender
+{
+    if (s_taking_work_break == state) {
+	micro_pause_t = 0;
+	micro_pause_taking_t = 0;
+	work_break_taking_t = 0;
+	work_break_taking_cached_t = 0;
+	work_break_t -= 10*60; // decrease with 10 minutes
+	if (work_break_t < 0) work_break_t = 0;
+	[self endBreak];
+    }
+}
+
+- (IBAction)breakNow:(id)sender
+{
+    [self doWorkBreak];
+}
+
+- (IBAction)resetSession:(id)sender;
+{
+    if (s_normal != state) {
+        [self endBreak];
+    }
+    [self resetTimers];
+}
+
+// validate menu items
+- (BOOL)validateMenuItem:(NSMenuItem *)anItem
+{
+    if ([anItem action] == @selector(breakNow:) && state == s_normal)
+	return YES;
+    
+    if ([anItem action] == @selector(postpone:) && state == s_taking_work_break)
+	return YES;
+    
+    if ([anItem action] == @selector(resetSession:))
+	return YES;
+    
+    if ([anItem action] == @selector(gotoWebsite:))
+	return YES;
+    
+    if ([anItem action] == @selector(checkForUpdate:))
+	return YES;
+    
+    return NO;
+}
+
+// we are delegate of NSApplication, so we can restore the icon on quit.
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+    // make sure timer doesn't tick once more ...
+    draw_dock_image_q = NO;
+    [mtimer invalidate];
+    [mtimer autorelease];
+    mtimer = nil;
+    [dock_image release];
+    // stupid fix for icon beeing restored ... it is not my fault,
+    // the dock or NSImage or setApplicationIconImage seem to be caching or taking
+    // snapshot or something ... !
+    [NSApp setApplicationIconImage:original_dock_image];
+    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+    [NSApp setApplicationIconImage:original_dock_image];
+    
+}
+
+@end
+
Index: releases/AntiRSI/1.4njr3/AntiRSI.xcodeproj/project.pbxproj
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSI.xcodeproj/project.pbxproj	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSI.xcodeproj/project.pbxproj	(revision 349)
@@ -0,0 +1,448 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		464D9ADE0C6A622B005A0582 /* CTBadge.h in Headers */ = {isa = PBXBuildFile; fileRef = 464D9ADA0C6A622B005A0582 /* CTBadge.h */; };
+		464D9ADF0C6A622B005A0582 /* CTBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = 464D9ADB0C6A622B005A0582 /* CTBadge.m */; };
+		464D9AE00C6A622B005A0582 /* CTGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 464D9ADC0C6A622B005A0582 /* CTGradient.h */; };
+		464D9AE10C6A622B005A0582 /* CTGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 464D9ADD0C6A622B005A0582 /* CTGradient.m */; };
+		464D9B790C6A760B005A0582 /* CTBadge_1.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 464D9B750C6A760B005A0582 /* CTBadge_1.pdf */; };
+		464D9B7A0C6A760B005A0582 /* CTBadge_3.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 464D9B760C6A760B005A0582 /* CTBadge_3.pdf */; };
+		464D9B7B0C6A760B005A0582 /* CTBadge_4.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 464D9B770C6A760B005A0582 /* CTBadge_4.pdf */; };
+		464D9B7C0C6A760B005A0582 /* CTBadge_5.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 464D9B780C6A760B005A0582 /* CTBadge_5.pdf */; };
+		4DB6164E061B59EA002EF355 /* AntiRSI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DB6164C061B59EA002EF355 /* AntiRSI.h */; };
+		4DB6164F061B59EA002EF355 /* AntiRSI.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DB6164D061B59EA002EF355 /* AntiRSI.m */; };
+		4DF73F67061E136200B0D9C9 /* AntiRSIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF73F65061E136200B0D9C9 /* AntiRSIView.m */; };
+		4DF73F68061E136200B0D9C9 /* AntiRSIView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF73F66061E136200B0D9C9 /* AntiRSIView.h */; };
+		4DF73F86061E155C00B0D9C9 /* AntiRSI.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */; };
+		8D1107280486CEB800E47090 /* AntiRSI_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */; };
+		8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+		8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+		8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+		8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+		E1203BFC0894184900759E75 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1203BFB0894184900759E75 /* ApplicationServices.framework */; };
+		E1F60361098592D800806C3B /* AntiRSILevelIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */; };
+		E1F60362098592D800806C3B /* AntiRSILevelIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+		29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+		32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AntiRSI_Prefix.pch; sourceTree = "<group>"; };
+		464D9ADA0C6A622B005A0582 /* CTBadge.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CTBadge.h; path = CTBadge/CTBadge.h; sourceTree = "<group>"; };
+		464D9ADB0C6A622B005A0582 /* CTBadge.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = CTBadge.m; path = CTBadge/CTBadge.m; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
+		464D9ADC0C6A622B005A0582 /* CTGradient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CTGradient.h; path = CTBadge/CTGradient.h; sourceTree = "<group>"; };
+		464D9ADD0C6A622B005A0582 /* CTGradient.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = CTGradient.m; path = CTBadge/CTGradient.m; sourceTree = "<group>"; };
+		464D9B750C6A760B005A0582 /* CTBadge_1.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = CTBadge_1.pdf; sourceTree = "<group>"; };
+		464D9B760C6A760B005A0582 /* CTBadge_3.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = CTBadge_3.pdf; sourceTree = "<group>"; };
+		464D9B770C6A760B005A0582 /* CTBadge_4.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = CTBadge_4.pdf; sourceTree = "<group>"; };
+		464D9B780C6A760B005A0582 /* CTBadge_5.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = CTBadge_5.pdf; sourceTree = "<group>"; };
+		4DB6164C061B59EA002EF355 /* AntiRSI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSI.h; sourceTree = "<group>"; };
+		4DB6164D061B59EA002EF355 /* AntiRSI.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSI.m; sourceTree = "<group>"; tabWidth = 8; wrapsLines = 1; };
+		4DF73F65061E136200B0D9C9 /* AntiRSIView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSIView.m; sourceTree = "<group>"; };
+		4DF73F66061E136200B0D9C9 /* AntiRSIView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSIView.h; sourceTree = "<group>"; };
+		4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AntiRSI.icns; sourceTree = "<group>"; };
+		8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D1107320486CEB800E47090 /* AntiRSI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AntiRSI.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		E1203BFB0894184900759E75 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+		E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSILevelIndicator.m; sourceTree = "<group>"; };
+		E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSILevelIndicator.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8D11072E0486CEB800E47090 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+				E1203BFC0894184900759E75 /* ApplicationServices.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		080E96DDFE201D6D7F000001 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				4DB6164C061B59EA002EF355 /* AntiRSI.h */,
+				4DB6164D061B59EA002EF355 /* AntiRSI.m */,
+				4DF73F66061E136200B0D9C9 /* AntiRSIView.h */,
+				4DF73F65061E136200B0D9C9 /* AntiRSIView.m */,
+				E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */,
+				E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */,
+			);
+			name = Classes;
+			sourceTree = "<group>";
+		};
+		1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				E1203BFB0894184900759E75 /* ApplicationServices.framework */,
+				29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+				29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D1107320486CEB800E47090 /* AntiRSI.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* AntiRSI */ = {
+			isa = PBXGroup;
+			children = (
+				080E96DDFE201D6D7F000001 /* Classes */,
+				464D9AE40C6A622F005A0582 /* CTBadge */,
+				29B97315FDCFA39411CA2CEA /* Other Sources */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = AntiRSI;
+			sourceTree = "<group>";
+		};
+		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */,
+				29B97316FDCFA39411CA2CEA /* main.m */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */,
+				8D1107310486CEB800E47090 /* Info.plist */,
+				089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+				29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+				1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		464D9AE40C6A622F005A0582 /* CTBadge */ = {
+			isa = PBXGroup;
+			children = (
+				464D9B740C6A760B005A0582 /* badges */,
+				464D9ADA0C6A622B005A0582 /* CTBadge.h */,
+				464D9ADB0C6A622B005A0582 /* CTBadge.m */,
+				464D9ADC0C6A622B005A0582 /* CTGradient.h */,
+				464D9ADD0C6A622B005A0582 /* CTGradient.m */,
+			);
+			name = CTBadge;
+			sourceTree = "<group>";
+		};
+		464D9B740C6A760B005A0582 /* badges */ = {
+			isa = PBXGroup;
+			children = (
+				464D9B750C6A760B005A0582 /* CTBadge_1.pdf */,
+				464D9B760C6A760B005A0582 /* CTBadge_3.pdf */,
+				464D9B770C6A760B005A0582 /* CTBadge_4.pdf */,
+				464D9B780C6A760B005A0582 /* CTBadge_5.pdf */,
+			);
+			name = badges;
+			path = CTBadge/badges;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8D1107270486CEB800E47090 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D1107280486CEB800E47090 /* AntiRSI_Prefix.pch in Headers */,
+				4DB6164E061B59EA002EF355 /* AntiRSI.h in Headers */,
+				4DF73F68061E136200B0D9C9 /* AntiRSIView.h in Headers */,
+				E1F60362098592D800806C3B /* AntiRSILevelIndicator.h in Headers */,
+				464D9ADE0C6A622B005A0582 /* CTBadge.h in Headers */,
+				464D9AE00C6A622B005A0582 /* CTGradient.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		8D1107260486CEB800E47090 /* AntiRSI */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = E1203B7B0894152100759E75 /* Build configuration list for PBXNativeTarget "AntiRSI" */;
+			buildPhases = (
+				8D1107270486CEB800E47090 /* Headers */,
+				8D1107290486CEB800E47090 /* Resources */,
+				8D11072C0486CEB800E47090 /* Sources */,
+				8D11072E0486CEB800E47090 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = AntiRSI;
+			productInstallPath = "$(HOME)/Applications";
+			productName = AntiRSI;
+			productReference = 8D1107320486CEB800E47090 /* AntiRSI.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = E1203B7F0894152100759E75 /* Build configuration list for PBXProject "AntiRSI" */;
+			compatibilityVersion = "Xcode 2.4";
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+				Spanish,
+			);
+			mainGroup = 29B97314FDCFA39411CA2CEA /* AntiRSI */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8D1107260486CEB800E47090 /* AntiRSI */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D1107290486CEB800E47090 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
+				8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+				4DF73F86061E155C00B0D9C9 /* AntiRSI.icns in Resources */,
+				464D9B790C6A760B005A0582 /* CTBadge_1.pdf in Resources */,
+				464D9B7A0C6A760B005A0582 /* CTBadge_3.pdf in Resources */,
+				464D9B7B0C6A760B005A0582 /* CTBadge_4.pdf in Resources */,
+				464D9B7C0C6A760B005A0582 /* CTBadge_5.pdf in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8D11072C0486CEB800E47090 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072D0486CEB800E47090 /* main.m in Sources */,
+				4DB6164F061B59EA002EF355 /* AntiRSI.m in Sources */,
+				4DF73F67061E136200B0D9C9 /* AntiRSIView.m in Sources */,
+				E1F60361098592D800806C3B /* AntiRSILevelIndicator.m in Sources */,
+				464D9ADF0C6A622B005A0582 /* CTBadge.m in Sources */,
+				464D9AE10C6A622B005A0582 /* CTGradient.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C165DFE840E0CC02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				29B97319FDCFA39411CA2CEA /* English */,
+			);
+			name = MainMenu.nib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		E1203B7C0894152100759E75 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				DEBUGGING_SYMBOLS = YES;
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O0";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = YES;
+			};
+			name = Development;
+		};
+		E1203B7D0894152100759E75 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = NO;
+			};
+			name = Deployment;
+		};
+		E1203B7E0894152100759E75 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+			};
+			name = Default;
+		};
+		E1203B800894152100759E75 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_C_LANGUAGE_STANDARD = c99;
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Development;
+		};
+		E1203B810894152100759E75 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				GCC_C_LANGUAGE_STANDARD = c99;
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Deployment;
+		};
+		E1203B820894152100759E75 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_C_LANGUAGE_STANDARD = c99;
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Default;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		E1203B7B0894152100759E75 /* Build configuration list for PBXNativeTarget "AntiRSI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E1203B7C0894152100759E75 /* Development */,
+				E1203B7D0894152100759E75 /* Deployment */,
+				E1203B7E0894152100759E75 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+		E1203B7F0894152100759E75 /* Build configuration list for PBXProject "AntiRSI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E1203B800894152100759E75 /* Development */,
+				E1203B810894152100759E75 /* Deployment */,
+				E1203B820894152100759E75 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
Index: releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.h
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.h	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.h	(revision 349)
@@ -0,0 +1,8 @@
+/* AntiRSILevelIndicator */
+
+#import <Cocoa/Cocoa.h>
+
+@interface AntiRSILevelIndicator : NSLevelIndicator
+{
+}
+@end
Index: releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.m
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSILevelIndicator.m	(revision 349)
@@ -0,0 +1,10 @@
+#import "AntiRSILevelIndicator.h"
+
+@implementation AntiRSILevelIndicator
+
+- (BOOL)mouseDownCanMoveWindow;
+{
+    return true;
+}
+
+@end
Index: releases/AntiRSI/1.4njr3/AntiRSIView.h
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSIView.h	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSIView.h	(revision 349)
@@ -0,0 +1,27 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface AntiRSIView : NSView
+{
+}
+
+@end
Index: releases/AntiRSI/1.4njr3/AntiRSIView.m
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSIView.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSIView.m	(revision 349)
@@ -0,0 +1,69 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import "AntiRSIView.h"
+
+@implementation AntiRSIView
+
+- (void)drawRect:(NSRect)rect
+{
+    NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.90];
+    NSRect bgRect = [self frame];
+    int minX = NSMinX(bgRect);
+    int midX = NSMidX(bgRect);
+    int maxX = NSMaxX(bgRect);
+    int minY = NSMinY(bgRect);
+    int midY = NSMidY(bgRect);
+    int maxY = NSMaxY(bgRect);
+    float radius = 25.0; // correct value to duplicate Panther's App Switcher
+    NSBezierPath *bgPath = [NSBezierPath bezierPath];
+    
+    /* XXX from Casey Marshall's version; does it help with the hole-in-window problem? */
+    [[NSColor clearColor] set];
+    NSRectFill(bgRect);
+    /* XXX end */
+    
+    // Bottom edge and bottom-right curve
+    [bgPath moveToPoint:NSMakePoint(midX, minY)];
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY) 
+                                     toPoint:NSMakePoint(maxX, midY) 
+                                      radius:radius];
+    
+    // Right edge and top-right curve
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY) 
+                                     toPoint:NSMakePoint(midX, maxY) 
+                                      radius:radius];
+    
+    // Top edge and top-left curve
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY) 
+                                     toPoint:NSMakePoint(minX, midY) 
+                                      radius:radius];
+    
+    // Left edge and bottom-left curve
+    [bgPath appendBezierPathWithArcFromPoint:bgRect.origin 
+                                     toPoint:NSMakePoint(midX, minY) 
+                                      radius:radius];
+    [bgPath closePath];
+    
+    [bgColor set];
+    [bgPath fill];
+}
+
+@end
Index: releases/AntiRSI/1.4njr3/AntiRSI_Prefix.pch
===================================================================
--- releases/AntiRSI/1.4njr3/AntiRSI_Prefix.pch	(revision 349)
+++ releases/AntiRSI/1.4njr3/AntiRSI_Prefix.pch	(revision 349)
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'AntiRSI' target in the 'AntiRSI' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
Index: releases/AntiRSI/1.4njr3/COPYING
===================================================================
--- releases/AntiRSI/1.4njr3/COPYING	(revision 349)
+++ releases/AntiRSI/1.4njr3/COPYING	(revision 349)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: releases/AntiRSI/1.4njr3/CTBadge/CTBadge.h
===================================================================
--- releases/AntiRSI/1.4njr3/CTBadge/CTBadge.h	(revision 349)
+++ releases/AntiRSI/1.4njr3/CTBadge/CTBadge.h	(revision 349)
@@ -0,0 +1,48 @@
+//
+//  CTBadge.h
+//  CTWidgets
+//
+//  Created by Chad Weider on 2/14/07.
+//  Copyright (c) 2007 Chad Weider.
+//  Some rights reserved: <http://creativecommons.org/licenses/by/2.5/>
+//
+//  Version: 1.5
+
+#import <Cocoa/Cocoa.h>
+#import "CTGradient.h"
+
+extern const float CTLargeBadgeSize;
+extern const float CTSmallBadgeSize;
+extern const float CTLargeLabelSize;
+extern const float CTSmallLabelSize;
+
+@interface CTBadge : NSObject
+  {
+  NSColor *badgeColor;
+  NSColor *labelColor;
+  }
+
++ (CTBadge *)systemBadge;																//Classic white on red badge
++ (CTBadge *)badgeWithColor:(NSColor *)badgeColor labelColor:(NSColor *)labelColor;		//Badge of any color scheme
+
+- (NSImage *)smallBadgeForValue:(unsigned)value;				   //Image to use during drag operations
+- (NSImage *)smallBadgeForString:(NSString *)string;
+- (NSImage *)largeBadgeForValue:(unsigned)value;				   //For dock icons, etc
+- (NSImage *)largeBadgeForString:(NSString *)string;
+- (NSImage *)badgeOfSize:(float)size forValue:(unsigned)value;	   //A badge of arbitrary size,
+- (NSImage *)badgeOfSize:(float)size forString:(NSString *)string; //	<size> is the size in pixels of the badge
+																   //	not counting the shadow effect
+																   //	(image returned will be larger than <size>)
+
+- (NSImage *)badgeOverlayImageForValue:(unsigned)value insetX:(float)dx y:(float)dy;		//Returns a transparent 128x128 image
+- (NSImage *)badgeOverlayImageForString:(NSString *)string insetX:(float)dx y:(float)dy;	//  with Large badge inset dx/dy from the upper right
+- (void)badgeApplicationDockIconWithValue:(unsigned)value insetX:(float)dx y:(float)dy;		//Badges the Application's icon with <value>
+- (void)badgeApplicationDockIconWithString:(NSString *)string insetX:(float)dx y:(float)dy; //	and puts it on the dock
+
+- (void)setBadgeColor:(NSColor *)theColor;					//Sets the color used on badge
+- (void)setLabelColor:(NSColor *)theColor;					//Sets the color of the label
+
+- (NSColor *)badgeColor;									//Color currently being used on the badge
+- (NSColor *)labelColor;									//Color currently being used on the label
+
+@end
Index: releases/AntiRSI/1.4njr3/CTBadge/CTBadge.m
===================================================================
--- releases/AntiRSI/1.4njr3/CTBadge/CTBadge.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/CTBadge/CTBadge.m	(revision 349)
@@ -0,0 +1,311 @@
+//
+//  CTBadge.m
+//  CTWidgets
+//
+//  Created by Chad Weider on 2/14/07.
+//  Copyright (c) 2007 Chad Weider.
+//  Some rights reserved: <http://creativecommons.org/licenses/by/2.5/>
+//
+//  Version: 1.5
+
+#import "CTBadge.h"
+
+const float CTLargeBadgeSize = 46.;
+const float CTSmallBadgeSize = 23.;
+const float CTLargeLabelSize = 24.;
+const float CTSmallLabelSize = 11.;
+
+@interface CTBadge (Private)
+- (NSImage *)badgeMaskOfSize:(float)size length:(unsigned)length;			//return a badge with height of <size> to fit <length> characters
+- (NSAttributedString *)labelForString:(NSString *)string size:(unsigned)size;	//returns appropriately attributed label string (not autoreleased)
+- (CTGradient *)badgeGradient;												//gradient used to fill badge mask
+@end
+
+@implementation CTBadge
+
+- (id)init
+  {
+  self = [super init];
+  
+  if (self != nil)
+	{
+	badgeColor = nil;
+	labelColor = nil;
+	
+	[self setBadgeColor:[NSColor redColor]];
+	[self setLabelColor:[NSColor whiteColor]];
+	}
+  return self;
+  }
+
+- (void)dealloc
+  {
+  if(badgeColor != nil)
+	[badgeColor release];
+  if(labelColor != nil)
+    [labelColor release];
+  
+  [super dealloc];
+  }
+
++ (CTBadge *)systemBadge
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  return [newInstance autorelease];
+  }
+
++ (CTBadge *)badgeWithColor:(NSColor *)badgeColor labelColor:(NSColor *)labelColor;
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  [newInstance setBadgeColor:badgeColor];
+  [newInstance setLabelColor:labelColor];
+  
+  return [newInstance autorelease];
+  }
+#pragma mark -
+
+
+#pragma mark Appearance
+- (void)setBadgeColor:(NSColor *)theColor;
+  {
+  if(badgeColor != nil)
+	[badgeColor release];
+  
+  badgeColor = theColor;
+  [badgeColor retain];
+  }
+- (void)setLabelColor:(NSColor *)theColor;
+  {
+  if(labelColor != nil)
+	[labelColor release];
+  
+  labelColor = theColor;
+  [labelColor retain];
+  }
+
+- (NSColor *)badgeColor
+  {
+  return badgeColor;
+  }
+- (NSColor *)labelColor
+  {
+  return labelColor;
+  }
+#pragma mark -
+
+
+#pragma mark Drawing
+- (NSImage *)smallBadgeForValue:(unsigned)value		//does drawing in it's own special way
+  {
+  return [self badgeOfSize:CTSmallBadgeSize forValue:value];
+  }
+
+- (NSImage *)smallBadgeForString:(NSString *)string
+  {
+  return [self badgeOfSize:CTSmallBadgeSize forString:string];
+  }
+
+- (NSImage *)largeBadgeForValue:(unsigned)value
+  {
+  return [self badgeOfSize:CTLargeBadgeSize forValue:value];
+  }
+
+- (NSImage *)largeBadgeForString:(NSString *)string
+  {
+  return [self badgeOfSize:CTLargeBadgeSize forString:string];
+  }
+
+- (NSImage *)badgeOfSize:(float)size forValue:(unsigned)value
+  {
+  return [self badgeOfSize:(float)size forString:[NSString stringWithFormat:@"%u", value]];
+  }
+
+- (NSImage *)badgeOfSize:(float)size forString:(NSString *)string
+  {
+  float scaleFactor = 1;
+  
+  if(size <= 0)
+	[NSException raise:NSInvalidArgumentException format:@"%@ %@: size (%f) must be positive", [self class], NSStringFromSelector(_cmd), size];
+  else if(size <= CTSmallBadgeSize)
+	scaleFactor = size/CTSmallBadgeSize;
+  else
+	scaleFactor = size/CTLargeBadgeSize;
+  
+  //Label stuff  -----------------------------------------------
+  NSAttributedString *label;
+  NSSize labelSize;
+  
+  if(size <= CTSmallBadgeSize)
+	label = [self labelForString:string size:CTSmallLabelSize*scaleFactor];
+  else
+	label = [self labelForString:string size:CTLargeLabelSize*scaleFactor];
+  
+  labelSize = [label size];
+  
+  //Badge stuff  -----------------------------------------------
+  NSImage *badgeImage;	//this the image with the gradient fill
+  NSImage *badgeMask ;	//we nock out this mask from the gradient
+  
+  CTGradient *badgeGradient = [self badgeGradient];
+  
+  float shadowOpacity,
+		shadowOffset,
+        shadowBlurRadius;
+  
+  int angle;
+  
+  if(size <= CTSmallBadgeSize)
+	{
+	shadowOpacity    = .6;
+	shadowOffset     = floorf(1*scaleFactor);
+	shadowBlurRadius = ceilf(1*scaleFactor);
+	}
+  else
+	{
+	shadowOpacity    = .8;
+	shadowOffset     = ceilf(1*scaleFactor);
+	shadowBlurRadius = ceilf(2*scaleFactor);
+	}
+  
+  if ([label length] <= 3)	//Badges have different gradient angles
+	angle = -45;
+  else
+	angle = -30;
+  
+  badgeMask = [self badgeMaskOfSize:size length:[label length]];
+  
+  NSSize badgeSize = [badgeMask size];
+  NSPoint   origin = NSMakePoint(shadowBlurRadius, shadowBlurRadius+shadowOffset);
+  
+  badgeImage = [[NSImage alloc] initWithSize:NSMakeSize(badgeSize.width  + 2*shadowBlurRadius,											//sometimes it needs more
+														badgeSize.height + 2*shadowBlurRadius - shadowOffset + (size <= CTSmallBadgeSize))];	//space when small
+  
+  [badgeImage lockFocus];
+	[badgeGradient fillRect:NSMakeRect(origin.x, origin.y, floorf(badgeSize.width), floorf(badgeSize.height)) angle:angle];				//apply the gradient
+	[badgeMask compositeToPoint:origin operation: NSCompositeDestinationAtop];															//knock out the badge area
+	[label drawInRect:NSMakeRect(origin.x+floorf((badgeSize.width-labelSize.width)/2), origin.y+floorf((badgeSize.height-labelSize.height)/2), badgeSize.width, labelSize.height)];	//draw label in center
+  [badgeImage unlockFocus];
+  
+  
+  //Final stuff   -----------------------------------------------
+  NSImage *image = [[NSImage alloc] initWithSize:[badgeImage size]];
+  
+  [image lockFocus];
+	[NSGraphicsContext saveGraphicsState];
+	  NSShadow *theShadow = [[NSShadow alloc] init];
+	  [theShadow setShadowOffset: NSMakeSize(0,-shadowOffset)];
+	  [theShadow setShadowBlurRadius:shadowBlurRadius];
+	  [theShadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:shadowOpacity]];
+	  [theShadow set];
+	  [theShadow release];
+	  [badgeImage compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];
+	[NSGraphicsContext restoreGraphicsState];
+  [image unlockFocus];
+  
+  [label release];
+  [badgeImage release];
+  
+  return [image autorelease];
+  }
+
+
+- (NSImage *)badgeOverlayImageForString:(NSString *)string insetX:(float)dx y:(float)dy;
+  {
+  NSImage *badgeImage = [self largeBadgeForString:string];
+  NSImage *overlayImage = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+
+  //draw large icon in the upper right corner of the overlay image
+  [overlayImage lockFocus];
+  NSSize badgeSize = [badgeImage size];
+  [badgeImage compositeToPoint:NSMakePoint(128-dx-badgeSize.width,128-dy-badgeSize.height) operation:NSCompositeSourceOver];  
+  [overlayImage unlockFocus];
+
+  return [overlayImage autorelease];
+  }
+
+- (void)badgeApplicationDockIconWithString:(NSString *)string insetX:(float)dx y:(float)dy;
+  {
+  NSImage *appIcon      = [NSImage imageNamed:@"NSApplicationIcon"];
+  NSImage *badgeOverlay = [self badgeOverlayImageForString:string insetX:dx y:dy];
+  
+  //Put the appIcon underneath the badgeOverlay
+  [badgeOverlay lockFocus];
+	[appIcon compositeToPoint:NSZeroPoint operation:NSCompositeDestinationOver];
+  [badgeOverlay unlockFocus];
+  
+  [NSApp setApplicationIconImage:badgeOverlay];
+  }
+
+- (NSImage *)badgeOverlayImageForValue:(unsigned)value insetX:(float)dx y:(float)dy
+  {
+  return [self badgeOverlayImageForString:[NSString stringWithFormat:@"%u", value] insetX:dx y:dy];
+  }
+
+- (void)badgeApplicationDockIconWithValue:(unsigned)value insetX:(float)dx y:(float)dy
+  {
+  [self badgeApplicationDockIconWithString:[NSString stringWithFormat:@"%u", value] insetX:dx y:dy];
+  }
+#pragma mark -
+
+
+#pragma mark Misc.
+- (CTGradient *)badgeGradient
+  {
+  CTGradient *aGradient = [CTGradient gradientWithBeginningColor:[self badgeColor] endingColor:[[self badgeColor] shadowWithLevel:(1./3.)]];
+  
+  aGradient = [aGradient addColorStop:[self badgeColor] atPosition:(1./3.)];
+  
+  return aGradient;
+  }
+
+- (NSAttributedString *)labelForString:(NSString *)label size:(unsigned)size
+  {
+  //set Attributes to use on String  ---------------------------
+  NSFont *labelFont;
+  
+  if(size <= CTSmallLabelSize)
+	labelFont = [NSFont boldSystemFontOfSize:size];
+  else
+	labelFont = [NSFont fontWithName:@"Helvetica-Bold" size:size];
+  
+  NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];[pStyle setAlignment:NSCenterTextAlignment];
+  NSDictionary *attributes = [[NSDictionary alloc] initWithObjectsAndKeys:[self labelColor], NSForegroundColorAttributeName,
+																		  labelFont        , NSFontAttributeName           , nil];
+  [pStyle release];
+  
+  //Label stuff
+  if([label length] >= 6)
+    label = [NSString stringWithUTF8String:"\xe2\x88\x9e"];
+  
+  NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:label attributes:attributes];
+  [attributes release];
+  
+  return attributedString;
+  }
+
+- (NSImage *)badgeMaskOfSize:(float)size length:(unsigned)length;
+  {
+  NSImage *badgeMask;
+  
+  if(length <=2)
+	badgeMask = [NSImage imageNamed:@"CTBadge_1.pdf"];
+  else if(length <=3)
+	badgeMask = [NSImage imageNamed:@"CTBadge_3.pdf"];
+  else if(length <=4)
+	badgeMask = [NSImage imageNamed:@"CTBadge_4.pdf"];
+  else
+	badgeMask = [NSImage imageNamed:@"CTBadge_5.pdf"];
+  
+  if(size > 0 && size != [badgeMask size].height)
+	{
+	[badgeMask setName:nil];
+	[badgeMask setScalesWhenResized:YES];
+	[badgeMask setSize:NSMakeSize([badgeMask size].width*(size/[badgeMask size].height), size)];
+	}
+  
+  return badgeMask;
+  }
+
+@end
Index: releases/AntiRSI/1.4njr3/CTBadge/CTGradient.h
===================================================================
--- releases/AntiRSI/1.4njr3/CTBadge/CTGradient.h	(revision 349)
+++ releases/AntiRSI/1.4njr3/CTBadge/CTGradient.h	(revision 349)
@@ -0,0 +1,72 @@
+//
+//  CTGradient.h
+//
+//  Created by Chad Weider on 2/14/07.
+//  Copyright (c) 2007 Chad Weider.
+//  Some rights reserved: <http://creativecommons.org/licenses/by/2.5/>
+//
+//  Version: 1.6
+
+#import <Cocoa/Cocoa.h>
+
+typedef struct _CTGradientElement 
+	{
+	float red, green, blue, alpha;
+	float position;
+	
+	struct _CTGradientElement *nextElement;
+	} CTGradientElement;
+
+typedef enum  _CTBlendingMode
+	{
+	CTLinearBlendingMode,
+	CTChromaticBlendingMode,
+	CTInverseChromaticBlendingMode
+	} CTGradientBlendingMode;
+
+
+@interface CTGradient : NSObject <NSCopying, NSCoding>
+	{
+	CTGradientElement* elementList;
+	CTGradientBlendingMode blendingMode;
+	
+	CGFunctionRef gradientFunction;
+	}
+
++ (id)gradientWithBeginningColor:(NSColor *)begin endingColor:(NSColor *)end;
+
++ (id)aquaSelectedGradient;
++ (id)aquaNormalGradient;
++ (id)aquaPressedGradient;
+
++ (id)unifiedSelectedGradient;
++ (id)unifiedNormalGradient;
++ (id)unifiedPressedGradient;
++ (id)unifiedDarkGradient;
+
++ (id)sourceListSelectedGradient;
++ (id)sourceListUnselectedGradient;
+
++ (id)rainbowGradient;
++ (id)hydrogenSpectrumGradient;
+
+- (CTGradient *)gradientWithAlphaComponent:(float)alpha;
+
+- (CTGradient *)addColorStop:(NSColor *)color atPosition:(float)position;	//positions given relative to [0,1]
+- (CTGradient *)removeColorStopAtIndex:(unsigned)index;
+- (CTGradient *)removeColorStopAtPosition:(float)position;
+
+- (CTGradientBlendingMode)blendingMode;
+- (NSColor *)colorStopAtIndex:(unsigned)index;
+- (NSColor *)colorAtPosition:(float)position;
+
+
+- (void)drawSwatchInRect:(NSRect)rect;
+- (void)fillRect:(NSRect)rect angle:(float)angle;					//fills rect with axial gradient
+																	//	angle in degrees
+- (void)radialFillRect:(NSRect)rect;								//fills rect with radial gradient
+																	//  gradient from center outwards
+- (void)fillBezierPath:(NSBezierPath *)path angle:(float)angle;
+- (void)radialFillBezierPath:(NSBezierPath *)path;
+
+@end
Index: releases/AntiRSI/1.4njr3/CTBadge/CTGradient.m
===================================================================
--- releases/AntiRSI/1.4njr3/CTBadge/CTGradient.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/CTBadge/CTGradient.m	(revision 349)
@@ -0,0 +1,1253 @@
+//
+//  CTGradient.m
+//
+//  Created by Chad Weider on 2/14/07.
+//  Copyright (c) 2007 Chad Weider.
+//  Some rights reserved: <http://creativecommons.org/licenses/by/2.5/>
+//
+//  Version: 1.6
+
+#import "CTGradient.h"
+
+@interface CTGradient (Private)
+- (void)_commonInit;
+- (void)setBlendingMode:(CTGradientBlendingMode)mode;
+- (void)addElement:(CTGradientElement*)newElement;
+
+- (CTGradientElement *)elementAtIndex:(unsigned)index;
+
+- (CTGradientElement)removeElementAtIndex:(unsigned)index;
+- (CTGradientElement)removeElementAtPosition:(float)position;
+@end
+
+//C Fuctions for color blending
+static void linearEvaluation   (void *info, const float *in, float *out);
+static void chromaticEvaluation(void *info, const float *in, float *out);
+static void inverseChromaticEvaluation(void *info, const float *in, float *out);
+static void transformRGB_HSV(float *components);
+static void transformHSV_RGB(float *components);
+static void resolveHSV(float *color1, float *color2);
+
+
+@implementation CTGradient
+/////////////////////////////////////Initialization Type Stuff
+- (id)init
+  {
+  self = [super init];
+  
+  if (self != nil)
+	{
+	[self _commonInit];
+	[self setBlendingMode:CTLinearBlendingMode];
+	}
+  return self;
+  }
+
+- (void)_commonInit
+  {
+  elementList = nil;
+  }
+
+- (void)dealloc
+  {
+  CGFunctionRelease(gradientFunction);
+  
+  CTGradientElement *elementToRemove = elementList;
+  while(elementList != nil)
+	{
+	elementToRemove = elementList;
+	elementList = elementList->nextElement;
+	free(elementToRemove);
+	}
+  
+  [super dealloc];
+  }
+
+- (id)copyWithZone:(NSZone *)zone
+  {
+  CTGradient *copy = [[[self class] allocWithZone:zone] init];
+  
+  //now just copy my elementlist
+  CTGradientElement *currentElement = elementList;
+  while(currentElement != nil)
+	{
+	[copy addElement:currentElement];
+	currentElement = currentElement->nextElement;
+	}
+  
+  [copy setBlendingMode:blendingMode];
+  
+  return copy;
+  }
+
+- (void)encodeWithCoder:(NSCoder *)coder
+  {
+  if([coder allowsKeyedCoding])
+	{
+	unsigned count = 0;
+	CTGradientElement *currentElement = elementList;
+	while(currentElement != nil)
+		{
+		[coder encodeValueOfObjCType:@encode(float) at:&(currentElement->red)];
+		[coder encodeValueOfObjCType:@encode(float) at:&(currentElement->green)];
+		[coder encodeValueOfObjCType:@encode(float) at:&(currentElement->blue)];
+		[coder encodeValueOfObjCType:@encode(float) at:&(currentElement->alpha)];
+		[coder encodeValueOfObjCType:@encode(float) at:&(currentElement->position)];
+		
+		count++;
+		currentElement = currentElement->nextElement;
+		}
+	[coder encodeInt:count forKey:@"CTGradientElementCount"];
+	[coder encodeInt:blendingMode forKey:@"CTGradientBlendingMode"];
+	}
+  else
+	[NSException raise:NSInvalidArchiveOperationException format:@"Only supports NSKeyedArchiver coders"];
+  }
+
+- (id)initWithCoder:(NSCoder *)coder
+  {
+  [self _commonInit];
+  
+  [self setBlendingMode:[coder decodeIntForKey:@"CTGradientBlendingMode"]];
+  unsigned count = [coder decodeIntForKey:@"CTGradientElementCount"];
+  
+  while(count != 0)
+	{
+    CTGradientElement newElement;
+	
+	[coder decodeValueOfObjCType:@encode(float) at:&(newElement.red)];
+	[coder decodeValueOfObjCType:@encode(float) at:&(newElement.green)];
+	[coder decodeValueOfObjCType:@encode(float) at:&(newElement.blue)];
+	[coder decodeValueOfObjCType:@encode(float) at:&(newElement.alpha)];
+	[coder decodeValueOfObjCType:@encode(float) at:&(newElement.position)];
+	
+	count--;
+	[self addElement:&newElement];
+	}
+  return self;
+  }
+#pragma mark -
+
+
+
+#pragma mark Creation
++ (id)gradientWithBeginningColor:(NSColor *)begin endingColor:(NSColor *)end
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  CTGradientElement color2;
+  
+  [[begin colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&color1.red
+															   green:&color1.green
+																blue:&color1.blue
+															   alpha:&color1.alpha];
+  
+  [[end   colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&color2.red
+															   green:&color2.green
+																blue:&color2.blue
+															   alpha:&color2.alpha];  
+  color1.position = 0;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)aquaSelectedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red   = 0.58;
+  color1.green = 0.86;
+  color1.blue  = 0.98;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red   = 0.42;
+  color2.green = 0.68;
+  color2.blue  = 0.90;
+  color2.alpha = 1.00;
+  color2.position = 11.5/23;
+  
+  CTGradientElement color3;
+  color3.red   = 0.64;
+  color3.green = 0.80;
+  color3.blue  = 0.94;
+  color3.alpha = 1.00;
+  color3.position = 11.5/23;
+  
+  CTGradientElement color4;
+  color4.red   = 0.56;
+  color4.green = 0.70;
+  color4.blue  = 0.90;
+  color4.alpha = 1.00;
+  color4.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  [newInstance addElement:&color3];
+  [newInstance addElement:&color4];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)aquaNormalGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.95;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.83;
+  color2.alpha = 1.00;
+  color2.position = 11.5/23;
+  
+  CTGradientElement color3;
+  color3.red = color3.green = color3.blue  = 0.95;
+  color3.alpha = 1.00;
+  color3.position = 11.5/23;
+  
+  CTGradientElement color4;
+  color4.red = color4.green = color4.blue  = 0.92;
+  color4.alpha = 1.00;
+  color4.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  [newInstance addElement:&color3];
+  [newInstance addElement:&color4];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)aquaPressedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.80;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.64;
+  color2.alpha = 1.00;
+  color2.position = 11.5/23;
+  
+  CTGradientElement color3;
+  color3.red = color3.green = color3.blue  = 0.80;
+  color3.alpha = 1.00;
+  color3.position = 11.5/23;
+  
+  CTGradientElement color4;
+  color4.red = color4.green = color4.blue  = 0.77;
+  color4.alpha = 1.00;
+  color4.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  [newInstance addElement:&color3];
+  [newInstance addElement:&color4];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)unifiedSelectedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.85;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.95;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)unifiedNormalGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.75;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.90;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)unifiedPressedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.60;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.75;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)unifiedDarkGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red = color1.green = color1.blue  = 0.68;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red = color2.green = color2.blue  = 0.83;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)sourceListSelectedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red   = 0.06;
+  color1.green = 0.37;
+  color1.blue  = 0.85;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red   = 0.30;
+  color2.green = 0.60;
+  color2.blue  = 0.92;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)sourceListUnselectedGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red   = 0.43;
+  color1.green = 0.43;
+  color1.blue  = 0.43;
+  color1.alpha = 1.00;
+  color1.position = 0;
+  
+  CTGradientElement color2;
+  color2.red   = 0.60;
+  color2.green = 0.60;
+  color2.blue  = 0.60;
+  color2.alpha = 1.00;
+  color2.position = 1;
+  
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)rainbowGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement color1;
+  color1.red   = 1.00;
+  color1.green = 0.00;
+  color1.blue  = 0.00;
+  color1.alpha = 1.00;
+  color1.position = 0.0;
+  
+  CTGradientElement color2;
+  color2.red   = 0.54;
+  color2.green = 0.00;
+  color2.blue  = 1.00;
+  color2.alpha = 1.00;
+  color2.position = 1.0;
+    
+  [newInstance addElement:&color1];
+  [newInstance addElement:&color2];
+  
+  [newInstance setBlendingMode:CTChromaticBlendingMode];
+  
+  return [newInstance autorelease];
+  }
+
++ (id)hydrogenSpectrumGradient
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  struct {float hue; float position; float width;} colorBands[4];
+  
+  colorBands[0].hue = 22;
+  colorBands[0].position = .145;
+  colorBands[0].width = .01;
+  
+  colorBands[1].hue = 200;
+  colorBands[1].position = .71;
+  colorBands[1].width = .008;
+  
+  colorBands[2].hue = 253;
+  colorBands[2].position = .885;
+  colorBands[2].width = .005;
+  
+  colorBands[3].hue = 275;
+  colorBands[3].position = .965;
+  colorBands[3].width = .003;
+  
+  int i;
+  /////////////////////////////
+  for(i = 0; i < 4; i++)
+	{	
+	float color[4];
+	color[0] = colorBands[i].hue - 180*colorBands[i].width;
+	color[1] = 1;
+	color[2] = 0.001;
+	color[3] = 1;
+	transformHSV_RGB(color);
+	CTGradientElement fadeIn;
+	fadeIn.red   = color[0];
+	fadeIn.green = color[1];
+	fadeIn.blue  = color[2];
+	fadeIn.alpha = color[3];
+	fadeIn.position = colorBands[i].position - colorBands[i].width;
+	
+	
+	color[0] = colorBands[i].hue;
+	color[1] = 1;
+	color[2] = 1;
+	color[3] = 1;
+	transformHSV_RGB(color);
+	CTGradientElement band;
+	band.red   = color[0];
+	band.green = color[1];
+	band.blue  = color[2];
+	band.alpha = color[3];
+	band.position = colorBands[i].position;
+	
+	color[0] = colorBands[i].hue + 180*colorBands[i].width;
+	color[1] = 1;
+	color[2] = 0.001;
+	color[3] = 1;
+	transformHSV_RGB(color);
+	CTGradientElement fadeOut;
+	fadeOut.red   = color[0];
+	fadeOut.green = color[1];
+	fadeOut.blue  = color[2];
+	fadeOut.alpha = color[3];
+	fadeOut.position = colorBands[i].position + colorBands[i].width;
+	
+	
+	[newInstance addElement:&fadeIn];
+	[newInstance addElement:&band];
+	[newInstance addElement:&fadeOut];
+	}
+  
+  [newInstance setBlendingMode:CTChromaticBlendingMode];
+  
+  return [newInstance autorelease];
+  }
+
+#pragma mark -
+
+
+
+#pragma mark Modification
+- (CTGradient *)gradientWithAlphaComponent:(float)alpha
+  {
+  id newInstance = [[[self class] alloc] init];
+  
+  CTGradientElement *curElement = elementList;
+  CTGradientElement tempElement;
+
+  while(curElement != nil)
+	{
+	tempElement = *curElement;
+	tempElement.alpha = alpha;
+	[newInstance addElement:&tempElement];
+	
+	curElement = curElement->nextElement;
+	}
+  
+  return [newInstance autorelease];
+  }
+
+- (CTGradient *)gradientWithBlendingMode:(CTGradientBlendingMode)mode
+  {
+  CTGradient *newGradient = [self copy];  
+  
+  [newGradient setBlendingMode:mode];
+  
+  return [newGradient autorelease];
+  }
+
+
+//Adds a color stop with <color> at <position> in elementList
+//(if two elements are at the same position then added imediatly after the one that was there already)
+- (CTGradient *)addColorStop:(NSColor *)color atPosition:(float)position
+  {
+  CTGradient *newGradient = [self copy];
+  CTGradientElement newGradientElement;
+  
+  //put the components of color into the newGradientElement - must make sure it is a RGB color (not Gray or CMYK) 
+  [[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&newGradientElement.red
+															   green:&newGradientElement.green
+																blue:&newGradientElement.blue
+															   alpha:&newGradientElement.alpha];
+  newGradientElement.position = position;
+  
+  //Pass it off to addElement to take care of adding it to the elementList
+  [newGradient addElement:&newGradientElement];
+  
+  return [newGradient autorelease];
+  }
+
+
+//Removes the color stop at <position> from elementList
+- (CTGradient *)removeColorStopAtPosition:(float)position
+  {
+  CTGradient *newGradient = [self copy];
+  CTGradientElement removedElement = [newGradient removeElementAtPosition:position];
+  
+  if(isnan(removedElement.position))
+	[NSException raise:NSRangeException format:@"-[%@ removeColorStopAtPosition:]: no such colorStop at position (%f)", [self class], position];
+  
+  return [newGradient autorelease];
+  }
+
+- (CTGradient *)removeColorStopAtIndex:(unsigned)index
+  {
+  CTGradient *newGradient = [self copy];
+  CTGradientElement removedElement = [newGradient removeElementAtIndex:index];
+  
+  if(isnan(removedElement.position))
+	[NSException raise:NSRangeException format:@"-[%@ removeColorStopAtIndex:]: index (%i) beyond bounds", [self class], index];
+  
+  return [newGradient autorelease];
+  }
+#pragma mark -
+
+
+
+#pragma mark Information
+- (CTGradientBlendingMode)blendingMode
+  {
+  return blendingMode;
+  }
+
+//Returns color at <position> in gradient
+- (NSColor *)colorStopAtIndex:(unsigned)index
+  {
+  CTGradientElement *element = [self elementAtIndex:index];
+  
+  if(element != nil)
+	return [NSColor colorWithCalibratedRed:element->red 
+									 green:element->green
+									  blue:element->blue
+									 alpha:element->alpha];
+  
+  [NSException raise:NSRangeException format:@"-[%@ removeColorStopAtIndex:]: index (%i) beyond bounds", [self class], index];
+  
+  return nil;
+  }
+
+- (NSColor *)colorAtPosition:(float)position
+  {
+  float components[4];
+  
+  switch(blendingMode)
+	{
+	case CTLinearBlendingMode:
+		 linearEvaluation(&elementList, &position, components);				break;
+	case CTChromaticBlendingMode:
+		 chromaticEvaluation(&elementList, &position, components);			break;
+	case CTInverseChromaticBlendingMode:
+		 inverseChromaticEvaluation(&elementList, &position, components);	break;
+	}
+  
+  
+  return [NSColor colorWithCalibratedRed:components[0]
+								   green:components[1]
+								    blue:components[2]
+								   alpha:components[3]];
+  }
+#pragma mark -
+
+
+
+#pragma mark Drawing
+- (void)drawSwatchInRect:(NSRect)rect
+  {
+  [self fillRect:rect angle:45];
+  }
+
+- (void)fillRect:(NSRect)rect angle:(float)angle
+  {
+  //First Calculate where the beginning and ending points should be
+  CGPoint startPoint;
+  CGPoint endPoint;
+  
+  if(angle == 0)		//screw the calculations - we know the answer
+  	{
+  	startPoint = CGPointMake(NSMinX(rect), NSMinY(rect));	//right of rect
+  	endPoint   = CGPointMake(NSMaxX(rect), NSMinY(rect));	//left  of rect
+  	}
+  else if(angle == 90)	//same as above
+  	{
+  	startPoint = CGPointMake(NSMinX(rect), NSMinY(rect));	//bottom of rect
+  	endPoint   = CGPointMake(NSMinX(rect), NSMaxY(rect));	//top    of rect
+  	}
+  else						//ok, we'll do the calculations now 
+  	{
+  	float x,y;
+  	float sina, cosa, tana;
+  	
+  	float length;
+  	float deltax,
+  		  deltay;
+	
+  	float rangle = angle * pi/180;	//convert the angle to radians
+	
+  	if(fabsf(tan(rangle))<=1)	//for range [-45,45], [135,225]
+		{
+		x = NSWidth(rect);
+		y = NSHeight(rect);
+		
+		sina = sin(rangle);
+		cosa = cos(rangle);
+		tana = tan(rangle);
+		
+		length = x/fabsf(cosa)+(y-x*fabsf(tana))*fabsf(sina);
+		
+		deltax = length*cosa/2;
+		deltay = length*sina/2;
+		}
+	else						//for range [45,135], [225,315]
+		{
+		x = NSHeight(rect);
+		y = NSWidth(rect);
+		
+		sina = sin(rangle - 90*pi/180);
+		cosa = cos(rangle - 90*pi/180);
+		tana = tan(rangle - 90*pi/180);
+		
+		length = x/fabsf(cosa)+(y-x*fabsf(tana))*fabsf(sina);
+		
+		deltax =-length*sina/2;
+		deltay = length*cosa/2;
+		}
+  
+	startPoint = CGPointMake(NSMidX(rect)-deltax, NSMidY(rect)-deltay);
+	endPoint   = CGPointMake(NSMidX(rect)+deltax, NSMidY(rect)+deltay);
+	}
+  
+  //Calls to CoreGraphics
+  CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+  CGContextSaveGState(currentContext);
+	  #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+		CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+	  #else
+		CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+	  #endif
+	  CGShadingRef myCGShading = CGShadingCreateAxial(colorspace, startPoint, endPoint, gradientFunction, false, false);
+	  
+	  CGContextClipToRect (currentContext, *(CGRect *)&rect);	//This is where the action happens
+	  CGContextDrawShading(currentContext, myCGShading);
+	  
+	  CGShadingRelease(myCGShading);
+	  CGColorSpaceRelease(colorspace );
+  CGContextRestoreGState(currentContext);
+  }
+
+- (void)radialFillRect:(NSRect)rect
+  {
+  CGPoint startPoint , endPoint;
+  float startRadius, endRadius;
+  float scalex, scaley, transx, transy;
+  
+  startPoint = endPoint = CGPointMake(NSMidX(rect), NSMidY(rect));
+  
+  startRadius = -1;
+  if(NSHeight(rect)>NSWidth(rect))
+	{
+	scalex = NSWidth(rect)/NSHeight(rect);
+	transx = (NSHeight(rect)-NSWidth(rect))/2;
+	scaley = 1;
+	transy = 1;
+	endRadius = NSHeight(rect)/2;
+	}
+  else
+	{
+	scalex = 1;
+	transx = 1;
+	scaley = NSHeight(rect)/NSWidth(rect);
+	transy = (NSWidth(rect)-NSHeight(rect))/2;
+	endRadius = NSWidth(rect)/2;
+	}
+  
+  //Calls to CoreGraphics
+  CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+  CGContextSaveGState(currentContext);
+	  #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+		CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+	  #else
+		CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+	  #endif
+  	  CGShadingRef myCGShading = CGShadingCreateRadial(colorspace, startPoint, startRadius, endPoint, endRadius, gradientFunction, true, true);
+
+	  CGContextClipToRect  (currentContext, *(CGRect *)&rect);
+	  CGContextScaleCTM    (currentContext, scalex, scaley);
+	  CGContextTranslateCTM(currentContext, transx, transy);
+	  CGContextDrawShading (currentContext, myCGShading);		//This is where the action happens
+	  
+	  CGShadingRelease(myCGShading);
+	  CGColorSpaceRelease(colorspace);
+  CGContextRestoreGState(currentContext);
+  }
+
+- (void)fillBezierPath:(NSBezierPath *)path angle:(float)angle
+  {
+  NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+  [currentContext saveGraphicsState];
+	NSAffineTransform *transform = [[NSAffineTransform alloc] init];
+	
+	[transform rotateByDegrees:-angle];
+	[path transformUsingAffineTransform:transform];
+	[transform invert];
+	[transform concat];
+	
+	[path addClip];
+	[self fillRect:[path bounds] angle:0];
+	[path transformUsingAffineTransform:transform];
+	[transform release];
+  [currentContext restoreGraphicsState];
+  }
+- (void)radialFillBezierPath:(NSBezierPath *)path
+  {
+  NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+  [currentContext saveGraphicsState];
+	[path addClip];
+	[self radialFillRect:[path bounds]];
+  [currentContext restoreGraphicsState];
+  }
+#pragma mark -
+
+
+
+#pragma mark Private Methods
+- (void)setBlendingMode:(CTGradientBlendingMode)mode;
+  {
+  blendingMode = mode;
+  
+  //Choose what blending function to use
+  void *evaluationFunction;
+  switch(blendingMode)
+	{
+	case CTLinearBlendingMode:
+		 evaluationFunction = &linearEvaluation;			break;
+	case CTChromaticBlendingMode:
+		 evaluationFunction = &chromaticEvaluation;			break;
+	case CTInverseChromaticBlendingMode:
+		 evaluationFunction = &inverseChromaticEvaluation;	break;
+	}
+  
+  //replace the current CoreGraphics Function with new one
+  if(gradientFunction != NULL)
+	  CGFunctionRelease(gradientFunction);
+    
+  CGFunctionCallbacks evaluationCallbackInfo = {0 , evaluationFunction, NULL};	//Version, evaluator function, cleanup function
+  
+  static const float input_value_range   [2] = { 0, 1 };						//range  for the evaluator input
+  static const float output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };		//ranges for the evaluator output (4 returned values)
+  
+  gradientFunction = CGFunctionCreate(&elementList,					//the two transition colors
+									  1, input_value_range  ,		//number of inputs (just fraction of progression)
+									  4, output_value_ranges,		//number of outputs (4 - RGBa)
+									  &evaluationCallbackInfo);		//info for using the evaluator function
+  }
+
+- (void)addElement:(CTGradientElement *)newElement
+{
+  if(elementList == nil || newElement->position < elementList->position)	//inserting at beginning of list
+	{
+	CTGradientElement *tmpNext = elementList;
+	elementList = malloc(sizeof(CTGradientElement));
+	*elementList = *newElement;
+	elementList->nextElement = tmpNext;
+	}
+  else																		//inserting somewhere inside list
+	{
+	CTGradientElement *curElement = elementList;
+	
+	while(curElement->nextElement != nil && !((curElement->position <= newElement->position) && (newElement->position < curElement->nextElement->position)))
+		{
+		curElement = curElement->nextElement;
+		}
+	
+	CTGradientElement *tmpNext = curElement->nextElement;
+	curElement->nextElement = malloc(sizeof(CTGradientElement));
+	*(curElement->nextElement) = *newElement;
+	curElement->nextElement->nextElement = tmpNext;
+	}
+  }
+
+- (CTGradientElement)removeElementAtIndex:(unsigned)index
+  {
+  CTGradientElement removedElement;
+  
+  if(elementList != nil)
+	{
+	if(index == 0)
+		{
+		CTGradientElement *tmpNext = elementList;
+		elementList = elementList->nextElement;
+		
+		removedElement = *tmpNext;
+		free(tmpNext);
+		
+		return removedElement;
+		}
+	
+	unsigned count = 1;		//we want to start one ahead
+	CTGradientElement *currentElement = elementList;
+	while(currentElement->nextElement != nil)
+		{
+		if(count == index)
+			{
+			CTGradientElement *tmpNext  = currentElement->nextElement;
+			currentElement->nextElement = currentElement->nextElement->nextElement;
+			
+			removedElement = *tmpNext;
+			free(tmpNext);
+
+			return removedElement;
+			}
+
+		count++;
+		currentElement = currentElement->nextElement;
+		}
+	}
+  
+  //element is not found, return empty element
+  removedElement.red   = 0.0;
+  removedElement.green = 0.0;
+  removedElement.blue  = 0.0;
+  removedElement.alpha = 0.0;
+  removedElement.position = NAN;
+  removedElement.nextElement = nil;
+  
+  return removedElement;
+  }
+
+- (CTGradientElement)removeElementAtPosition:(float)position
+  {
+  CTGradientElement removedElement;
+  
+  if(elementList != nil)
+	{
+	if(elementList->position == position)
+		{
+		CTGradientElement *tmpNext = elementList;
+		elementList = elementList->nextElement;
+		
+		removedElement = *tmpNext;
+		free(tmpNext);
+		
+		return removedElement;
+		}
+	else
+		{
+		CTGradientElement *curElement = elementList;
+		while(curElement->nextElement != nil)
+			{
+			if(curElement->nextElement->position == position)
+				{
+				CTGradientElement *tmpNext = curElement->nextElement;
+				curElement->nextElement = curElement->nextElement->nextElement;
+				
+				removedElement = *tmpNext;
+				free(tmpNext);
+
+				return removedElement;
+				}
+			}
+		}
+	}
+  
+  //element is not found, return empty element
+  removedElement.red   = 0.0;
+  removedElement.green = 0.0;
+  removedElement.blue  = 0.0;
+  removedElement.alpha = 0.0;
+  removedElement.position = NAN;
+  removedElement.nextElement = nil;
+  
+  return removedElement;
+  }
+
+
+- (CTGradientElement *)elementAtIndex:(unsigned)index;			
+  {
+  unsigned count = 0;
+  CTGradientElement *currentElement = elementList;
+  
+  while(currentElement != nil)
+	{
+	if(count == index)
+		return currentElement;
+	
+	count++;
+	currentElement = currentElement->nextElement;
+	}
+  
+  return nil;
+  }
+#pragma mark -
+
+
+
+#pragma mark Core Graphics
+//////////////////////////////////////Blending Functions/////////////////////////////////////
+void linearEvaluation (void *info, const float *in, float *out)
+  {
+  float position = *in;
+  
+  if(*(CTGradientElement **)info == nil)	//if elementList is empty return clear color
+	{
+	out[0] = out[1] = out[2] = out[3] = 1;
+	return;
+	}
+  
+  //This grabs the first two colors in the sequence
+  CTGradientElement *color1 = *(CTGradientElement **)info;
+  CTGradientElement *color2 = color1->nextElement;
+  
+  //make sure first color and second color are on other sides of position
+  while(color2 != nil && color2->position < position)
+  	{
+  	color1 = color2;
+  	color2 = color1->nextElement;
+  	}
+  //if we don't have another color then make next color the same color
+  if(color2 == nil)
+    {
+	color2 = color1;
+    }
+  
+  //----------FailSafe settings----------
+  //color1->red   = 1; color2->red   = 0;
+  //color1->green = 1; color2->green = 0;
+  //color1->blue  = 1; color2->blue  = 0;
+  //color1->alpha = 1; color2->alpha = 1;
+  //color1->position = .5;
+  //color2->position = .5;
+  //-------------------------------------
+  
+  if(position <= color1->position)			//Make all below color color1's position equal to color1
+  	{
+  	out[0] = color1->red; 
+  	out[1] = color1->green;
+  	out[2] = color1->blue;
+  	out[3] = color1->alpha;
+  	}
+  else if (position >= color2->position)	//Make all above color color2's position equal to color2
+  	{
+  	out[0] = color2->red; 
+  	out[1] = color2->green;
+  	out[2] = color2->blue;
+  	out[3] = color2->alpha;
+  	}
+  else										//Interpolate color at postions between color1 and color1
+  	{
+  	//adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position 
+	position = (position-color1->position)/(color2->position - color1->position);
+	
+	out[0] = (color2->red   - color1->red  )*position + color1->red; 
+  	out[1] = (color2->green - color1->green)*position + color1->green;
+  	out[2] = (color2->blue  - color1->blue )*position + color1->blue;
+  	out[3] = (color2->alpha - color1->alpha)*position + color1->alpha;
+  	}
+  }
+
+
+
+
+//Chromatic Evaluation - 
+//	This blends colors by their Hue, Saturation, and Value(Brightness) right now I just 
+//	transform the RGB values stored in the CTGradientElements to HSB, in the future I may
+//	streamline it to avoid transforming in and out of HSB colorspace *for later*
+//
+//	For the chromatic blend we shift the hue of color1 to meet the hue of color2. To do
+//	this we will add to the hue's angle (if we subtract we'll be doing the inverse
+//	chromatic...scroll down more for that). All we need to do is keep adding to the hue
+//  until we wrap around the colorwheel and get to color2.
+void chromaticEvaluation(void *info, const float *in, float *out)
+  {
+  float position = *in;
+  
+  if(*(CTGradientElement **)info == nil)	//if elementList is empty return clear color
+	{
+	out[0] = out[1] = out[2] = out[3] = 1;
+	return;
+	}
+  
+  //This grabs the first two colors in the sequence
+  CTGradientElement *color1 = *(CTGradientElement **)info;
+  CTGradientElement *color2 = color1->nextElement;
+  
+  float c1[4];
+  float c2[4];
+    
+  //make sure first color and second color are on other sides of position
+  while(color2 != nil && color2->position < position)
+  	{
+  	color1 = color2;
+  	color2 = color1->nextElement;
+  	}
+  //if we don't have another color then make next color the same color
+  if(color2 == nil)
+    {
+	color2 = color1;
+    }
+  
+  
+  c1[0] = color1->red; 
+  c1[1] = color1->green;
+  c1[2] = color1->blue;
+  c1[3] = color1->alpha;
+  
+  c2[0] = color2->red; 
+  c2[1] = color2->green;
+  c2[2] = color2->blue;
+  c2[3] = color2->alpha;
+  
+  transformRGB_HSV(c1);
+  transformRGB_HSV(c2);
+  resolveHSV(c1,c2);
+  
+  if(c1[0] > c2[0]) //if color1's hue is higher than color2's hue then 
+	 c2[0] += 360;	//	we need to move c2 one revolution around the wheel
+  
+  
+  if(position <= color1->position)			//Make all below color color1's position equal to color1
+  	{
+  	out[0] = c1[0]; 
+  	out[1] = c1[1];
+  	out[2] = c1[2];
+  	out[3] = c1[3];
+  	}
+  else if (position >= color2->position)	//Make all above color color2's position equal to color2
+  	{
+  	out[0] = c2[0]; 
+  	out[1] = c2[1];
+  	out[2] = c2[2];
+  	out[3] = c2[3];
+  	}
+  else										//Interpolate color at postions between color1 and color1
+  	{
+  	//adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position 
+	position = (position-color1->position)/(color2->position - color1->position);
+	
+	out[0] = (c2[0] - c1[0])*position + c1[0]; 
+  	out[1] = (c2[1] - c1[1])*position + c1[1];
+  	out[2] = (c2[2] - c1[2])*position + c1[2];
+  	out[3] = (c2[3] - c1[3])*position + c1[3];
+  	}
+    
+  transformHSV_RGB(out);
+  }
+
+
+
+//Inverse Chromatic Evaluation - 
+//	Inverse Chromatic is about the same story as Chromatic Blend, but here the Hue
+//	is strictly decreasing, that is we need to get from color1 to color2 by decreasing
+//	the 'angle' (i.e. 90¼ -> 180¼ would be done by subtracting 270¼ and getting -180¼...
+//	which is equivalent to 180¼ mod 360¼
+void inverseChromaticEvaluation(void *info, const float *in, float *out)
+  {
+    float position = *in;
+  
+  if(*(CTGradientElement **)info == nil)	//if elementList is empty return clear color
+	{
+	out[0] = out[1] = out[2] = out[3] = 1;
+	return;
+	}
+  
+  //This grabs the first two colors in the sequence
+  CTGradientElement *color1 = *(CTGradientElement **)info;
+  CTGradientElement *color2 = color1->nextElement;
+  
+  float c1[4];
+  float c2[4];
+      
+  //make sure first color and second color are on other sides of position
+  while(color2 != nil && color2->position < position)
+  	{
+  	color1 = color2;
+  	color2 = color1->nextElement;
+  	}
+  //if we don't have another color then make next color the same color
+  if(color2 == nil)
+    {
+	color2 = color1;
+    }
+
+  c1[0] = color1->red; 
+  c1[1] = color1->green;
+  c1[2] = color1->blue;
+  c1[3] = color1->alpha;
+  
+  c2[0] = color2->red; 
+  c2[1] = color2->green;
+  c2[2] = color2->blue;
+  c2[3] = color2->alpha;
+
+  transformRGB_HSV(c1);
+  transformRGB_HSV(c2);
+  resolveHSV(c1,c2);
+
+  if(c1[0] < c2[0]) //if color1's hue is higher than color2's hue then 
+	 c1[0] += 360;	//	we need to move c2 one revolution back on the wheel
+
+  
+  if(position <= color1->position)			//Make all below color color1's position equal to color1
+  	{
+  	out[0] = c1[0]; 
+  	out[1] = c1[1];
+  	out[2] = c1[2];
+  	out[3] = c1[3];
+  	}
+  else if (position >= color2->position)	//Make all above color color2's position equal to color2
+  	{
+  	out[0] = c2[0]; 
+  	out[1] = c2[1];
+  	out[2] = c2[2];
+  	out[3] = c2[3];
+  	}
+  else										//Interpolate color at postions between color1 and color1
+  	{
+  	//adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position 
+	position = (position-color1->position)/(color2->position - color1->position);
+	
+	out[0] = (c2[0] - c1[0])*position + c1[0]; 
+  	out[1] = (c2[1] - c1[1])*position + c1[1];
+  	out[2] = (c2[2] - c1[2])*position + c1[2];
+  	out[3] = (c2[3] - c1[3])*position + c1[3];
+  	}
+    
+  transformHSV_RGB(out);
+  }
+
+
+
+void transformRGB_HSV(float *components) //H,S,B -> R,G,B
+	{
+	float H, S, V;
+	float R = components[0],
+		  G = components[1],
+		  B = components[2];
+	
+	float MAX = R > G ? (R > B ? R : B) : (G > B ? G : B),
+	      MIN = R < G ? (R < B ? R : B) : (G < B ? G : B);
+	
+	if(MAX == MIN)
+		H = NAN;
+	else if(MAX == R)
+		if(G >= B)
+			H = 60*(G-B)/(MAX-MIN)+0;
+		else
+			H = 60*(G-B)/(MAX-MIN)+360;
+	else if(MAX == G)
+		H = 60*(B-R)/(MAX-MIN)+120;
+	else if(MAX == B)
+		H = 60*(R-G)/(MAX-MIN)+240;
+	
+	S = MAX == 0 ? 0 : 1 - MIN/MAX;
+	V = MAX;
+	
+	components[0] = H;
+	components[1] = S;
+	components[2] = V;
+	}
+
+void transformHSV_RGB(float *components) //H,S,B -> R,G,B
+	{
+	float R, G, B;
+	float H = fmodf(components[0],359),	//map to [0,360)
+		  S = components[1],
+		  V = components[2];
+	
+	int   Hi = (int)floorf(H/60.) % 6;
+	float f  = H/60-Hi,
+		  p  = V*(1-S),
+		  q  = V*(1-f*S),
+		  t  = V*(1-(1-f)*S);
+	
+	switch (Hi)
+		{
+		case 0:	R=V;G=t;B=p;	break;
+		case 1:	R=q;G=V;B=p;	break;
+		case 2:	R=p;G=V;B=t;	break;
+		case 3:	R=p;G=q;B=V;	break;
+		case 4:	R=t;G=p;B=V;	break;
+		case 5:	R=V;G=p;B=q;	break;
+		}
+	
+	components[0] = R;
+	components[1] = G;
+	components[2] = B;
+	}
+
+void resolveHSV(float *color1, float *color2)	//H value may be undefined (i.e. graycale color)
+	{											//	we want to fill it with a sensible value
+	if(isnan(color1[0]) && isnan(color2[0]))
+		color1[0] = color2[0] = 0;
+	else if(isnan(color1[0]))
+		color1[0] = color2[0];
+	else if(isnan(color2[0]))
+		color2[0] = color1[0];
+	}
+
+@end
Index: releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/classes.nib	(revision 349)
+++ releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/classes.nib	(revision 349)
@@ -0,0 +1,39 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {
+                breakNow = id; 
+                checkForUpdate = id; 
+                gotoWebsite = id; 
+                postpone = id; 
+                resetSession = id; 
+            }; 
+            CLASS = AntiRSI; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                "dock_menu" = NSMenu; 
+                "next_break" = NSTextField; 
+                postpone = NSButton; 
+                progress = NSLevelIndicator; 
+                "reset_session_time" = NSDatePicker; 
+                "session_time" = NSTextField; 
+                "session_time_item" = NSMenuItem; 
+                status = NSTextField; 
+                time = NSTextField; 
+                version = NSTextField; 
+                view = AntiRSIView; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {
+            CLASS = AntiRSILevelIndicator; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSLevelIndicator; 
+        }, 
+        {CLASS = AntiRSIView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {CLASS = NSDatePicker; LANGUAGE = ObjC; SUPERCLASS = NSControl; }, 
+        {CLASS = NSLevelIndicator; LANGUAGE = ObjC; SUPERCLASS = NSControl; }
+    ); 
+    IBVersion = 1; 
+}
Index: releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/info.nib
===================================================================
--- releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/info.nib	(revision 349)
+++ releases/AntiRSI/1.4njr3/English.lproj/MainMenu.nib/info.nib	(revision 349)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>70 16 441 309 0 0 1680 1028 </string>
+	<key>IBEditorPositions</key>
+	<dict>
+		<key>259</key>
+		<string>668 524 300 322 0 0 1680 1028 </string>
+		<key>29</key>
+		<string>276 845 249 44 0 0 1680 1028 </string>
+		<key>343</key>
+		<string>241 262 145 99 0 0 1680 1028 </string>
+	</dict>
+	<key>IBFramework Version</key>
+	<string>446.1</string>
+	<key>IBOldestOS</key>
+	<integer>4</integer>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>259</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>8R2232</string>
+</dict>
+</plist>
Index: releases/AntiRSI/1.4njr3/Info.plist
===================================================================
--- releases/AntiRSI/1.4njr3/Info.plist	(revision 349)
+++ releases/AntiRSI/1.4njr3/Info.plist	(revision 349)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AntiRSI</string>
+	<key>CFBundleIconFile</key>
+	<string>AntiRSI.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.gorter.antirsi</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>ONNE</string>
+	<key>CFBundleVersion</key>
+	<string>1.4njr3</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
Index: releases/AntiRSI/1.4njr3/main.m
===================================================================
--- releases/AntiRSI/1.4njr3/main.m	(revision 349)
+++ releases/AntiRSI/1.4njr3/main.m	(revision 349)
@@ -0,0 +1,26 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char *argv[])
+{
+    return NSApplicationMain(argc, argv);
+}
