text:
// FRATextView delegate

#import "FRAStandardHeader.h"

#import "FRASyntaxColouring.h"
#import "FRATextView.h"
#import "FRABasicPerformer.h"
#import "FRAApplicationDelegate.h"
#import "FRAInterfacePerformer.h"
#import "FRAVariousPerformer.h"
#import "FRAProjectsController.h"
#import "FRAPreviewController.h"

#import "FRAProject.h"
#import "VADocument.h"
#import "FRATextView.h"

#import "VASyntaxDefinition.h"

#import <VAFoundation/VAFoundation.h>
#import <VADevUIKit/VADevUIKit.h>

@interface FRASyntaxColouring ()
{
	NSUndoManager *undoManager;
	VILayoutManager *firstLayoutManager;

	NSTimer *autocompleteWordsTimer;
	NSInteger currentYOfSelectedCharacter, lastYOfSelectedCharacter, currentYOfLastCharacterInLine, lastYOfLastCharacterInLine, currentYOfLastCharacter, lastYOfLastCharacter, lastCursorLocation;

	NSCharacterSet *letterCharacterSet, *keywordStartCharacterSet, *keywordEndCharacterSet;

	NSDictionary *commandsColour, *commentsColour, *instructionsColour, *keywordsColour, *autocompleteWordsColour, *stringsColour, *variablesColour, *attributesColour, *lineHighlightColour;

	NSEnumerator *wordEnumerator;
	NSSet *keywords;
	NSSet *autocompleteWords;
	NSArray *keywordsAndAutocompleteWords;
	BOOL keywordsCaseSensitive;
	BOOL recolourKeywordIfAlreadyColoured;
	NSString *beginCommand;
	NSString *endCommand;
	NSString *beginInstruction;
	NSString *endInstruction;
	NSCharacterSet *beginVariable;
	NSCharacterSet *endVariable;
	NSString *firstString;
	unichar firstStringUnichar;
	NSString *secondString;
	unichar secondStringUnichar;
	NSString *firstSingleLineComment, *secondSingleLineComment, *beginFirstMultiLineComment, *endFirstMultiLineComment, *beginSecondMultiLineComment, *endSecondMultiLineComment;

	NSString *completeString;
	NSString *searchString;
	NSScanner *scanner;
	NSScanner *completeDocumentScanner;
	NSInteger beginning, end, endOfLine, index, length, searchStringLength, commandLocation, skipEndCommand, beginLocationInMultiLine, endLocationInMultiLine, searchSyntaxLength, rangeLocation;
	NSRange rangeOfLine;
	NSString *keyword;
	BOOL shouldOnlyColourTillTheEndOfLine;
	unichar commandCharacterTest;
	unichar beginCommandCharacter;
	unichar endCommandCharacter;
	BOOL shouldColourMultiLineStrings;
	BOOL foundMatch;
	NSInteger completeStringLength;
	unichar characterToCheck;
	NSRange editedRange;
	NSInteger cursorLocation;
	NSInteger differenceBetweenLastAndPresent;
	NSInteger skipMatchingBrace;
	NSRect visibleRect;
	NSRange visibleRange;
	NSInteger beginningOfFirstVisibleLine;
	NSInteger endOfLastVisibleLine;
	NSRange selectedRange;;
	NSInteger stringLength;
	NSString *keywordTestString;
	NSString *autocompleteTestString;
	NSRange searchRange;
	NSInteger maxRange;

	NSTextContainer *textContainer;

	VADocument *document;

	NSCharacterSet *attributesCharacterSet;

	ICUPattern *firstStringPattern;
	ICUPattern *secondStringPattern;

	ICUMatcher *firstStringMatcher;
	ICUMatcher *secondStringMatcher;

	NSRange foundRange;

	NSTimer *liveUpdatePreviewTimer;

	NSRange lastLineHighlightRange;
}
@end

@implementation FRASyntaxColouring

@synthesize undoManager;

- (id)init
{
    return [self initWithDocument: nil];
}

- (id)initWithDocument:(id)theDocument
{
	if ((self = [super init]))
    {
		document = theDocument;
		firstLayoutManager = (VILayoutManager *)[[document firstTextView] layoutManager];
		_secondLayoutManager = nil;
		_thirdLayoutManager = nil;
		_fourthLayoutManager = nil;

		[self setColours];

		letterCharacterSet = [NSCharacterSet letterCharacterSet];
		NSMutableCharacterSet *temporaryCharacterSet = [[NSCharacterSet letterCharacterSet] mutableCopy];
		[temporaryCharacterSet addCharactersInString:@"_:@#"];
		keywordStartCharacterSet = [temporaryCharacterSet copy];

		temporaryCharacterSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy];
		[temporaryCharacterSet formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];
		[temporaryCharacterSet formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
		[temporaryCharacterSet removeCharactersInString:@"_"];
		keywordEndCharacterSet = [temporaryCharacterSet copy];

		temporaryCharacterSet = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
		[temporaryCharacterSet addCharactersInString:@" -"]; // If there are two spaces before an attribute
		attributesCharacterSet = [temporaryCharacterSet copy];

		[self setSyntaxDefinition];

		completeString = [[document firstTextView] string];
		textContainer = [[document firstTextView] textContainer];

		_reactToChanges = YES;

		[[document firstTextView] setDelegate:self];
		[[[document firstTextView] textStorage] setDelegate:self];
		undoManager = [[NSUndoManager alloc] init];
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkIfCanUndo) name:@"NSUndoManagerDidUndoChangeNotification" object:undoManager];

		lastLineHighlightRange = NSMakeRange(0, 0);

		NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];

		[defaultsController addObserver:self forKeyPath:@"values.CommandsColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.CommentsColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.InstructionsColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.KeywordsColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.AutocompleteColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.VariablesColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.StringsColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.AttributesColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourCommands" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourComments" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourInstructions" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourKeywords" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourAutocomplete" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourVariables" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourStrings" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourAttributes" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourMultiLineStrings" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.OnlyColourTillTheEndOfLine" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.HighlightCurrentLine" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.HighlightLineColourWell" options:NSKeyValueObservingOptionNew context:@"ColoursChanged"];
		[defaultsController addObserver:self forKeyPath:@"values.ColourMultiLineStrings" options:NSKeyValueObservingOptionNew context:@"MultiLineChanged"];

	}
    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	if ([(__bridge NSString *)context isEqualToString:@"ColoursChanged"]) {
		[self setColours];
		[self pageRecolour];
		if ([[FRADefaults valueForKey:@"HighlightCurrentLine"] boolValue] == YES) {
			NSRange range = [completeString lineRangeForRange:[[document firstTextView] selectedRange]];
			[self highlightLineRange:range];
			lastLineHighlightRange = range;
		} else {
			[self highlightLineRange:NSMakeRange(0, 0)];
		}
	} else if ([(__bridge NSString *)context isEqualToString:@"MultiLineChanged"]) {
		[self prepareRegularExpressions];
		[self pageRecolour];
	} else {
		[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
	}

}

- (NSUndoManager *)undoManagerForTextView:(NSTextView *)aTextView
{
	return undoManager;
}

#pragma mark -
#pragma mark Setup

- (void)setColours
{
	commandsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"CommandsColourWell"]]};

	commentsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"CommentsColourWell"]]};

	instructionsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"InstructionsColourWell"]]};

	keywordsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"KeywordsColourWell"]]};

	autocompleteWordsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"AutocompleteColourWell"]]};

	stringsColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"StringsColourWell"]]};

	variablesColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"VariablesColourWell"]]};

	attributesColour = @{NSForegroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"AttributesColourWell"]]};

	lineHighlightColour = @{NSBackgroundColorAttributeName: [NSUnarchiver unarchiveObjectWithData:[FRADefaults valueForKey:@"HighlightLineColourWell"]]};
}

