text:
import os

SITES = os.path.join(os.getcwd(), 'sites')
denied_extension = ['jpg', 'jpeg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'txt', 'ppt', 'pptx']

def is_allowed(filename):
    for ext in denied_extension:
        if filename.endswith(ext):
            return False
    return True

def create_site_dir(dir_name):
    print('spiders.__init__: %s' % os.getcwd())
    dir_path = os.path.join(SITES, dir_name)
    if not os.path.exists(dir_path):
        try:
            os.mkdir(dir_path, 0755)
            return dir_path
        except IOError:
            print('Site directory error!!')
    else:
        raise Exception('Site is exist!!')

redpajama_set_name: RedPajamaGithub


text:
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed 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.
// ----------------------------------------------------------------------------------

namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets
{
    /// <summary>
    /// Constants used by Job Cmdlets
    /// </summary>
    public class JobConstants
    {
        public const int MaximumJobsToFetch = 1000;
    }

    /// <summary>
    /// Constants used by Policy Cmdlets
    /// </summary>
    public class PolicyConstants
    {
        public const int MinPolicyNameLength = 3;
        public const int MaxPolicyNameLength = 150;
    }

    public class ContainerConstansts
    {
        public const string SqlContainerNamePrefix = "AzureSqlContainer;";
    }
}


text:
@implementation EBPurchase

@synthesize delegate;
@synthesize validProduct;

-(bool) requestProduct:(NSString*)productId
{
    if (productId != nil) {

        NSLog(@"EBPurchase requestProduct: %@", productId);

        if ([SKPaymentQueue canMakePayments]) {
            // Yes, In-App Purchase is enabled on this device.
            // Proceed to fetch available In-App Purchase items.

            // Initiate a product request of the Product ID.
            SKProductsRequest *prodRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productId]];
            prodRequest.delegate = self;
            [prodRequest start];
            [prodRequest release];

            return YES;

        } else {
            // Notify user that In-App Purchase is Disabled.

            NSLog(@"EBPurchase requestProduct: IAP Disabled");
            return NO;
        }

    } else {

        NSLog(@"EBPurchase requestProduct: productId = NIL");
       return NO;
    }

}

-(bool) purchaseProduct:(SKProduct*)requestedProduct
{
    if (requestedProduct != nil) {

        NSLog(@"EBPurchase purchaseProduct: %@", requestedProduct.productIdentifier);

        if ([SKPaymentQueue canMakePayments]) {
            // Yes, In-App Purchase is enabled on this device.
            // Proceed to purchase In-App Purchase item.

            // Assign a Product ID to a new payment request.
            SKPayment *paymentRequest = [SKPayment paymentWithProduct:requestedProduct];

            // Assign an observer to monitor the transaction status.
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

            // Request a purchase of the product.
            [[SKPaymentQueue defaultQueue] addPayment:paymentRequest];
            NSLog(@"this is runing");
            return YES;

        } else {
            // Notify user that In-App Purchase is Disabled.

            NSLog(@"EBPurchase purchaseProduct: IAP Disabled");

            return NO;
        }

    } else {

        NSLog(@"EBPurchase purchaseProduct: SKProduct = NIL");

        return NO;
    }
}

-(bool) restorePurchase
{
    NSLog(@"EBPurchase restorePurchase");

    if ([SKPaymentQueue canMakePayments]) {
        // Yes, In-App Purchase is enabled on this device.
        // Proceed to restore purchases.

        // Assign an observer to monitor the transaction status.
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

        // Request to restore previous purchases.
        [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

        return YES;

    } else {
        // Notify user that In-App Purchase is Disabled.

        return NO;
    }
}

#pragma mark -
#pragma mark SKProductsRequestDelegate Methods

// Store Kit returns a response from an SKProductsRequest.
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

	// Parse the received product info.
	self.validProduct = nil;
	int count = [response.products count];
	if (count>0) {
        // Grab the first product in the array.
		self.validProduct = [response.products objectAtIndex:0];
	}
	if (self.validProduct) {
        // Yes, product is available, so return values.

		[delegate requestedProduct:self identifier:self.validProduct.productIdentifier name:self.validProduct.localizedTitle price:[self.validProduct.price stringValue] description:self.validProduct.localizedDescription];

	} else {
        // No, product is NOT available, so return nil values.

		[delegate requestedProduct:self identifier:nil name:nil price:nil description:nil];
    }
}