- (void)setSyntaxDefinition
{
	NSArray *syntaxDefinitions = [VASyntaxDefinition allDefinitions];
    NSString *name = [FRADefaults valueForKey:@"SyntaxColouringPopUpString"];
	NSArray *foundSyntaxDefinition = nil;

	NSString *fileToUse = nil;
	NSString *extension = [[document name] pathExtension];
	if ([document hasManuallyChangedSyntaxDefinition] == YES)
    { // Once the user has changed the syntax definition always use that one and not the one from the extension

        //TODO
        //[document syntaxDefinition];
		NSArray *foundManuallyChangedSyntaxDefinition = nil;

		if ([foundManuallyChangedSyntaxDefinition count] != 0)
        {
			fileToUse = [foundManuallyChangedSyntaxDefinition[0] file];
		} else
        {
			fileToUse = [syntaxDefinitions[0] file];
		}
	} else {

		if ([[FRADefaults valueForKey:@"SyntaxColouringMatrix"] integerValue] == 1) { // Always use...
			if ([foundSyntaxDefinition count] != 0) {
				fileToUse = [foundSyntaxDefinition[0] file];
				[document setSyntaxDefinition: [foundSyntaxDefinition[0] name]];
			} else {
				fileToUse = [syntaxDefinitions[0] file];
				[document setSyntaxDefinition: [syntaxDefinitions[0] name]];
			}
		} else {
			NSString *lowercaseExtension;
			if ([extension isEqualToString:@""]) { // If there is no extension try to guess it
				NSString *string = [[[document firstTextScrollView] documentView] string];
				NSString *firstLine = [string substringWithRange:[string lineRangeForRange:NSMakeRange(0,0)]];
				if ([firstLine hasPrefix:@"#!"] || [firstLine hasPrefix:@"%"] || [firstLine hasPrefix:@"<?"]) {
					lowercaseExtension = [self guessSyntaxDefinitionFromFirstLine:firstLine];
				} else {
					lowercaseExtension = @"";
				}
			} else {
				lowercaseExtension = [extension lowercaseString];
			}

			VASyntaxDefinition *item;
			index = 0;
			for (item in syntaxDefinitions)
            {
				NSString *name = [item name];

				if ([name isEqualToString:@"Standard"] || [name isEqualToString:@"None"] || [item extensions] == nil)
                {
					continue;
				}
				NSMutableString *extensionsString = [NSMutableString stringWithString:[item extensions]];
				[extensionsString replaceOccurrencesOfString:@"." withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [extensionsString length])];
				if ([[extensionsString componentsSeparatedByString:@" "] containsObject:lowercaseExtension])
                {
					fileToUse = [item file];
					[document setSyntaxDefinition: name];
					break;
				}
				index++;
			}
			if (fileToUse == nil && [foundSyntaxDefinition count] != 0)
            {
				fileToUse = [foundSyntaxDefinition[0] file];
				[document setSyntaxDefinition: [foundSyntaxDefinition[0] name]];
			}
		}
	}

	if (fileToUse == nil)
    {
		fileToUse = @"standard"; // Be sure to set it to something
		[document setSyntaxDefinition: @"Standard"];
	}

	NSDictionary *syntaxDictionary;
	syntaxDictionary = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileToUse ofType:@"plist" inDirectory:@"Syntax Definitions"]];

	if (!syntaxDictionary)
    { // If it can't find it in the bundle try in Application Support
		NSString *path = [[[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"] stringByAppendingPathComponent:@"Application Support"] stringByAppendingPathComponent:@"Fraise"] stringByAppendingPathComponent:fileToUse] stringByAppendingString:@".plist"];
		syntaxDictionary = [[NSDictionary alloc] initWithContentsOfFile:path];
	}

	if (!syntaxDictionary)
    {
		syntaxDictionary = @{@"name": @"Standard", @"file": @"standard", @"extensions": @""}; // If it can't find a syntax file use Standard
	}

	NSMutableArray *keywordsAndAutocompleteWordsTemporary = [NSMutableArray array];

	// If the plist file is malformed be sure to set the values to something
	if (syntaxDictionary[@"keywords"])
    {
		keywords = [[NSSet alloc] initWithArray:syntaxDictionary[@"keywords"]];
		[keywordsAndAutocompleteWordsTemporary addObjectsFromArray:syntaxDictionary[@"keywords"]];
	}

	if (syntaxDictionary[@"autocompleteWords"]) {
		autocompleteWords = [[NSSet alloc] initWithArray:syntaxDictionary[@"autocompleteWords"]];

		[keywordsAndAutocompleteWordsTemporary addObjectsFromArray:syntaxDictionary[@"autocompleteWords"]];
	}

	if ([[FRADefaults valueForKey:@"ColourAutocompleteWordsAsKeywords"] boolValue] == YES)
    {
		keywords = [NSSet setWithArray:keywordsAndAutocompleteWordsTemporary];
	}

	keywordsAndAutocompleteWords = [keywordsAndAutocompleteWordsTemporary sortedArrayUsingSelector:@selector(compare:)];

	if (syntaxDictionary[@"recolourKeywordIfAlreadyColoured"])
    {
		recolourKeywordIfAlreadyColoured = [syntaxDictionary[@"recolourKeywordIfAlreadyColoured"] boolValue];
	}

	if (syntaxDictionary[@"keywordsCaseSensitive"])
    {
		keywordsCaseSensitive = [syntaxDictionary[@"keywordsCaseSensitive"] boolValue];
	}

	if (keywordsCaseSensitive == NO)
    {
		NSMutableArray *lowerCaseKeywords = [[NSMutableArray alloc] init];
		for (id item in keywords)
        {
			[lowerCaseKeywords addObject:[item lowercaseString]];
		}

		NSSet *lowerCaseKeywordsSet = [[NSSet alloc] initWithArray:lowerCaseKeywords];
		keywords = lowerCaseKeywordsSet;
	}

    beginCommand = syntaxDictionary[@"beginCommand"] ?: @"";
    endCommand = syntaxDictionary[@"endCommand"] ?: @"";
    beginInstruction = syntaxDictionary[@"beginInstruction"] ?: @"";
    endInstruction = syntaxDictionary[@"endInstruction"] ?: @"";

	if (syntaxDictionary[@"beginVariable"])
    {
		beginVariable = [NSCharacterSet characterSetWithCharactersInString:syntaxDictionary[@"beginVariable"]];
	}

	if (syntaxDictionary[@"endVariable"]) {
		endVariable = [NSCharacterSet characterSetWithCharactersInString:syntaxDictionary[@"endVariable"]];
	} else {
		endVariable = [NSCharacterSet characterSetWithCharactersInString:@""];
	}

	if (syntaxDictionary[@"firstString"]) {
		firstString = syntaxDictionary[@"firstString"];
		if (![syntaxDictionary[@"firstString"] isEqualToString:@""]) {
			firstStringUnichar = [syntaxDictionary[@"firstString"] characterAtIndex:0];
		}
	} else {
		firstString = @"";
	}

	if (syntaxDictionary[@"secondString"]) {
		secondString = syntaxDictionary[@"secondString"];
		if (![syntaxDictionary[@"secondString"] isEqualToString:@""]) {
			secondStringUnichar = [syntaxDictionary[@"secondString"] characterAtIndex:0];
		}
	} else {
		secondString = @"";
	}

    firstSingleLineComment = syntaxDictionary[@"firstSingleLineComment"] ?: @"";
    secondSingleLineComment = syntaxDictionary[@"secondSingleLineComment"] ?: @"";
    beginFirstMultiLineComment = syntaxDictionary[@"beginFirstMultiLineComment"] ?: @"";

    endFirstMultiLineComment = syntaxDictionary[@"endFirstMultiLineComment"] ?: @"";
    beginSecondMultiLineComment = syntaxDictionary[@"beginSecondMultiLineComment"] ?: @"";

    endSecondMultiLineComment = syntaxDictionary[@"endSecondMultiLineComment"] ?: @"";
    self.functionDefinition = syntaxDictionary[@"functionDefinition"] ?: @"";

    self.removeFromFunction = syntaxDictionary[@"removeFromFunction"] ?: @"";

	if (syntaxDictionary[@"excludeFromKeywordStartCharacterSet"])
    {
		NSMutableCharacterSet *temporaryCharacterSet = [keywordStartCharacterSet mutableCopy];
		[temporaryCharacterSet removeCharactersInString:syntaxDictionary[@"excludeFromKeywordStartCharacterSet"]];
		keywordStartCharacterSet = [temporaryCharacterSet copy];
	}

	if (syntaxDictionary[@"excludeFromKeywordEndCharacterSet"]) {
		NSMutableCharacterSet *temporaryCharacterSet = [keywordEndCharacterSet mutableCopy];
		[temporaryCharacterSet removeCharactersInString:syntaxDictionary[@"excludeFromKeywordEndCharacterSet"]];
		keywordEndCharacterSet = [temporaryCharacterSet copy];
	}

	if (syntaxDictionary[@"includeInKeywordStartCharacterSet"]) {
		NSMutableCharacterSet *temporaryCharacterSet = [keywordStartCharacterSet mutableCopy];
		[temporaryCharacterSet addCharactersInString:syntaxDictionary[@"includeInKeywordStartCharacterSet"]];
		keywordStartCharacterSet = [temporaryCharacterSet copy];
	}

	if (syntaxDictionary[@"includeInKeywordEndCharacterSet"]) {
		NSMutableCharacterSet *temporaryCharacterSet = [keywordEndCharacterSet mutableCopy];
		[temporaryCharacterSet addCharactersInString:syntaxDictionary[@"includeInKeywordEndCharacterSet"]];
		keywordEndCharacterSet = [temporaryCharacterSet copy];
	}

	[self prepareRegularExpressions];
}

- (void)prepareRegularExpressions
{
	if ([[FRADefaults valueForKey:@"ColourMultiLineStrings"] boolValue] == NO)
    {
		firstStringPattern = [[ICUPattern alloc] initWithString:[NSString stringWithFormat:@"\\W%@[^%@\\\\\\r\\n]*+(?:\\\\(?:.|$)[^%@\\\\\\r\\n]*+)*+%@", firstString, firstString, firstString, firstString]];

		secondStringPattern = [[ICUPattern alloc] initWithString:[NSString stringWithFormat:@"\\W%@[^%@\\\\\\r\\n]*+(?:\\\\(?:.|$)[^%@\\\\]*+)*+%@", secondString, secondString, secondString, secondString]];

	} else
    {
		firstStringPattern = [[ICUPattern alloc] initWithString:[NSString stringWithFormat:@"\\W%@[^%@\\\\]*+(?:\\\\(?:.|$)[^%@\\\\]*+)*+%@", firstString, firstString, firstString, firstString]];

		secondStringPattern = [[ICUPattern alloc] initWithString:[NSString stringWithFormat:@"\\W%@[^%@\\\\]*+(?:\\\\(?:.|$)[^%@\\\\]*+)*+%@", secondString, secondString, secondString, secondString]];
	}
}

#pragma mark -
#pragma mark Colouring

- (void)removeAllColours
{
	NSRange wholeRange = NSMakeRange(0, [completeString length]);

	[firstLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:wholeRange];
    [_secondLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:wholeRange];
    [_thirdLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:wholeRange];
    [_fourthLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:wholeRange];
}

- (void)removeColoursFromRange:(NSRange)range
{
	[firstLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:range];

    [_secondLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:range];
    [_thirdLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:range];
    [_fourthLayoutManager removeTemporaryAttribute:NSForegroundColorAttributeName forCharacterRange:range];
}

- (void)pageRecolour
{
	[self pageRecolourTextView:[document firstTextView]];
	if (_secondLayoutManager != nil)
    {
		[self pageRecolourTextView:[document secondTextView]];
	}
	if (_thirdLayoutManager != nil)
    {
		[self pageRecolourTextView:[document thirdTextView]];
	}
	if (_fourthLayoutManager != nil)
    {
		[self pageRecolourTextView: [document fourthTextView]];
	}
}

- (void)pageRecolourTextView:(FRATextView *)textView
{
	if ([document isSyntaxColoured] == NO) {
		return;
	}

	if (textView == nil) {
		return;
	}
	visibleRect = [[[textView enclosingScrollView] contentView] documentVisibleRect];
	visibleRange = [[textView layoutManager] glyphRangeForBoundingRect:visibleRect inTextContainer:[textView textContainer]];
	beginningOfFirstVisibleLine = [[textView string] lineRangeForRange:NSMakeRange(visibleRange.location, 0)].location;
	endOfLastVisibleLine = NSMaxRange([completeString lineRangeForRange:NSMakeRange(NSMaxRange(visibleRange), 0)]);

	[self recolourRange:NSMakeRange(beginningOfFirstVisibleLine, endOfLastVisibleLine - beginningOfFirstVisibleLine)];
}

- (void)recolourRange:(NSRange)range
{
	if (_reactToChanges == NO)
    {
		return;
	}

	shouldOnlyColourTillTheEndOfLine = [[FRADefaults valueForKey:@"OnlyColourTillTheEndOfLine"] boolValue];
	shouldColourMultiLineStrings = [[FRADefaults valueForKey:@"ColourMultiLineStrings"] boolValue];

	NSRange effectiveRange = range;

	if (shouldColourMultiLineStrings) { // When multiline strings are coloured it needs to go backwards to find where the string might have started if it's "above" the top of the screen
		NSInteger beginFirstStringInMultiLine = [completeString rangeOfString:firstString options:NSBackwardsSearch range:NSMakeRange(0, effectiveRange.location)].location;
		if (beginFirstStringInMultiLine != NSNotFound && [[firstLayoutManager temporaryAttributesAtCharacterIndex:beginFirstStringInMultiLine effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
			NSInteger startOfLine = [completeString lineRangeForRange:NSMakeRange(beginFirstStringInMultiLine, 0)].location;
			effectiveRange = NSMakeRange(startOfLine, range.length + (range.location - startOfLine));
		}
	}

	rangeLocation = effectiveRange.location;
	maxRange = NSMaxRange(effectiveRange);
	searchString = [completeString substringWithRange:effectiveRange];
	searchStringLength = [searchString length];
	if (searchStringLength == 0) {
		return;
	}
	scanner = [[NSScanner alloc] initWithString:searchString];
	[scanner setCharactersToBeSkipped:nil];
	completeDocumentScanner = [[NSScanner alloc] initWithString:completeString];
	[completeDocumentScanner setCharactersToBeSkipped:nil];

	completeStringLength = [completeString length];

	beginLocationInMultiLine = 0;

	[self removeColoursFromRange:range];

	@try {

        // Commands
        if (![beginCommand isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourCommands"] boolValue] == YES) {
            searchSyntaxLength = [endCommand length];
            beginCommandCharacter = [beginCommand characterAtIndex:0];
            endCommandCharacter = [endCommand characterAtIndex:0];
            while (![scanner isAtEnd]) {
                [scanner scanUpToString:beginCommand intoString:nil];
                beginning = [scanner scanLocation];
                endOfLine = NSMaxRange([searchString lineRangeForRange:NSMakeRange(beginning, 0)]);
                if (![scanner scanUpToString:endCommand intoString:nil] || [scanner scanLocation] >= endOfLine) {
                    [scanner setScanLocation:endOfLine];
                    continue; // Don't colour it if it hasn't got a closing tag
                } else {
                    // To avoid problems with strings like <yada <%=yada%> yada> we need to balance the number of begin- and end-tags
                    // If ever there's a beginCommand or endCommand with more than one character then do a check first
                    commandLocation = beginning + 1;
                    skipEndCommand = 0;

                    while (commandLocation < endOfLine) {
                        commandCharacterTest = [searchString characterAtIndex:commandLocation];
                        if (commandCharacterTest == endCommandCharacter) {
                            if (!skipEndCommand) {
                                break;
                            } else {
                                skipEndCommand--;
                            }
                        }
                        if (commandCharacterTest == beginCommandCharacter) {
                            skipEndCommand++;
                        }
                        commandLocation++;
                    }
                    if (commandLocation < endOfLine) {
                        [scanner setScanLocation:commandLocation + searchSyntaxLength];
                    } else {
                        [scanner setScanLocation:endOfLine];
                    }
                }

                [self setColour:commandsColour range:NSMakeRange(beginning + rangeLocation, [scanner scanLocation] - beginning)];
            }
        }

        // Instructions
        if (![beginInstruction isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourInstructions"] boolValue] == YES) {
            // It takes too long to scan the whole document if it's large, so for instructions, first multi-line comment and second multi-line comment search backwards and begin at the start of the first beginInstruction etc. that it finds from the present position and, below, break the loop if it has passed the scanned range (i.e. after the end instruction)

            beginLocationInMultiLine = [completeString rangeOfString:beginInstruction options:NSBackwardsSearch range:NSMakeRange(0, rangeLocation)].location;
            endLocationInMultiLine = [completeString rangeOfString:endInstruction options:NSBackwardsSearch range:NSMakeRange(0, rangeLocation)].location;
            if (beginLocationInMultiLine == NSNotFound || (endLocationInMultiLine != NSNotFound && beginLocationInMultiLine < endLocationInMultiLine)) {
                beginLocationInMultiLine = rangeLocation;
            }

            searchSyntaxLength = [endInstruction length];
            while (![completeDocumentScanner isAtEnd]) {
                searchRange = NSMakeRange(beginLocationInMultiLine, range.length);
                if (NSMaxRange(searchRange) > completeStringLength) {
                    searchRange = NSMakeRange(beginLocationInMultiLine, completeStringLength - beginLocationInMultiLine);
                }

                beginning = [completeString rangeOfString:beginInstruction options:NSLiteralSearch range:searchRange].location;
                if (beginning == NSNotFound) {
                    break;
                }
                [completeDocumentScanner setScanLocation:beginning];
                if (![completeDocumentScanner scanUpToString:endInstruction intoString:nil] || [completeDocumentScanner scanLocation] >= completeStringLength) {
                    if (shouldOnlyColourTillTheEndOfLine) {
                        [completeDocumentScanner setScanLocation:NSMaxRange([completeString lineRangeForRange:NSMakeRange(beginning, 0)])];
                    } else {
                        [completeDocumentScanner setScanLocation:completeStringLength];
                    }
                } else {
                    if ([completeDocumentScanner scanLocation] + searchSyntaxLength <= completeStringLength) {
                        [completeDocumentScanner setScanLocation:[completeDocumentScanner scanLocation] + searchSyntaxLength];
                    }
                }

                [self setColour:instructionsColour range:NSMakeRange(beginning, [completeDocumentScanner scanLocation] - beginning)];
                if ([completeDocumentScanner scanLocation] > maxRange) {
                    break;
                }
                beginLocationInMultiLine = [completeDocumentScanner scanLocation];
            }
        }

        // Keywords
        if ([keywords count] != 0 && [[FRADefaults valueForKey:@"ColourKeywords"] boolValue] == YES) {
            [scanner setScanLocation:0];
            while (![scanner isAtEnd]) {
                [scanner scanUpToCharactersFromSet:keywordStartCharacterSet intoString:nil];
                beginning = [scanner scanLocation];
                if ((beginning + 1) < searchStringLength) {
                    [scanner setScanLocation:(beginning + 1)];
                }
                [scanner scanUpToCharactersFromSet:keywordEndCharacterSet intoString:nil];

                end = [scanner scanLocation];
                if (end > searchStringLength || beginning == end) {
                    break;
                }

                if (!keywordsCaseSensitive) {
                    keywordTestString = [[completeString substringWithRange:NSMakeRange(beginning + rangeLocation, end - beginning)] lowercaseString];
                } else {
                    keywordTestString = [completeString substringWithRange:NSMakeRange(beginning + rangeLocation, end - beginning)];
                }
                if ([keywords containsObject:keywordTestString]) {
                    if (!recolourKeywordIfAlreadyColoured) {
                        if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning + rangeLocation effectiveRange:NULL] isEqualToDictionary:commandsColour]) {
                            continue;
                        }
                    }
                    [self setColour:keywordsColour range:NSMakeRange(beginning + rangeLocation, [scanner scanLocation] - beginning)];
                }
            }
        }

        // Autocomplete
        if ([autocompleteWords count] != 0 && [[FRADefaults valueForKey:@"ColourAutocomplete"] boolValue] == YES) {
            [scanner setScanLocation:0];
            while (![scanner isAtEnd]) {
                [scanner scanUpToCharactersFromSet:keywordStartCharacterSet intoString:nil];
                beginning = [scanner scanLocation];
                if ((beginning + 1) < searchStringLength) {
                    [scanner setScanLocation:(beginning + 1)];
                }
                [scanner scanUpToCharactersFromSet:keywordEndCharacterSet intoString:nil];

                end = [scanner scanLocation];
                if (end > searchStringLength || beginning == end) {
                    break;
                }

                if (!keywordsCaseSensitive) {
                    autocompleteTestString = [[completeString substringWithRange:NSMakeRange(beginning + rangeLocation, end - beginning)] lowercaseString];
                } else {
                    autocompleteTestString = [completeString substringWithRange:NSMakeRange(beginning + rangeLocation, end - beginning)];
                }
                if ([autocompleteWords containsObject:autocompleteTestString]) {
                    if (!recolourKeywordIfAlreadyColoured) {
                        if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning + rangeLocation effectiveRange:NULL] isEqualToDictionary:commandsColour]) {
                            continue;
                        }
                    }

                    [self setColour:autocompleteWordsColour range:NSMakeRange(beginning + rangeLocation, [scanner scanLocation] - beginning)];
                }
            }
        }

        // Variables
        if (beginVariable != nil && [[FRADefaults valueForKey:@"ColourVariables"] boolValue] == YES) {
            [scanner setScanLocation:0];
            while (![scanner isAtEnd]) {
                [scanner scanUpToCharactersFromSet:beginVariable intoString:nil];
                beginning = [scanner scanLocation];
                if (beginning + 1 < searchStringLength) {
                    if ([firstSingleLineComment isEqualToString:@"%"] && [searchString characterAtIndex:beginning + 1] == '%') { // To avoid a problem in LaTex with \%
                        if ([scanner scanLocation] < searchStringLength) {
                            [scanner setScanLocation:beginning + 1];
                        }
                        continue;
                    }
                }
                endOfLine = NSMaxRange([searchString lineRangeForRange:NSMakeRange(beginning, 0)]);
                if (![scanner scanUpToCharactersFromSet:endVariable intoString:nil] || [scanner scanLocation] >= endOfLine) {
                    [scanner setScanLocation:endOfLine];
                    length = [scanner scanLocation] - beginning;
                } else {
                    length = [scanner scanLocation] - beginning;
                    if ([scanner scanLocation] < searchStringLength) {
                        [scanner setScanLocation:[scanner scanLocation] + 1];
                    }
                }

                [self setColour:variablesColour range:NSMakeRange(beginning + rangeLocation, length)];
            }
        }

        // Second string, first pass
        if (![secondString isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourStrings"] boolValue] == YES) {
            @try {
                secondStringMatcher = [[ICUMatcher alloc] initWithPattern:secondStringPattern overString:searchString];
            }
            @catch (NSException *exception) {
                return;
            }

            while ([secondStringMatcher findNext]) {
                foundRange = [secondStringMatcher rangeOfMatch];
                [self setColour:stringsColour range:NSMakeRange(foundRange.location + rangeLocation + 1, foundRange.length - 1)];
            }
        }

        // First string
        if (![firstString isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourStrings"] boolValue] == YES) {
            @try {
                firstStringMatcher = [[ICUMatcher alloc] initWithPattern:firstStringPattern overString:searchString];
            }
            @catch (NSException *exception) {
                return;
            }

            while ([firstStringMatcher findNext]) {
                foundRange = [firstStringMatcher rangeOfMatch];
                if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:foundRange.location + rangeLocation effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
                    continue;
                }
                [self setColour:stringsColour range:NSMakeRange(foundRange.location + rangeLocation + 1, foundRange.length - 1)];
            }
        }

        // Attributes
        if ([[FRADefaults valueForKey:@"ColourAttributes"] boolValue] == YES) {
            [scanner setScanLocation:0];
            while (![scanner isAtEnd]) {
                [scanner scanUpToString:@" " intoString:nil];
                beginning = [scanner scanLocation];
                if (beginning + 1 < searchStringLength) {
                    [scanner setScanLocation:beginning + 1];
                } else {
                    break;
                }
                if (![[firstLayoutManager temporaryAttributesAtCharacterIndex:(beginning + rangeLocation) effectiveRange:NULL] isEqualToDictionary:commandsColour]) {
                    continue;
                }

                [scanner scanCharactersFromSet:attributesCharacterSet intoString:nil];
                end = [scanner scanLocation];

                if (end + 1 < searchStringLength) {
                    [scanner setScanLocation:[scanner scanLocation] + 1];
                }

                if ([completeString characterAtIndex:end + rangeLocation] == '=') {
                    [self setColour:attributesColour range:NSMakeRange(beginning + rangeLocation, end - beginning)];
                }
            }
        }

        // First single-line comment
        if (![firstSingleLineComment isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourComments"] boolValue] == YES) {
            [scanner setScanLocation:0];
            searchSyntaxLength = [firstSingleLineComment length];
            while (![scanner isAtEnd]) {
                [scanner scanUpToString:firstSingleLineComment intoString:nil];
                beginning = [scanner scanLocation];
                if ([firstSingleLineComment isEqualToString:@"//"]) {
                    if (beginning > 0 && [searchString characterAtIndex:beginning - 1] == ':') {
                        [scanner setScanLocation:beginning + 1];
                        continue; // To avoid http:// ftp:// file:// etc.
                    }
                } else if ([firstSingleLineComment isEqualToString:@"#"]) {
                    if (searchStringLength > 1) {
                        rangeOfLine = [searchString lineRangeForRange:NSMakeRange(beginning, 0)];
                        if ([searchString rangeOfString:@"#!" options:NSLiteralSearch range:rangeOfLine].location != NSNotFound) {
                            [scanner setScanLocation:NSMaxRange(rangeOfLine)];
                            continue; // Don't treat the line as a comment if it begins with #!
                        } else if ([searchString characterAtIndex:beginning - 1] == '$') {
                            [scanner setScanLocation:beginning + 1];
                            continue; // To avoid $#
                        } else if ([searchString characterAtIndex:beginning - 1] == '&') {
                            [scanner setScanLocation:beginning + 1];
                            continue; // To avoid &#
                        }
                    }
                } else if ([firstSingleLineComment isEqualToString:@"%"]) {
                    if (searchStringLength > 1) {
                        if ([searchString characterAtIndex:beginning - 1] == '\\') {
                            [scanner setScanLocation:beginning + 1];
                            continue; // To avoid \% in LaTex
                        }
                    }
                }
                if (beginning + rangeLocation + searchSyntaxLength < completeStringLength) {
                    if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning + rangeLocation effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
                        [scanner setScanLocation:beginning + 1];
                        continue; // If the comment is within a string disregard it
                    }
                }
                endOfLine = NSMaxRange([searchString lineRangeForRange:NSMakeRange(beginning, 0)]);
                [scanner setScanLocation:endOfLine];

                [self setColour:commentsColour range:NSMakeRange(beginning + rangeLocation, [scanner scanLocation] - beginning)];
            }
        }

        // Second single-line comment
        if (![secondSingleLineComment isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourComments"] boolValue] == YES) {
            [scanner setScanLocation:0];
            searchSyntaxLength = [secondSingleLineComment length];
            while (![scanner isAtEnd]) {
                [scanner scanUpToString:secondSingleLineComment intoString:nil];
                beginning = [scanner scanLocation];

                if ([secondSingleLineComment isEqualToString:@"//"]) {
                    if (beginning > 0 && [searchString characterAtIndex:beginning - 1] == ':') {
                        [scanner setScanLocation:beginning + 1];
                        continue; // To avoid http:// ftp:// file:// etc.
                    }
                } else if ([secondSingleLineComment isEqualToString:@"#"]) {
                    if (searchStringLength > 1) {
                        rangeOfLine = [searchString lineRangeForRange:NSMakeRange(beginning, 0)];
                        if ([searchString rangeOfString:@"#!" options:NSLiteralSearch range:rangeOfLine].location != NSNotFound) {
                            [scanner setScanLocation:NSMaxRange(rangeOfLine)];
                            continue; // Don't treat the line as a comment if it begins with #!
                        } else if ([searchString characterAtIndex:beginning - 1] == '$') {
                            [scanner setScanLocation:beginning + 1];
                            continue; // To avoid $#
                        } else if ([searchString characterAtIndex:beginning - 1] == '&') {
                            [scanner setScanLocation:beginning + 1];
                            continue; // To avoid &#
                        }
                    }
                }
                if (beginning + rangeLocation + searchSyntaxLength < completeStringLength) {
                    if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning + rangeLocation effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
                        [scanner setScanLocation:beginning + 1];
                        continue; // If the comment is within a string disregard it
                    }
                }
                endOfLine = NSMaxRange([searchString lineRangeForRange:NSMakeRange(beginning, 0)]);
                [scanner setScanLocation:endOfLine];

                [self setColour:commentsColour range:NSMakeRange(beginning + rangeLocation, [scanner scanLocation] - beginning)];
            }
        }

        // First multi-line comment
        if (![beginFirstMultiLineComment isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourComments"] boolValue] == YES) {

            beginLocationInMultiLine = [completeString rangeOfString:beginFirstMultiLineComment options:NSBackwardsSearch range:NSMakeRange(0, rangeLocation)].location;
            endLocationInMultiLine = [completeString rangeOfString:endFirstMultiLineComment options:NSBackwardsSearch range:NSMakeRange(0, rangeLocation)].location;
            if (beginLocationInMultiLine == NSNotFound || (endLocationInMultiLine != NSNotFound && beginLocationInMultiLine < endLocationInMultiLine)) {
                beginLocationInMultiLine = rangeLocation;
            }
            [completeDocumentScanner setScanLocation:beginLocationInMultiLine];
            searchSyntaxLength = [endFirstMultiLineComment length];

            while (![completeDocumentScanner isAtEnd]) {
                searchRange = NSMakeRange(beginLocationInMultiLine, range.length);
                if (NSMaxRange(searchRange) > completeStringLength) {
                    searchRange = NSMakeRange(beginLocationInMultiLine, completeStringLength - beginLocationInMultiLine);
                }
                beginning = [completeString rangeOfString:beginFirstMultiLineComment options:NSLiteralSearch range:searchRange].location;
                if (beginning == NSNotFound) {
                    break;
                }
                [completeDocumentScanner setScanLocation:beginning];
                if (beginning + 1 < completeStringLength) {
                    if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
                        [completeDocumentScanner setScanLocation:beginning + 1];
                        beginLocationInMultiLine++;
                        continue; // If the comment is within a string disregard it
                    }
                }
                if (![completeDocumentScanner scanUpToString:endFirstMultiLineComment intoString:nil] || [completeDocumentScanner scanLocation] >= completeStringLength) {
                    if (shouldOnlyColourTillTheEndOfLine) {
                        [completeDocumentScanner setScanLocation:NSMaxRange([completeString lineRangeForRange:NSMakeRange(beginning, 0)])];
                    } else {
                        [completeDocumentScanner setScanLocation:completeStringLength];
                    }
                    length = [completeDocumentScanner scanLocation] - beginning;
                } else {
                    if ([completeDocumentScanner scanLocation] < completeStringLength)
                        [completeDocumentScanner setScanLocation:[completeDocumentScanner scanLocation] + searchSyntaxLength];
                    length = [completeDocumentScanner scanLocation] - beginning;
                    if ([endFirstMultiLineComment isEqualToString:@"-->"]) {
                        [completeDocumentScanner scanUpToCharactersFromSet:letterCharacterSet intoString:nil]; // Search for the first letter after -->
                        if ([completeDocumentScanner scanLocation] + 6 < completeStringLength) {// Check if there's actually room for a </script>
                            if ([completeString rangeOfString:@"</script>" options:NSCaseInsensitiveSearch range:NSMakeRange([completeDocumentScanner scanLocation] - 2, 9)].location != NSNotFound || [completeString rangeOfString:@"</style>" options:NSCaseInsensitiveSearch range:NSMakeRange([completeDocumentScanner scanLocation] - 2, 8)].location != NSNotFound) {
                                beginLocationInMultiLine = [completeDocumentScanner scanLocation];
                                continue; // If the comment --> is followed by </script> or </style> it is probably not a real comment
                            }
                        }
                        [completeDocumentScanner setScanLocation:beginning + length]; // Reset the scanner position
                    }
                }

                [self setColour:commentsColour range:NSMakeRange(beginning, length)];

                if ([completeDocumentScanner scanLocation] > maxRange) {
                    break;
                }
                beginLocationInMultiLine = [completeDocumentScanner scanLocation];
            }
        }

        // Second multi-line comment
        if (![beginSecondMultiLineComment isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourComments"] boolValue] == YES) {

            beginLocationInMultiLine = rangeLocation;
            [completeDocumentScanner setScanLocation:beginLocationInMultiLine];
            searchSyntaxLength = [endSecondMultiLineComment length];

            while (![completeDocumentScanner isAtEnd]) {
                searchRange = NSMakeRange(beginLocationInMultiLine, range.length);
                if (NSMaxRange(searchRange) > completeStringLength) {
                    searchRange = NSMakeRange(beginLocationInMultiLine, completeStringLength - beginLocationInMultiLine);
                }
                beginning = [completeString rangeOfString:beginSecondMultiLineComment options:NSLiteralSearch range:searchRange].location;
                if (beginning == NSNotFound) {
                    break;
                }
                [completeDocumentScanner setScanLocation:beginning];
                if (beginning + 1 < completeStringLength) {
                    if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:beginning effectiveRange:NULL] isEqualToDictionary:stringsColour]) {
                        [completeDocumentScanner setScanLocation:beginning + 1];
                        beginLocationInMultiLine++;
                        continue; // If the comment is within a string disregard it
                    }
                }

                if (![completeDocumentScanner scanUpToString:endSecondMultiLineComment intoString:nil] || [completeDocumentScanner scanLocation] >= completeStringLength) {
                    if (shouldOnlyColourTillTheEndOfLine) {
                        [completeDocumentScanner setScanLocation:NSMaxRange([completeString lineRangeForRange:NSMakeRange(beginning, 0)])];
                    } else {
                        [completeDocumentScanner setScanLocation:completeStringLength];
                    }
                    length = [completeDocumentScanner scanLocation] - beginning;
                } else {
                    if ([completeDocumentScanner scanLocation] < completeStringLength)
                        [completeDocumentScanner setScanLocation:[completeDocumentScanner scanLocation] + searchSyntaxLength];
                    length = [completeDocumentScanner scanLocation] - beginning;
                    if ([endSecondMultiLineComment isEqualToString:@"-->"]) {
                        [completeDocumentScanner scanUpToCharactersFromSet:letterCharacterSet intoString:nil]; // Search for the first letter after -->
                        if ([completeDocumentScanner scanLocation] + 6 < completeStringLength) { // Check if there's actually room for a </script>
                            if ([completeString rangeOfString:@"</script>" options:NSCaseInsensitiveSearch range:NSMakeRange([completeDocumentScanner scanLocation] - 2, 9)].location != NSNotFound || [completeString rangeOfString:@"</style>" options:NSCaseInsensitiveSearch range:NSMakeRange([completeDocumentScanner scanLocation] - 2, 8)].location != NSNotFound) {
                                beginLocationInMultiLine = [completeDocumentScanner scanLocation];
                                continue; // If the comment --> is followed by </script> or </style> it is probably not a real comment
                            }
                        }
                        [completeDocumentScanner setScanLocation:beginning + length]; // Reset the scanner position
                    }
                }
                [self setColour:commentsColour range:NSMakeRange(beginning, length)];

                if ([completeDocumentScanner scanLocation] > maxRange) {
                    break;
                }
                beginLocationInMultiLine = [completeDocumentScanner scanLocation];
            }
        }

        // Second string, second pass
        if (![secondString isEqualToString:@""] && [[FRADefaults valueForKey:@"ColourStrings"] boolValue] == YES) {
            @try {
                [secondStringMatcher reset];
            }
            @catch (NSException *exception) {
                return;
            }

            while ([secondStringMatcher findNext]) {
                foundRange = [secondStringMatcher rangeOfMatch];
                if ([[firstLayoutManager temporaryAttributesAtCharacterIndex:foundRange.location + rangeLocation effectiveRange:NULL] isEqualToDictionary:stringsColour] || [[firstLayoutManager temporaryAttributesAtCharacterIndex:foundRange.location + rangeLocation effectiveRange:NULL] isEqualToDictionary:commentsColour]) {
                    continue;
                }
                [self setColour:stringsColour range:NSMakeRange(foundRange.location + rangeLocation + 1, foundRange.length - 1)];
            }
        }

	}
	@catch (NSException *exception) {
		//Log(exception);
	}

}

- (void)setColour:(NSDictionary *)colourDictionary range:(NSRange)range
{
	[firstLayoutManager setTemporaryAttributes:colourDictionary forCharacterRange:range];

    [_secondLayoutManager setTemporaryAttributes:colourDictionary forCharacterRange:range];
    [_thirdLayoutManager setTemporaryAttributes:colourDictionary forCharacterRange:range];
    [_fourthLayoutManager setTemporaryAttributes:colourDictionary forCharacterRange:range];
}

- (void)highlightLineRange:(NSRange)lineRange
{
	if (lineRange.location == lastLineHighlightRange.location && lineRange.length == lastLineHighlightRange.length) {
		return;
	}

	[firstLayoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:lastLineHighlightRange];

    [_secondLayoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:lastLineHighlightRange];

    [_thirdLayoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:lastLineHighlightRange];
    [_fourthLayoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:lastLineHighlightRange];

	[self pageRecolour];

	[firstLayoutManager addTemporaryAttributes:lineHighlightColour forCharacterRange:lineRange];

    [_secondLayoutManager addTemporaryAttributes:lineHighlightColour forCharacterRange:lineRange];

    [_thirdLayoutManager addTemporaryAttributes:lineHighlightColour forCharacterRange:lineRange];
    [_fourthLayoutManager addTemporaryAttributes:lineHighlightColour forCharacterRange:lineRange];

	lastLineHighlightRange = lineRange;
}