#pragma mark -
#pragma mark SKPaymentTransactionObserver Methods

// The transaction status of the SKPaymentQueue is sent here.
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
	for(SKPaymentTransaction *transaction in transactions) {
		switch (transaction.transactionState) {

			case SKPaymentTransactionStatePurchasing:
				// Item is still in the process of being purchased

				break;

			case SKPaymentTransactionStatePurchased:
				// Item was successfully purchased!

				// Return transaction data. App should provide user with purchased product.

                [delegate successfulPurchase:self identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];

				// After customer has successfully received purchased content,
				// remove the finished transaction from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;

			case SKPaymentTransactionStateRestored:
				// Verified that user has already paid for this item.
				// Ideal for restoring item across all devices of this customer.

				// Return transaction data. App should provide user with purchased product.

                [delegate successfulPurchase:self identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];

				// After customer has restored purchased content on this device,
				// remove the finished transaction from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;

			case SKPaymentTransactionStateFailed:
				// Purchase was either cancelled by user or an error occurred.

				if (transaction.error.code != SKErrorPaymentCancelled) {
					// A transaction error occurred, so notify user.

                    [delegate failedPurchase:self error:transaction.error.code message:transaction.error.localizedDescription];
				}
				// Finished transactions should be removed from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
		}
	}
}

// Called when one or more transactions have been removed from the queue.
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
    NSLog(@"EBPurchase removedTransactions");

    // Release the transaction observer since transaction is finished/removed.
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

// Called when SKPaymentQueue has finished sending restored transactions.
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {

    NSLog(@"EBPurchase paymentQueueRestoreCompletedTransactionsFinished");

    if ([queue.transactions count] == 0) {
        // Queue does not include any transactions, so either user has not yet made a purchase
        // or the user's prior purchase is unavailable, so notify app (and user) accordingly.

        NSLog(@"EBPurchase restore queue.transactions count == 0");

        // Release the transaction observer since no prior transactions were found.
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

//        [delegate incompleteRestore:self];
        [delegate successfulRestore:self purchasedList:[NSMutableArray array]];
    } else {
        // Queue does contain one or more transactions, so return transaction data.
        // App should provide user with purchased product.

        NSLog(@"EBPurchase restore queue.transactions available");

        NSMutableArray* purchased = [NSMutableArray array];
        for(SKPaymentTransaction *transaction in queue.transactions) {

            NSLog(@"EBPurchase restore queue.transactions - transaction data found");
            [purchased addObject:transaction.payment.productIdentifier];
//            [delegate successfulPurchase:self identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];
        }
        if(purchased.count > 0) {
            [delegate successfulRestore:self purchasedList:purchased];
        }
    }
}

// Called if an error occurred while restoring transactions.
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
    // Restore was cancelled or an error occurred, so notify user.

    NSLog(@"EBPurchase restoreCompletedTransactionsFailedWithError");

    [delegate failedRestore:self error:error.code message:error.localizedDescription];
}

#pragma mark - Internal Methods & Events

- (void)dealloc
{
    [validProduct release];
    [delegate release];

    [super dealloc];
}

@end


text:
import cr, utils
from urlparse import urlparse

url = 'http://www.beeradvocate.com'
base_urls = [urlparse(url).netloc]
spider = cr.Spider(url, base_urls, 'beer.db', 0.1, '/beer')
spider.nstep(100000)
utils.combine('beer.db')


text:
package com.amazonaws.services.identitymanagement.model;
import com.amazonaws.AmazonWebServiceRequest;

/**
 * Container for the parameters to the {@link com.amazonaws.services.identitymanagement.AmazonIdentityManagement#createInstanceProfile(CreateInstanceProfileRequest) CreateInstanceProfile operation}.
 *

 * Creates a new instance profile. For information about instance profiles, go to  About Instance Profiles  .
 *

 *

 * For information about the number of instance profiles you can create, see  Limitations on IAM Entities  in Using AWS
 * Identity and Access Management .
 *

 *
 * @see com.amazonaws.services.identitymanagement.AmazonIdentityManagement#createInstanceProfile(CreateInstanceProfileRequest)
 */
public class CreateInstanceProfileRequest extends AmazonWebServiceRequest {

    /**
     * Name of the instance profile to create.
     *

     * Constraints:

     * Length: 1 - 128

     * Pattern: [\w+=,.@-]*

     */
    private String instanceProfileName;

    /**
     * The path to the instance profile. For more information about paths,
     * see Identifiers for IAM Entities in Using AWS
     * Identity and Access Management.
This parameter is optional. If
     * it is not included, it defaults to a slash (/).
     *

     * Constraints:

     * Length: 1 - 512

     * Pattern: (\u002F)|(\u002F[\u0021-\u007F]+\u002F)

     */
    private String path;

    /**
     * Name of the instance profile to create.
     *

     * Constraints:

     * Length: 1 - 128

     * Pattern: [\w+=,.@-]*

     *
     * @return Name of the instance profile to create.
     */
    public String getInstanceProfileName() {
        return instanceProfileName;
    }

    /**
     * Name of the instance profile to create.
     *

     * Constraints:

     * Length: 1 - 128

     * Pattern: [\w+=,.@-]*

     *
     * @param instanceProfileName Name of the instance profile to create.
     */
    public void setInstanceProfileName(String instanceProfileName) {
        this.instanceProfileName = instanceProfileName;
    }

    /**
     * Name of the instance profile to create.
     *

     * Returns a reference to this object so that method calls can be chained together.
     *

     * Constraints:

     * Length: 1 - 128

     * Pattern: [\w+=,.@-]*

     *
     * @param instanceProfileName Name of the instance profile to create.
     *
     * @return A reference to this updated object so that method calls can be chained
     *         together.
     */
    public CreateInstanceProfileRequest withInstanceProfileName(String instanceProfileName) {
        this.instanceProfileName = instanceProfileName;
        return this;
    }

    /**
     * The path to the instance profile. For more information about paths,
     * see Identifiers for IAM Entities in Using AWS
     * Identity and Access Management.
This parameter is optional. If
     * it is not included, it defaults to a slash (/).
     *

     * Constraints:

     * Length: 1 - 512

     * Pattern: (\u002F)|(\u002F[\u0021-\u007F]+\u002F)

     *
     * @return The path to the instance profile. For more information about paths,
     *         see Identifiers for IAM Entities in Using AWS
     *         Identity and Access Management.
This parameter is optional. If
     *         it is not included, it defaults to a slash (/).
     */
    public String getPath() {
        return path;
    }

    /**
     * The path to the instance profile. For more information about paths,
     * see Identifiers for IAM Entities in Using AWS
     * Identity and Access Management.
This parameter is optional. If
     * it is not included, it defaults to a slash (/).
     *

     * Constraints:

     * Length: 1 - 512

     * Pattern: (\u002F)|(\u002F[\u0021-\u007F]+\u002F)

     *
     * @param path The path to the instance profile. For more information about paths,
     *         see Identifiers for IAM Entities in Using AWS
     *         Identity and Access Management.
This parameter is optional. If
     *         it is not included, it defaults to a slash (/).
     */
    public void setPath(String path) {
        this.path = path;
    }

    /**
     * The path to the instance profile. For more information about paths,
     * see Identifiers for IAM Entities in Using AWS
     * Identity and Access Management.
This parameter is optional. If
     * it is not included, it defaults to a slash (/).
     *

     * Returns a reference to this object so that method calls can be chained together.
     *

     * Constraints:

     * Length: 1 - 512

     * Pattern: (\u002F)|(\u002F[\u0021-\u007F]+\u002F)

     *
     * @param path The path to the instance profile. For more information about paths,
     *         see Identifiers for IAM Entities in Using AWS
     *         Identity and Access Management.
This parameter is optional. If
     *         it is not included, it defaults to a slash (/).
     *
     * @return A reference to this updated object so that method calls can be chained
     *         together.
     */
    public CreateInstanceProfileRequest withPath(String path) {
        this.path = path;
        return this;
    }