#pragma mark -
#pragma mark Delegates

- (void)textDidChange:(NSNotification *)notification
{
	if (_reactToChanges == NO)
    {
		return;
	}

	if ([completeString length] < 2) {
		[FRAInterface updateStatusBar]; // One needs to call this from here as well because otherwise it won't update the status bar if one writes one character and deletes it in an empty document, because the textViewDidChangeSelection delegate method won't be called.
	}

	FRATextView *textView = (FRATextView *)[notification object];

	if ([document isEdited] == NO) {
		[FRAVarious hasChangedDocument:document];
	}

	if ([[FRADefaults valueForKey:@"HighlightCurrentLine"] boolValue] == YES) {
		[self highlightLineRange:[completeString lineRangeForRange:[textView selectedRange]]];
	} else if ([document isSyntaxColoured] == YES) {
		[self pageRecolourTextView:textView];
	}

	if (autocompleteWordsTimer != nil) {
		[autocompleteWordsTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:[[FRADefaults valueForKey:@"AutocompleteAfterDelay"] doubleValue]]];
	} else if ([[FRADefaults valueForKey:@"AutocompleteSuggestAutomatically"] boolValue] == YES) {
		autocompleteWordsTimer = [NSTimer scheduledTimerWithTimeInterval:[[FRADefaults valueForKey:@"AutocompleteAfterDelay"] doubleValue] target:self selector:@selector(autocompleteWordsTimerSelector:) userInfo:textView repeats:NO];
	}

	if (liveUpdatePreviewTimer != nil) {
		[liveUpdatePreviewTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:[[FRADefaults valueForKey:@"LiveUpdatePreviewDelay"] doubleValue]]];
	} else if ([[FRADefaults valueForKey:@"LiveUpdatePreview"] boolValue] == YES) {
		liveUpdatePreviewTimer = [NSTimer scheduledTimerWithTimeInterval:[[FRADefaults valueForKey:@"LiveUpdatePreviewDelay"] doubleValue] target:self selector:@selector(liveUpdatePreviewTimerSelector:) userInfo:textView repeats:NO];
	}

	[[document lineNumbers] updateLineNumbersCheckWidth: NO];
}