    /**
     * Returns a string representation of this object; useful for testing and
     * debugging.
     *
     * @return A string representation of this object.
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        if (instanceProfileName != null) sb.append("InstanceProfileName: " + instanceProfileName + ", ");
        if (path != null) sb.append("Path: " + path + ", ");
        sb.append("}");
        return sb.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int hashCode = 1;

        hashCode = prime * hashCode + ((getInstanceProfileName() == null) ? 0 : getInstanceProfileName().hashCode());
        hashCode = prime * hashCode + ((getPath() == null) ? 0 : getPath().hashCode());
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;

        if (obj instanceof CreateInstanceProfileRequest == false) return false;
        CreateInstanceProfileRequest other = (CreateInstanceProfileRequest)obj;

        if (other.getInstanceProfileName() == null ^ this.getInstanceProfileName() == null) return false;
        if (other.getInstanceProfileName() != null && other.getInstanceProfileName().equals(this.getInstanceProfileName()) == false) return false;
        if (other.getPath() == null ^ this.getPath() == null) return false;
        if (other.getPath() != null && other.getPath().equals(this.getPath()) == false) return false;
        return true;
    }

}


text:
<?php

/**
 * Translates CMS directives using a template filter
 *
 * @author Daniel Deady <daniel@clockworkgeek.com>
 * @license MIT
 */
class Clockworkgeek_Extrarestful_Model_Api2_Block_Filter extends Mage_Api2_Model_Acl_Filter
{

    public function out(array $retrievedData)
    {
        if (isset($retrievedData['content'])) {
            $processor = Mage::helper('cms')->getBlockTemplateProcessor();
            $retrievedData['content'] = $processor->filter($retrievedData['content']);

        }
        return parent::out($retrievedData);
    }
}


text:
package ru.molkov.collapsar.data.core;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.HttpException;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import ru.molkov.collapsar.data.core.error.RetrofitException;
import rx.Observable;
import rx.functions.Func1;

public class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
    private final RxJavaCallAdapterFactory mOriginal;

    private ErrorHandlingCallAdapterFactory() {
        mOriginal = RxJavaCallAdapterFactory.create();
    }

    public static CallAdapter.Factory create() {
        return new ErrorHandlingCallAdapterFactory();
    }

    @Override
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        return new CallAdapterWrapper(retrofit, mOriginal.get(returnType, annotations, retrofit));
    }

    private static class CallAdapterWrapper implements CallAdapter<Observable<?>> {
        private final Retrofit mRetrofit;
        private final CallAdapter<?> mWrapped;

        public CallAdapterWrapper(Retrofit retrofit, CallAdapter<?> wrapped) {
            mRetrofit = retrofit;
            mWrapped = wrapped;
        }

        @Override
        public Type responseType() {
            return mWrapped.responseType();
        }

        @SuppressWarnings("unchecked")
        @Override
        public <R> Observable<?> adapt(Call<R> call) {
            return ((Observable) mWrapped.adapt(call)).onErrorResumeNext(new Func1<Throwable, Observable>() {
                @Override
                public Observable call(Throwable throwable) {
                    // Workaround because there're some "broken" dates and api return 500 error in that case
                    RetrofitException exception = asRetrofitException(throwable);
                    if (exception.getKind().equals(RetrofitException.Kind.SERVER)) {
                        return Observable.just(null);
                    }
                    return Observable.error(asRetrofitException(throwable));
                }
            });
        }

        private RetrofitException asRetrofitException(Throwable throwable) {
            if (throwable instanceof HttpException) {
                HttpException httpException = (HttpException) throwable;
                int code = httpException.code();

                if (code == 403) {
                    return RetrofitException.forbiddenError(httpException);
                } else if (code == 429) {
                    return RetrofitException.tooManyRequestsError(httpException);
                } else if (code >= 400 && code < 500) {
                    return RetrofitException.clientError(httpException);
                } else if (code >= 500 && code < 600) {
                    return RetrofitException.serverError(httpException);
                }
            } else if (throwable instanceof IOException) {
                return RetrofitException.networkError((IOException) throwable);
            }

            return RetrofitException.unexpectedError(throwable);
        }
    }

}


text:
#import <Foundation/Foundation.h>

#import "FBAccessTokenData.h"