- (void)textViewDidChangeSelection:(NSNotification *)aNotification
{
	if (_reactToChanges == NO)
    {
		return;
	}

	completeStringLength = [completeString length];
	if (completeStringLength == 0) {
		return;
	}

	FRATextView *textView = [aNotification object];
	[FRACurrentProject setLastTextViewInFocus:textView];

	[FRAInterface updateStatusBar];

	editedRange = [textView selectedRange];

	if ([[FRADefaults valueForKey:@"HighlightCurrentLine"] boolValue] == YES) {
		[self highlightLineRange:[completeString lineRangeForRange:editedRange]];
	}

	if ([[FRADefaults valueForKey:@"ShowMatchingBraces"] boolValue] == NO) {
		return;
	}

	cursorLocation = editedRange.location;
	differenceBetweenLastAndPresent = cursorLocation - lastCursorLocation;
	lastCursorLocation = cursorLocation;
	if (differenceBetweenLastAndPresent != 1 && differenceBetweenLastAndPresent != -1) {
		return; // If the difference is more than one, they've moved the cursor with the mouse or it has been moved by resetSelectedRange below and we shouldn't check for matching braces then
	}

	if (differenceBetweenLastAndPresent == 1) { // Check if the cursor has moved forward
		cursorLocation--;
	}

	if (cursorLocation == completeStringLength) {
		return;
	}

	characterToCheck = [completeString characterAtIndex:cursorLocation];
	skipMatchingBrace = 0;

	if (characterToCheck == ')') {
		while (cursorLocation--) {
			characterToCheck = [completeString characterAtIndex:cursorLocation];
			if (characterToCheck == '(') {
				if (!skipMatchingBrace) {
					[textView showFindIndicatorForRange:NSMakeRange(cursorLocation, 1)];
					return;
				} else {
					skipMatchingBrace--;
				}
			} else if (characterToCheck == ')') {
				skipMatchingBrace++;
			}
		}
		NSBeep();
	} else if (characterToCheck == ']') {
		while (cursorLocation--) {
			characterToCheck = [completeString characterAtIndex:cursorLocation];
			if (characterToCheck == '[') {
				if (!skipMatchingBrace) {
					[textView showFindIndicatorForRange:NSMakeRange(cursorLocation, 1)];
					return;
				} else {
					skipMatchingBrace--;
				}
			} else if (characterToCheck == ']') {
				skipMatchingBrace++;
			}
		}
		NSBeep();
	} else if (characterToCheck == '}') {
		while (cursorLocation--) {
			characterToCheck = [completeString characterAtIndex:cursorLocation];
			if (characterToCheck == '{') {
				if (!skipMatchingBrace) {
					[textView showFindIndicatorForRange:NSMakeRange(cursorLocation, 1)];
					return;
				} else {
					skipMatchingBrace--;
				}
			} else if (characterToCheck == '}') {
				skipMatchingBrace++;
			}
		}
		NSBeep();
	} else if (characterToCheck == '>') {
		while (cursorLocation--) {
			characterToCheck = [completeString characterAtIndex:cursorLocation];
			if (characterToCheck == '<') {
				if (!skipMatchingBrace) {
					[textView showFindIndicatorForRange:NSMakeRange(cursorLocation, 1)];
					return;
				} else {
					skipMatchingBrace--;
				}
			} else if (characterToCheck == '>') {
				skipMatchingBrace++;
			}
		}
	}
}

- (NSArray *)textView:theTextView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index
{
	if ([keywordsAndAutocompleteWords count] == 0) {
		if ([[FRADefaults valueForKey:@"AutocompleteIncludeStandardWords"] boolValue] == NO) {
			return @[];
		} else {
			return words;
		}
	}

	NSString *matchString = [[theTextView string] substringWithRange:charRange];
	NSMutableArray *finalWordsArray = [NSMutableArray arrayWithArray:keywordsAndAutocompleteWords];
	if ([[FRADefaults valueForKey:@"AutocompleteIncludeStandardWords"] boolValue]) {
		[finalWordsArray addObjectsFromArray:words];
	}

	NSMutableArray *matchArray = [NSMutableArray array];
	NSString *item;
	for (item in finalWordsArray) {
		if ([item rangeOfString:matchString options:NSCaseInsensitiveSearch range:NSMakeRange(0, [item length])].location == 0) {
			[matchArray addObject:item];
		}
	}

	if ([[FRADefaults valueForKey:@"AutocompleteIncludeStandardWords"] boolValue]) { // If no standard words are added there's no need to sort it again as it has already been sorted
		return [matchArray sortedArrayUsingSelector:@selector(compare:)];
	} else {
		return matchArray;
	}
}