/*!
 @class

 @abstract
 The `FBSessionTokenCachingStrategy` class is responsible for persisting and retrieving cached data related to
 an <FBSession> object, including the user's Facebook access token.

 @discussion
 `FBSessionTokenCachingStrategy` is designed to be instantiated directly or used as a base class. Usually default
 token caching behavior is sufficient, and you do not need to interface directly with `FBSessionTokenCachingStrategy` objects.
 However, if you need to control where or how `FBSession` information is cached, then you may take one of two approaches.

 The first and simplest approach is to instantiate an instance of `FBSessionTokenCachingStrategy`, and then pass
 the instance to `FBSession` class' `init` method. This enables your application to control the key name used in
 `NSUserDefaults` to store session information. You may consider this approach if you plan to cache session information
 for multiple users.

 The second and more advanced approached is to derive a custom class from `FBSessionTokenCachingStrategy`, which will
 be responsible for caching behavior of your application. This approach is useful if you need to change where the
 information is cached, for example if you prefer to use the filesystem or make a network connection to fetch and
 persist cached tokens.  Inheritors should override the cacheTokenInformation, fetchTokenInformation, and clearToken methods.
 Doing this enables your application to implement any token caching scheme, including no caching at all (see
 `[FBSessionTokenCachingStrategy nullCacheInstance]`.

 Direct use of `FBSessionTokenCachingStrategy`is an advanced technique. Most applications use <FBSession> objects without
 passing an `FBSessionTokenCachingStrategy`, which yields default caching to `NSUserDefaults`.
 */
@interface FBSessionTokenCachingStrategy : NSObject

/*!
 @abstract Initializes and returns an instance
 */
- (instancetype)init;

/*!
 @abstract
 Initializes and returns an instance

 @param tokenInformationKeyName     Specifies a key name to use for cached token information in NSUserDefaults, nil
 indicates a default value of @"FBAccessTokenInformationKey"
 */
- (instancetype)initWithUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName;

/*!
 @abstract
 Called by <FBSession> (and overridden by inheritors), in order to cache token information.

 @param tokenInformation            Dictionary containing token information to be cached by the method
 @discussion You should favor overriding this instead of `cacheFBAccessTokenData` only if you intend
 to cache additional data not captured by the FBAccessTokenData type.
 */
- (void)cacheTokenInformation:(NSDictionary *)tokenInformation;

/*!
 @abstract Cache the supplied token.
 @param accessToken The token instance.
 @discussion This essentially wraps a call to `cacheTokenInformation` so you should
 override this when providing a custom token caching strategy.
 */
- (void)cacheFBAccessTokenData:(FBAccessTokenData *)accessToken;

/*!
 @abstract
 Called by <FBSession> (and overridden by inheritors), in order to fetch cached token information

 @discussion
 An overriding implementation should only return a token if it
 can also return an expiration date, otherwise return nil.
 You should favor overriding this instead of `fetchFBAccessTokenData` only if you intend
 to cache additional data not captured by the FBAccessTokenData type.

 */
- (NSDictionary *)fetchTokenInformation;

/*!
 @abstract
 Fetches the cached token instance.

 @discussion
 This essentially wraps a call to `fetchTokenInformation` so you should
 override this when providing a custom token caching strategy.

 In order for an `FBSession` instance to be able to use a cached token,
 the token must be not be expired (see `+isValidTokenInformation:`) and
 must also contain all permissions in the initialized session instance.
 */
- (FBAccessTokenData *)fetchFBAccessTokenData;

/*!
 @abstract
 Called by <FBSession> (and overridden by inheritors), in order delete any cached information for the current token
 */
- (void)clearToken;

/*!
 @abstract
 Helper function called by the SDK as well as apps, in order to fetch the default strategy instance.
 */
+ (FBSessionTokenCachingStrategy *)defaultInstance;

/*!
 @abstract
 Helper function to return a FBSessionTokenCachingStrategy instance that does not perform any caching.
 */
+ (FBSessionTokenCachingStrategy *)nullCacheInstance;

/*!
 @abstract
 Helper function called by the SDK as well as application code, used to determine whether a given dictionary
 contains the minimum token information usable by the <FBSession>.

 @param tokenInformation            Dictionary containing token information to be validated
 */
+ (BOOL)isValidTokenInformation:(NSDictionary *)tokenInformation;

@end

// The key to use with token information dictionaries to get and set the token value
extern NSString *const FBTokenInformationTokenKey;

// The to use with token information dictionaries to get and set the expiration date
extern NSString *const FBTokenInformationExpirationDateKey;

// The to use with token information dictionaries to get and set the refresh date
extern NSString *const FBTokenInformationRefreshDateKey;

// The key to use with token information dictionaries to get the related user's fbid
extern NSString *const FBTokenInformationUserFBIDKey;

// The key to use with token information dictionaries to determine whether the token was fetched via Facebook Login
extern NSString *const FBTokenInformationIsFacebookLoginKey;

// The key to use with token information dictionaries to determine whether the token was fetched via the OS
extern NSString *const FBTokenInformationLoginTypeLoginKey;

// The key to use with token information dictionaries to get the latest known permissions
extern NSString *const FBTokenInformationPermissionsKey;

// The key to use with token information dictionaries to get the date the permissions were last refreshed.
extern NSString *const FBTokenInformationPermissionsRefreshDateKey;


text:
var CardReader = function (error_start, track_start, track_end, timeout) {
	this.error_start = error_start || "é";
	this.track_start = track_start || "%";
	this.track_end = track_end || "_";
	this.timeout = timeout || 100;

	this.error_start = this.error_start.charCodeAt(0);
	this.track_start = this.track_start.charCodeAt(0);
	this.track_end = this.track_end.charCodeAt(0);

	this.started = false;
	this.finished = false;
	this.isError = false;
	this.input = "";
	this.timer = undefined;
	this.callbacks = [];
	this.errbacks = [];
	this.validators = [];
	this.isDispatching = false;
};

CardReader.prototype = {
	dispatch: function (data, isError) {
		if (!isError) {
			for (var cb in this.validators) {
				if (!this.validators[cb](data)) {
					isError = true;
					break;
				}
			}
		}

		if (this.isDispatching) {
			if (isError) {
				console.log("Immediate error!");
				return;
			} else {
				clearTimeout(this.isDispatching);
			}
		}

		var reader = this;

		this.isDispatching = setTimeout(function () {
			console.log("Error timeout cleared");
			reader.isDispatching = false;
		}, 200);

		if (isError) {
			for (var cb in this.errbacks) {
				this.errbacks[cb](this.input);
			}
		} else {
			for (var cb in this.callbacks) {
				this.callbacks[cb](this.input);
			}
		}
	},

	readObserver: function (e) {
		var ob = this;

		if (!this.started && (e.which === this.track_start || e.which === this.error_start)) {
			e.stopImmediatePropagation();
			e.preventDefault();

			this.started = true;
			this.isError = e.which === this.error_start;

			this.timer = setTimeout(function () {
				ob.started = false;
				ob.finished = false;
				ob.isError = false;
				ob.input = "";
			}, this.timeout);
		} else if (this.started && e.which === this.track_end) {
			e.stopImmediatePropagation();
			e.preventDefault();

			this.finished = true;

			clearTimeout(this.timer);
			this.timer = setTimeout(function () {
				ob.started = false;
				ob.finished = false;
				ob.isError = false;
				ob.input = "";
			}, this.timeout);
		} else if (this.started && this.finished && e.which === 13) {
			e.stopImmediatePropagation();
			e.preventDefault();

			this.dispatch(this.input, this.isError);

			this.started = false;
			this.finished = false;
			this.isError = false;
			this.input = "";

			clearTimeout(this.timer);

		} else if (this.started) {
			e.stopImmediatePropagation();
			e.preventDefault();

			this.input += String.fromCharCode(e.which);

			clearTimeout(this.timer);
			this.timer = setTimeout(function () {
				ob.started = false;
				ob.finished = false;
				ob.isError = false;
				ob.input = "";
			}, this.timeout);
		}
	},

	observe: function (element) {
		var func = this;

		$(element).keypress(function (e) {
			CardReader.prototype.readObserver.apply(func, arguments);
		});
	},

	validate: function (validator) {
		this.validators.push(validator);
	},

	cardRead: function (callback) {
		this.callbacks.push(callback);
	},

	cardError: function (errback) {
		this.errbacks.push(errback);
	},
}