#pragma mark -
#pragma mark Other
- (NSString *)guessSyntaxDefinitionFromFirstLine:(NSString *)firstLine
{
	NSString *returnString;
	NSRange firstLineRange = NSMakeRange(0, [firstLine length]);
	if ([firstLine rangeOfString:@"perl" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"pl";
	} else if ([firstLine rangeOfString:@"wish" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"tcl";
	} else if ([firstLine rangeOfString:@"sh" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"sh";
	} else if ([firstLine rangeOfString:@"php" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"php";
	} else if ([firstLine rangeOfString:@"python" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"py";
	} else if ([firstLine rangeOfString:@"awk" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"awk";
	} else if ([firstLine rangeOfString:@"xml" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"xml";
	} else if ([firstLine rangeOfString:@"ruby" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"rb";
	} else if ([firstLine rangeOfString:@"%!ps" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"ps";
	} else if ([firstLine rangeOfString:@"%pdf" options:NSCaseInsensitiveSearch range:firstLineRange].location != NSNotFound) {
		returnString = @"pdf";
	} else {
		returnString = @"";
	}

	return returnString;
}

- (void)checkIfCanUndo
{
	if (![undoManager canUndo]) {
		[[FRAProjectsController currentDocument] setValue:@NO forKey:@"isEdited"];
		[FRACurrentProject updateEditedBlobStatus];
		[FRACurrentProject reloadData];
	}
}

- (void)autocompleteWordsTimerSelector:(NSTimer *)theTimer
{
	FRATextView *textView = [theTimer userInfo];
	selectedRange = [textView selectedRange];
	stringLength = [completeString length];
	if (selectedRange.location <= stringLength && selectedRange.length == 0 && stringLength != 0) {
		if (selectedRange.location == stringLength) { // If we're at the very end of the document
			[textView complete:nil];
		} else {
			unichar characterAfterSelection = [completeString characterAtIndex:selectedRange.location];
			if ([[NSCharacterSet symbolCharacterSet] characterIsMember:characterAfterSelection] || [[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:characterAfterSelection] || [[NSCharacterSet punctuationCharacterSet] characterIsMember:characterAfterSelection] || selectedRange.location == stringLength) { // Don't autocomplete if we're in the middle of a word
				[textView complete:nil];
			}
		}
	}

	if (autocompleteWordsTimer) {
		[autocompleteWordsTimer invalidate];
		autocompleteWordsTimer = nil;
	}
}

- (void)liveUpdatePreviewTimerSelector:(NSTimer *)theTimer
{
	if ([[FRADefaults valueForKey:@"LiveUpdatePreview"] boolValue] == YES) {
		[[FRAPreviewController sharedInstance] liveUpdate];
	}

	if (liveUpdatePreviewTimer) {
		[liveUpdatePreviewTimer invalidate];
		liveUpdatePreviewTimer = nil;
	}
}

@end


text:
package com.aaomidi.justskyblock.engine.protection;

import com.aaomidi.justskyblock.JustSkyblock;

/**
 * @author aaomidi
 */
public class ProtectionManagement {
    protected final JustSkyblock instance;

    public ProtectionManagement(JustSkyblock instance) {
        this.instance = instance;
    }
}

redpajama_set_name: RedPajamaGithub


text:
Mini application Tetris / projet d'école - jeu vidéo INSTA 2016 ( SKM / JB / FDE )

USAGE

Desktop
In your terminal :
sh run_server.sh
...
sh run_client.sh

Android
On eclipse
	Run As > Android Application


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Gard. Chron. ser. 2, 18:134. 1882

#### Original name
null

### Remarks
null


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->

<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://ofbiz.apache.org/Simple-Method" xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method http://ofbiz.apache.org/dtds/simple-methods.xsd">

    <simple-method method-name="portalPermissionIsEmployee" short-description="check permission for Employee">
        <set field="hasPermission" value="true" type="Boolean"/>
        <set field="hasNoPermission" value="false" type="Boolean"/>

        <if-has-permission permission="MYPORTAL_EMPLOYEE">
            <field-to-result field="hasPermission"/>
            <return/>
            <else>
                <field-to-result field="hasNoPermission" result-name="hasPermission"/>
                <return/>
            </else>
        </if-has-permission>
    </simple-method>

    <simple-method method-name="portalPermissionIsCustomer" short-description="check permission for customer">
        <set field="hasPermission" value="true" type="Boolean"/>
        <set field="hasNoPermission" value="false" type="Boolean"/>

        <if-has-permission permission="MYPORTAL_CUSTOMER">
            <field-to-result field="hasPermission"/>
            <return/>
            <else>
                <field-to-result field="hasNoPermission" result-name="hasPermission"/>
                <return/>
            </else>
        </if-has-permission>
    </simple-method>

</simple-methods>


text:
import copy

from rally.common import logging
from rally import consts
from rally.deployment import credential
from rally.deployment import engine

LOG = logging.getLogger(__name__)

@engine.configure(name="ExistingCloud")
class ExistingCloud(engine.Engine):
    """Platform independent deployment engine.

    This deployment engine allows specifing list of credentials for one
    or more platforms.

    Example configuration:

    .. code-block:: json

        {
            "type": "ExistingCloud",
            "creds": {
                "openstack": {
                    "auth_url": "http://localhost:5000/v3/",
                    "region_name": "RegionOne",
                    "endpoint_type": "public",
                    "admin": {
                        "username": "admin",
                        "password": "admin",
                        "user_domain_name": "admin",
                        "project_name": "admin",
                        "project_domain_name": "admin",
                    },
                    "https_insecure": False,
                    "https_cacert": "",
                }
            }
        }

    To specify extra options use can use special "extra" parameter:

    .. code-block:: json

        {
            "type": "ExistingCloud",
            ...
            "extra": {"some_var": "some_value"}
        }

    It also support deprecated version of configuration that supports
    only OpenStack.

    keystone v2:

    .. code-block:: json

        {
            "type": "ExistingCloud",
            "auth_url": "http://localhost:5000/v2.0/",
            "region_name": "RegionOne",
            "endpoint_type": "public",
            "admin": {
                "username": "admin",
                "password": "password",
                "tenant_name": "demo"
            },
            "https_insecure": False,
            "https_cacert": "",
        }

    keystone v3 API endpoint:

    .. code-block:: json

        {
            "type": "ExistingCloud",
            "auth_url": "http://localhost:5000/v3/",
            "region_name": "RegionOne",
            "endpoint_type": "public",
            "admin": {
                "username": "admin",
                "password": "admin",
                "user_domain_name": "admin",
                "project_name": "admin",
                "project_domain_name": "admin",
            },
            "https_insecure": False,
            "https_cacert": "",
        }

    """

    USER_SCHEMA = {
        "type": "object",
        "oneOf": [
            {
                "description": "Keystone V2.0",
                "properties": {
                    "username": {"type": "string"},
                    "password": {"type": "string"},
                    "tenant_name": {"type": "string"},
                },
                "required": ["username", "password", "tenant_name"],
                "additionalProperties": False
            },
            {
                "description": "Keystone V3.0",
                "properties": {
                    "username": {"type": "string"},
                    "password": {"type": "string"},
                    "domain_name": {"type": "string"},
                    "user_domain_name": {"type": "string"},
                    "project_name": {"type": "string"},
                    "project_domain_name": {"type": "string"},
                },
                "required": ["username", "password", "project_name"],
                "additionalProperties": False
            }
        ],
    }

    OLD_CONFIG_SCHEMA = {
        "type": "object",
        "description": "Deprecated schema (openstack only)",
        "properties": {
            "type": {"type": "string"},
            "auth_url": {"type": "string"},
            "region_name": {"type": "string"},
            # NOTE(andreykurilin): it looks like we do not use endpoint
            # var at all
            "endpoint": {"type": ["string", "null"]},
            "endpoint_type": {"enum": [consts.EndpointType.ADMIN,
                                       consts.EndpointType.INTERNAL,
                                       consts.EndpointType.PUBLIC,
                                       None]},
            "https_insecure": {"type": "boolean"},
            "https_cacert": {"type": "string"},
            "profiler_hmac_key": {"type": ["string", "null"]},
            "admin": USER_SCHEMA,
            "users": {"type": "array", "items": USER_SCHEMA, "minItems": 1},
            "extra": {"type": "object", "additionalProperties": True}
        },
        "anyOf": [
            {"description": "The case when the admin is specified and the "
                            "users can be created via 'users' context or "
                            "'existing_users' will be used.",
             "required": ["type", "auth_url", "admin"]},
            {"description": "The case when the only existing users are "
                            "specified.",
             "required": ["type", "auth_url", "users"]}
        ],
        "additionalProperties": False
    }

    NEW_CONFIG_SCHEMA = {
        "type": "object",
        "description": "New schema for multiplatform deployment",
        "properties": {
            "type": {"enum": ["ExistingCloud"]},
            "creds": {
                "type": "object",
                "patternProperties": {
                    "^[a-z0-9_-]+$": {
                        "oneOf": [
                            {
                                "description": "Single credential",
                                "type": "object"
                            },
                            {
                                "description": "List of credentials",
                                "type": "array",
                                "items": {"type": "object"},
                                "maxItems": 1,
                            },
                        ]
                    }
                }
            },
            "extra": {"type": "object", "additionalProperties": True}
        },
        "required": ["type", "creds"],
        "additionalProperties": False
    }

    CONFIG_SCHEMA = {"type": "object",
                     "oneOf": [OLD_CONFIG_SCHEMA, NEW_CONFIG_SCHEMA]}

    def validate(self, config=None):
        config = config or self.config
        super(ExistingCloud, self).validate(config)

        creds_config = self._get_creds(config)
        for platform, config in creds_config.items():
            builder_cls = credential.get_builder(platform)
            for creds in config:
                builder_cls.validate(creds)

    def _get_creds(self, config):
        # NOTE(astudenov): copy config to prevent compatibility changes
        # from saving to database
        config = copy.deepcopy(config)
        if "creds" not in config:
            # backward compatibility with old schema
            del config["type"]
            creds_config = {"openstack": [config]}
        else:
            creds_config = config["creds"]

        # convert all credentials to list
        for platform, config in creds_config.items():
            if isinstance(config, dict):
                creds_config[platform] = [config]
        return creds_config

    def make_deploy(self):
        platforms = (["openstack"] if "creds" not in self.config
                     else self.config["creds"].keys())
        LOG.info("Save deployment '%(name)s' (uuid=%(uuid)s) with "
                 "'%(platforms)s' platform%(plural)s." %
                 {"name": self.deployment["name"],
                  "uuid": self.deployment["uuid"],
                  "platforms": "', '".join(platforms),
                  "plural": "s" if len(platforms) > 1 else ""})
        self.deployment.set_started()
        credentials = self.deploy()
        self.deployment.set_completed()
        return credentials

    def deploy(self):
        creds_config = self._get_creds(self.config)
        parsed_credentials = {}
        for platform, config in creds_config.items():
            builder_cls = credential.get_builder(platform)
            credentials = []
            for creds in config:
                builder = builder_cls(creds)
                credentials.append(builder.build_credentials())
            parsed_credentials[platform] = credentials
        return parsed_credentials

    def cleanup(self):
        pass


text:
cd /d %~dp0
copy %1 "bin\copyPasteToVisibleCellsOnly%~x1"
rem pause

DEcombine.bat

pause


text:
/**
 * Getter/Setter
 *
 * @author Alberto Arena <arena.alberto@gmail.com>
 * @licence MIT https://github.com/albertoarena/gettersetter/blob/master/LICENSE-MIT
 *
 */
define([], function () {
    return function (initValue, callback) {
        var val = initValue;
        if (typeof callback != 'function') {
            callback = null;
        }
        return function (v) {
            if (v !== undefined) {
                val = v;
                if (callback) {
                    callback(v);
                }
            }
            return val;
        };
    };
});


text:
package com.lewisd.ksp.craftstats.cfg;

public class CfgRawLine implements CfgLine {

    private String line;

    public CfgRawLine() {
    }

    public CfgRawLine(String line) {
        this.line = line;
    }

    @Override
    public String getLine() {
        return line;
    }
    @Override
    public void setLine(String line) {
        this.line = line;
    }

}


text:
To celebrate pi day and to get a little more public in the clustering community when it comes to raspberry pi, I am putting together a raspberry pi cluster which will be live come pi day! If you have any suggestions, let hear em. If you wanna copy this and be on your way, so be it! Just know my stuff evolves fast so keep an eye on the repo after you do. :)

### Layout of this repo

This repo is split into two sections to make it so those who just want the deatils on one side of the build can have what they need and leave but also to make a clean seperation of the two pieces of nature that is this computer science project.

### The hardware side

This is the section where the schematics will be going for how things are being powered, how things are wired, reasoning behind it and how I built some of the pieces. It will also have the details on what I bought and where I bought it in order to give you a better idea on exactly how you can do this too.

### The software side

The design of this cluster is a headless one. I've seen a lot of schematics of "clusters" where there was one load balancer and a ton of servers behind it, this is not one of those. I wanted to create an architecture that offered just as many access points as it added points where things could be processed. I'll include illustrations in how I did that as this project goes on.

---

### Current Overview

##### Software

| role     | name     |
|----------|----------|
| server   | cherrypy |
| database | couchdb  |

##### Hardware
![](https://github.com/CodyKochmann/pi-cluster/raw/master/hardware/pictures/version_0.1.jpg)


text:
- The `Daily Threat Feed` option has been removed since it is deprecated.
- Updated the Docker image to: *demisto/python3:3.10.4.27798*.

##### AutoFocus Daily Feed (Deprecated)
- Documentation fixes.


text:
<?php

namespace Pobl\Bongo;

use \Illuminate\Support\ServiceProvider;
use \Pobl\Bongo\Model;

class LaravelServiceProvider extends ServiceProvider
{

    public function boot()
    {
        //Publish the config
        $this->publishes([
            __DIR__ . '/config/laravel.php' => config_path('bongo.php')
        ]);
    }

    public function register()
    {
        //Merge config with default values
        $this->mergeConfigFrom(
            __DIR__ . '/config/laravel.php', 'bongo'
        );

        $this->app->booted(function() {
            $config = $this->app['config']['bongo']['connections'][$this->app['config']['bongo']['default']];
            $dsn = 'mongodb://' . ($config['username'] !== '' ? ($config['username']
                    . ':' . $config['password']) . '@' : '')
                    . $config['host'] . ':'
                    . $config['port'];
            $bongo = new Client($dsn);
            $bongo->useDatabase($config['database']);
            Model::setDefaultConnection($bongo);
        });
    }

}


text:
export PATH=$PATH:/opt/chef/embedded/bin/
cd /tmp/devenv
berks vendor /etc/chef/cookbooks/
chef-solo


text:
class Collision;

//! This class stores information for an Object in the game.
class Object {
private:
  Image img;
  Input i;
  SDL_Rect frame, dest, pos, buff, movedBuff;
  double angle;
  string name;
  double x, y, velX, velY, speed;
  bool displayable;
  bool gravity;
  bool objsImage;
  struct color { Uint8 r, g, b, a; };
  color objsColor;
public:
  Object();
  ~Object();
  SDL_Rect getBuff() const {return buff;}
  SDL_Rect getMovedBuff() const {return movedBuff;}
  void actGravity(bool g) {gravity=g;}
  //! This sets if you want the Object to visible on the screen by passing in a boolean.
  void setDisplayable(bool d) { displayable = d; }
  //! Check if the Object is displayable by seeing if it is in a given screen.
  bool isDisplayable(Object screen) { checkDisplayable(screen); return displayable; }
  //! Checks if the Object is in the given screen.
  virtual void checkDisplayable(Object screen);
  //! Set the coordinate of the Object with a given x and y.
  void setCoord(double x, double y) { setX(x); setY(y); }
  //! Set the x coordinate with a given x.
  void setX(double sx) { x = sx; }
  //! Set the y coordinate with a given y.
  void setY(double sy) { y = sy; }
  //! Move along the x and y coordinate with a given x and y amount.
  void move(double x, double y) { moveX(x); moveY(y); }
  //! Move along the x coordinate with a given x amount.
  void moveX(double mx) { x += mx; }
  //! Move along the y coordinate with a given y amount.
  void moveY(double my) { y += my; }
  //! Get the current x coordinate.
  double getX() const { return x; }
  //! Get the current y coordinate.
  double getY() const { return y; }
  //! Get the Object's Image.
  Image getImage() const { return img; }
  //! Set the Object's Image with a given Image.
  void setImage(Image i) { img = i; objsImage=true; }
  //! Give the path and renderer to create the Object's Image.
  void setImage(string file, SDL_Renderer* ren) { img.loadImage(file, ren); objsImage=true; }
  //! Get the Object's angle.
  double getAngle() const { return angle; }
  //! Set the angle.
  void setAngle(double a) { angle = a; }
  //! Center the Object based on a width and height.
  void center(int w, int h);
  //! Get the frame that the Object parses from the Image.
  SDL_Rect getFrame() const { return frame; }
  //! Get the destination for the Object to be displayed on screen.
  SDL_Rect getDest() const { return dest; }
  //! Get the position of the Object in the world.
  SDL_Rect getPos() const { return pos; }
  //! Set the frame with a given SDL_Rect.
  void setFrame(SDL_Rect i) { frame = i; }
  //! Set the destination with a given SDL_Rect.
  void setDest(SDL_Rect i) { buff=dest; if(movedBuff.x!=buff.x && movedBuff.y!=buff.y) {movedBuff=buff;} dest = i; }
  //! Set the position with a given SDL_Rect.
  void setPos(SDL_Rect i) { pos = i; }
  //! Set the frame with a given x and y coordinate and width and height.
  void setFrame(int x, int y, int w, int h) { setFrameCoord(x, y); setFrameSize(w, h); }
  //! Set the x and y coordinate of the frame.
  void setFrameCoord(int x, int y) { setFrameX(x); setFrameY(y); }
  //! Set the size of the frame with a width and height.
  void setFrameSize(int w, int h) { setFrameW(w); setFrameH(h); }
  //! Set the x coordinate of the frame.
  void setFrameX(int x) { frame.x = x; }
  //! Set the object's velocity toward another object
  void setVelTo(Object o);
  //!Set the object's angle towards another object.
  void lookAt(Object o);
  //! Set the y coordinate of the frame.
  void setFrameY(int y) { frame.y = y; }
  void setFrameW(int w) { frame.w = w; }
  void setFrameH(int h) { frame.h = h; }
  int getFrameX() const { return frame.x; }
  int getFrameY() const { return frame.y; }
  int getFrameW() const { return frame.w; }
  int getFrameH() const { return frame.h; }
  void setDest(int x, int y, int w, int h) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} setDestCoord(x, y); setDestSize(w, h); }
  void setDestCoord(int x, int y) { setDestX(x); setDestY(y); }
  void setDestSize(int w, int h) { setDestW(w); setDestH(h); }
  void setDestX(int x) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.x = x; }
  void setDestY(int y) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.y = y; }
  void setDestW(int w) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.w = w; }
  void setDestH(int h) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.h = h; }
  int getDestX() const { return dest.x; }
  int getDestY() const { return dest.y; }
  int getDestW() const { return dest.w; }
  int getDestH() const { return dest.h; }
  void setPos(int x, int y, int w, int h) { setPosCoord(x, y); setPosSize(w, h); }
  void setPosCoord(int x, int y) { setPosX(x); setPosY(y); }
  void setPosSize(int w, int h) { setPosW(w); setPosH(h); }
  void setPosX(int x) { pos.x = x; }
  void setPosY(int y) { pos.y = y; }
  void setPosW(int w) { pos.w = w; }
  void setPosH(int h) { pos.h = h; }
  int getPosX() const { return pos.x; }
  int getPosY() const { return pos.y; }
  int getPosW() const { return pos.w; }
  int getPosH() const { return pos.h; }
  void moveFrame(int x, int y) { moveFrameX(x); moveFrameY(y); }
  void moveFrameX(int x) { frame.x += x; }
  void moveFrameY(int y) { frame.y += y; }
  void moveDest(int x, int y) { moveDestX(x); moveDestY(y); }
  void moveDestX(int x) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.x += x; }
  void moveDestY(int y) { buff=dest; if(movedBuff.x!=buff.x || movedBuff.y!=buff.y) {movedBuff=buff;} dest.y += y; }
  void movePos(int x, int y) { movePosX(x); movePosY(y); }
  void movePosX(int x) { pos.x += x; }
  void movePosY(int y) { pos.y += y; }
  double getVelX() { return velX; }
  double getVelY() { return velY; }
  void setVelX(double vx) { velX = vx; }
  void setVelY(double vy) { velY = vy; }
  void setVelTo(int x, int y);
  double getSpeed() {  return speed; }
  void setSpeed(double s) { speed = s; }
  void setName(string s);
  string getName();
  void centerOn(Input i);
  void centerOn(int cx, int cy);
  void centerOn(Object obj);
  void lookAt(Input i);
  color red = {0xff,0,0,0xff};
  color green = {0,0xff,0,0xff};
  color blue = {0,0,0xff,0xff};
  void setColor(color c) {objsColor = c;}
  void setColor(Uint8 r, Uint8 g, Uint8 b) {objsColor.r=r;objsColor.g=g;objsColor.b=b;}
  void setTransparency(Uint8 a) {objsColor.a = a;}
  bool imageSet() const {return objsImage;}
  color getColor() const {return objsColor;}
  void rotateAngle(int rot);
  void moveToVel();
};

#endif //OBJECT_H


text:
<!DOCTYPE html>

<title> CUFA: HTML, CSS, DOM </title>
<link rel="stylesheet" href="../styles/main.css">

          About

               Enspiral Dev Academy
               Joshua Fogg

Home

 Javascript vs HTML and CSS:

 If we were to compare HTML and CSS  to Javascript using a motorbike as an example. HTML and CSS would be the bikes overall look and style and build. Javascript however would be the light switches, electronics, steering and gear system,. These are all points where the user can interact with the bike and generate a change in behaviour from the bike. Javascript druves interaction and changes in behaviour, allowing a rich interaction with the user.

  So within website Javascript allows the creation of loops and functions, data capabilities and a more refined user experience.
  Although Javascript has these benefits, it requires a more demanding and variable syntax than HTML and CSS, as it must differntiate between a wider variety of instructions in its script. It is for this rea reason that Javascript can feel like HTML and CSS's uptight friend who likes to throw in the towel if your diction or syntax are even slightly off.

 * HTML gives a structure
 *   CSS allows for style and design
 *Javascript allows programmers to create unique and interactive experiences

Control Flow and Loops:

  Control Flow is an important concept in computer science, it is the order in which individual statements, instructions or functions are looked at and executed.

Imagine that before you went to bed each night, you wrote a list of things to do the next day after you wake up. This list included activities like brushing your teeth, getting dressed, having breakfast and heading to work.

  Now if you were to write these in a radom order you may end up dressing once you have left the house. However if you were to prioritise these activities then you could ensure you don't rock up to work without first being ready for the day.

  This prioritisation is '' Control Flow", it causes priorities and order for computers that are working through a script of instructions.

  Loops are a type of code that will repeat until interrrupted or told to stop. Loops are great for  reducing the amount of coding required to do the same steps. Loops give an efficient way to reduce the amount of code needed to repeat certain steps.

  For instance in the previous example a coding loop would be the equivalent of writing out a list once and knowing to re-follow the same list each day, possibly with a few adjustments over teh day to day. So rather than writing a new list each night you could write out a list once and use it each day.

Data Accessing from Arrays and Objects:

Javascript utilises "Objects" and "Arrays", both of which can hold different forms of data. Objects are a variable that can hold defined data lists, for example an object variable  called car can hold data for the car type, model and colour:

  var car = {type:"Fiat", model:"500", color:"white"};

    Accessing object data can be done by calling the object's properties or Key-values. Using the above example you could access it's data with the following:

  car.model or car["model"]

    Arrays can be used to store multiple values in a single variable. Arrays can be nestled also, allowing multiple bits of data to be stored relative to a value.

    var car = ["Fiat", 500, "White"];

    Array data can be accessed by using the zero based numeric index, which value starts at [0] for the data entry.

  cars[0]; which would return "Fiat"

Additionally, object data can be accessed using dot notation and bracket notation. Arrays rely solely on bracket notation.

Functions:

Functions are a type of coding structure that allow for variables and values to be taken in, computed, calculated, altered and returned to the user or input. The input and logical method are stored within a block of code.

 Functions are great for repeating steps.

why

 Back to the Top


text:
module Openlab
  class Projects
    PROJECTS_PATH = '/projects'

    attr_accessor :client

    def initialize(client = nil)
      @client = client || Openlab::Client.new
    end

    def search(q, opts = {})
      client.get(path, query: { q: q }.merge(opts))
    end

    def create(attributes)
      client.post(path, body: { project: attributes })
    end

    def update(id, attributes)
      client.patch("#{path}/#{id}", body: { project: attributes })
    end

    def destroy(id)
      client.delete("#{path}/#{id}")
    end

    private
      def path
        "#{Openlab.config.api_version_path}#{PROJECTS_PATH}"
      end
  end
end


text:
<?php
/**
 * Created by PhpStorm.
 * User: stas
 * Date: 03.05.16
 * Time: 18:35
 */

namespace CoreBundle\DataFixtures\ORM;

use CoreBundle\Entity\ChatMessage;
use CoreBundle\Entity\User;
use CoreBundle\Model\ChatMessage\ChatMessageType;

/**
 * Class ChatFixtures
 * @package CoreBundle\DataFixtures\ORM
 */
class ChatFixtures extends AbstractPlayzoneFixtures
{

    /**
     * @param array $data
     * @return mixed
     */
    protected function createEntity($data)
    {
        $chatMessage = $this->container->get("core.handler.chat")->createEntity($data["time"]);

        /** @var User $user */
        $user = $this->getReference($data["user"]);

        $chatMessage->setMessage($data["message"])
                    ->setType(new ChatMessageType($data["type"]))
                    ->setUser($user);

        return $chatMessage;
    }

    /**
     * Get the order of this fixture
     *
     * @return integer
     */
    public function getOrder()
    {
        return 120;
    }
}


text:
namespace dynet {

class Dict {
typedef std::unordered_map<std::string, int> Map;
public:
  Dict() : frozen(false), map_unk(false), unk_id(-1) {
  }

  inline unsigned size() const { return (unsigned)words_.size(); }

  inline bool contains(const std::string& words) const {
    return !(d_.find(words) == d_.end());
  }

  void freeze() { frozen = true; }
  bool is_frozen() const { return frozen; }

  inline int convert(const std::string& word) {
    auto i = d_.find(word);
    if (i == d_.end()) {
      if (frozen) {
        if (map_unk)
          return unk_id;
        else
          DYNET_RUNTIME_ERR("Unknown word encountered in frozen dictionary: " << word);
      }
      words_.push_back(word);
      return d_[word] = (int)words_.size() - 1;
    } else {
      return i->second;
    }
  }

  inline const std::string& convert(const int& id) const {
    DYNET_ARG_CHECK(id < (int)words_.size(),
                            "Out-of-bounds error in Dict::convert for word ID " << id <<
                            " (dict size: " << words_.size() << ")");
    return words_[id];
  }

  void set_unk(const std::string& word) {
    if (!frozen)
      DYNET_RUNTIME_ERR("Please call set_unk() only after dictionary is frozen");
    if (map_unk)
      DYNET_RUNTIME_ERR("Set UNK more than one time");

    // temporarily unfreeze the dictionary to allow the addition of the UNK
    frozen = false;
    unk_id = convert(word);
    frozen = true;

    map_unk = true;
  }

  int get_unk_id() const { return unk_id; }
  const std::vector<std::string> & get_words() const { return words_; }

  void clear() { words_.clear(); d_.clear(); }

protected:
  bool frozen;
  bool map_unk; // if true, map unknown word to unk_id
  int unk_id;
  std::vector<std::string> words_;
  Map d_;
};

std::vector<int> read_sentence(const std::string& line, Dict& sd);
void read_sentence_pair(const std::string& line, std::vector<int>& s, Dict& sd, std::vector<int>& t, Dict& td);

} // namespace dynet

#endif


text:
/**
 * @author Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include "mag.hpp"

#include <drivers/drv_hrt.h>
#include <systemlib/err.h>

const char *const UavcanMagnetometerBridge::NAME = "mag";

UavcanMagnetometerBridge::UavcanMagnetometerBridge(uavcan::INode &node) :
	UavcanCDevSensorBridgeBase("uavcan_mag", "/dev/uavcan/mag", MAG_BASE_DEVICE_PATH, ORB_ID(sensor_mag)),
	_sub_mag(node)
{
	_device_id.devid_s.devtype = DRV_MAG_DEVTYPE_HMC5883;     // <-- Why?

	_scale.x_scale = 1.0F;
	_scale.y_scale = 1.0F;
	_scale.z_scale = 1.0F;
}

int UavcanMagnetometerBridge::init()
{
	int res = device::CDev::init();

	if (res < 0) {
		return res;
	}

	res = _sub_mag.start(MagCbBinder(this, &UavcanMagnetometerBridge::mag_sub_cb));

	if (res < 0) {
		DEVICE_LOG("failed to start uavcan sub: %d", res);
		return res;
	}

	return 0;
}

ssize_t UavcanMagnetometerBridge::read(struct file *filp, char *buffer, size_t buflen)
{
	static uint64_t last_read = 0;
	struct mag_report *mag_buf = reinterpret_cast<struct mag_report *>(buffer);

	/* buffer must be large enough */
	unsigned count = buflen / sizeof(struct mag_report);

	if (count < 1) {
		return -ENOSPC;
	}

	if (last_read < _report.timestamp) {
		/* copy report */
		lock();
		*mag_buf = _report;
		last_read = _report.timestamp;
		unlock();
		return sizeof(struct mag_report);

	} else {
		/* no new data available, warn caller */
		return -EAGAIN;
	}
}

int UavcanMagnetometerBridge::ioctl(struct file *filp, int cmd, unsigned long arg)
{
	switch (cmd) {
	case SENSORIOCSQUEUEDEPTH: {
			return OK;			// Pretend that this stuff is supported to keep APM happy
		}

	case MAGIOCSSCALE: {
			std::memcpy(&_scale, reinterpret_cast<const void *>(arg), sizeof(_scale));
			return 0;
		}

	case MAGIOCGSCALE: {
			std::memcpy(reinterpret_cast<void *>(arg), &_scale, sizeof(_scale));
			return 0;
		}

	case MAGIOCSELFTEST: {
			return 0;           // Nothing to do
		}

	case MAGIOCGEXTERNAL: {
			return 1;           // declare it external rise it's priority and to allow for correct orientation compensation
		}

	case MAGIOCSSAMPLERATE: {
			return 0;           // Pretend that this stuff is supported to keep the sensor app happy
		}

	case MAGIOCCALIBRATE:
	case MAGIOCGSAMPLERATE:
	case MAGIOCSRANGE:
	case MAGIOCGRANGE:
	case MAGIOCSLOWPASS:
	case MAGIOCEXSTRAP:
	case MAGIOCGLOWPASS: {
			return -EINVAL;
		}

	default: {
			return CDev::ioctl(filp, cmd, arg);
		}
	}
}

void UavcanMagnetometerBridge::mag_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::ahrs::MagneticFieldStrength>
		&msg)
{
	lock();
	_report.range_ga = 1.3F;   // Arbitrary number, doesn't really mean anything
	/*
	 * FIXME HACK
	 * This code used to rely on msg.getMonotonicTimestamp().toUSec() instead of HRT.
	 * It stopped working when the time sync feature has been introduced, because it caused libuavcan
	 * to use an independent time source (based on hardware TIM5) instead of HRT.
	 * The proper solution is to be developed.
	 */
	_report.timestamp = hrt_absolute_time();

	_report.x = (msg.magnetic_field_ga[0] - _scale.x_offset) * _scale.x_scale;
	_report.y = (msg.magnetic_field_ga[1] - _scale.y_offset) * _scale.y_scale;
	_report.z = (msg.magnetic_field_ga[2] - _scale.z_offset) * _scale.z_scale;
	unlock();

	publish(msg.getSrcNodeID().get(), &_report);
}