text:
require_relative '../../spec_helper'

describe "Encoding#ascii_compatible?" do
  it "returns true if self represents an ASCII-compatible encoding" do
    Encoding::UTF_8.ascii_compatible?.should be_true
  end

  it "returns false if self does not represent an ASCII-compatible encoding" do
    Encoding::UTF_16LE.ascii_compatible?.should be_false
  end
end

redpajama_set_name: RedPajamaGithub


text:
// Generated by LiveScript 1.5.0
/**
 * @package  Shop
 * @category modules
 * @author   Nazar Mokrynskyi <nazar@mokrynskyi.com>
 * @license  0BSD
 */
(function(){
  Polymer({
    is: 'cs-shop-orders',
    behaviors: [cs.Polymer.behaviors.Language('shop_')],
    ready: function(){
      this.$.orders.innerHTML = this.querySelector('#orders').innerHTML;
    }
  });
}).call(this);


text:
Sequel.migration do
  change do

    create_table :additional_metadata_locations do
      primary_key :id

      String :uri, null: false
      String :namespace, null: false

      DateTime :created_at
      DateTime :updated_at
    end

  end
end


text:
class RenderViewContextMenu;

namespace content {
class WebContents;
struct ContextMenuParams;
}

// A ContextMenuDelegate can build and show renderer context menu.
class ContextMenuDelegate {
 public:
  explicit ContextMenuDelegate(content::WebContents* web_contents);
  virtual ~ContextMenuDelegate();

  static ContextMenuDelegate* FromWebContents(
      content::WebContents* web_contents);

  // Builds and returns a context menu for a context specified by |params|.
  // The returned value can be used to display the context menu.
  virtual scoped_ptr<RenderViewContextMenu> BuildMenu(
      content::WebContents* web_contents,
      const content::ContextMenuParams& params) = 0;

  // Displays the context menu.
  virtual void ShowMenu(scoped_ptr<RenderViewContextMenu> menu) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(ContextMenuDelegate);
};

#endif  // COMPONENTS_RENDERER_CONTEXT_MENU_CONTEXT_MENU_DELEGATE_H_


text:
package com.annimon.ownlang.parser.ast;

/**
 *
 * @author aNNiMON
 */
public interface Visitor {

    void visit(ArrayExpression s);
    void visit(AssignmentExpression s);
    void visit(BinaryExpression s);
    void visit(BlockStatement s);
    void visit(BreakStatement s);
    void visit(ClassDeclarationStatement s);
    void visit(ConditionalExpression s);
    void visit(ContainerAccessExpression s);
    void visit(ContinueStatement s);
    void visit(DoWhileStatement s);
    void visit(DestructuringAssignmentStatement s);
    void visit(ForStatement s);
    void visit(ForeachArrayStatement s);
    void visit(ForeachMapStatement s);
    void visit(FunctionDefineStatement s);
    void visit(FunctionReferenceExpression e);
    void visit(ExprStatement s);
    void visit(FunctionalExpression s);
    void visit(IfStatement s);
    void visit(IncludeStatement s);
    void visit(MapExpression s);
    void visit(MatchExpression s);
    void visit(ObjectCreationExpression s);
    void visit(PrintStatement s);
    void visit(PrintlnStatement s);
    void visit(ReturnStatement s);
    void visit(TernaryExpression s);
    void visit(UnaryExpression s);
    void visit(ValueExpression s);
    void visit(VariableExpression s);
    void visit(WhileStatement st);
    void visit(UseStatement st);
}


text:
const moment = require("moment");

module.exports = function(options, callback) {
    if (!options.db.pull_request) {
        return callback({
            message: "There are no PRs to count",
            stack: "skipping"
        });
    }

    /* Work out how many PRs are open now */
    options.db.pull_request.find({state: "open"}, {html_url: 1, title: 1}).toArray().then(openNowPR => {
        if (openNowPR.length == 0) return callback({
            message: "There are no PRs to count",
            stack: "skipping"
        });
        let result = {
            title: "Open PRs",
            list: openNowPR.map(pr => {
                return {html: '' + pr.title + ''};
            })
        }
        options.templates.list(result, callback);
    }).catch(e => { callback(e); });;
}


text:
package main

import (
	"log"
	"time"

	"github.com/wuyingsong/tcp"
)

func main() {
	srv := tcp.NewAsyncTCPServer("localhost:9001", &EchoCallback{}, &EchoProtocol{})
	srv.SetReadDeadline(time.Second * 10)
	log.Println("start listen...")
	log.Println(srv.ListenAndServe())
	select {}
}


text:
import ArraySetLength = require('../2015/ArraySetLength');
export = ArraySetLength;


text:
package de.fuberlin.wiwiss.d2rq.expr;

import java.util.HashSet;
import java.util.Set;

import de.fuberlin.wiwiss.d2rq.algebra.AliasMap;
import de.fuberlin.wiwiss.d2rq.algebra.Attribute;
import de.fuberlin.wiwiss.d2rq.algebra.ColumnRenamer;
import de.fuberlin.wiwiss.d2rq.sql.ConnectedDB;
import de.fuberlin.wiwiss.d2rq.sql.SQL;

/**
 * An SQL expression.
 *
 * TODO: Shouldn't call to SQL so much
 *
 * @author Richard Cyganiak (richard@cyganiak.de)
 */
public class SQLExpression extends Expression {

	public static Expression create(String sql) {
		sql = sql.trim();
		if ("1".equals(sql)) {
			return Expression.TRUE;
		}
		if ("0".equals(sql)) {
			return Expression.FALSE;
		}
		return new SQLExpression(sql);
	}

	private String expression;
	private Set<Attribute> columns = new HashSet<Attribute>();

	private SQLExpression(String expression) {
		this.expression = expression;
		this.columns = SQL.findColumnsInExpression(this.expression);
	}

	public boolean isTrue() {
		return false;
	}

	public boolean isFalse() {
		return false;
	}

	public Set<Attribute> attributes() {
		return this.columns;
	}

	public Expression renameAttributes(ColumnRenamer columnRenamer) {
		return new SQLExpression(SQL.replaceColumnsInExpression(this.expression, columnRenamer));
	}

	public String toSQL(ConnectedDB database, AliasMap aliases) {
		return "(" + SQL.quoteColumnsInExpression(this.expression, database) + ")";
	}

	public String toString() {
		return "SQL(" + this.expression + ")";
	}

	public boolean equals(Object other) {
		if (!(other instanceof SQLExpression)) {
			return false;
		}
		SQLExpression otherExpression = (SQLExpression) other;
		return this.expression.equals(otherExpression.expression);
	}

	public int hashCode() {
		return this.expression.hashCode();
	}

	public String getExpression()
	{
		return expression;
	}

}


text:
// +build windows

package paperless

func SetupLogging() {
}


text:
package com.gitblit.utils;

import java.io.CharConversionException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.GitBlit;
import com.gitblit.Keys;

/**
 * This is the support class for all container specific code.
 *
 * @author jpyeron
 */
public class ContainerUtils
{
    private static Logger LOGGER = LoggerFactory.getLogger(ContainerUtils.class);

    /**
     * The support class for managing and evaluating the environment with
     * regards to CVE-2007-0405.
     *
     * @see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0450
     * @author jpyeron
     */
    public static class CVE_2007_0450
    {
        /**
         * This method will test for know issues in certain containers where %2F
         * is blocked from use in URLs. It will emit a warning to the logger if
         * the configuration of Tomcat causes the URL processing to fail on %2F.
         */
        public static void test()
        {
            if (GitBlit.getBoolean(Keys.web.mountParameters, true)
                    && ((GitBlit.getChar(Keys.web.forwardSlashCharacter, '/')) == '/' || (GitBlit.getChar(
                            Keys.web.forwardSlashCharacter, '/')) == '\\'))
            {
                try
                {
                    if (GitBlit.isGO())
                        ;
                    else if (logCVE_2007_0450Tomcat())
                        ;
                    // else if (logCVE_2007_0450xxx());
                    else
                    {
                        LOGGER.info("Unknown container, cannot check for CVE-2007-0450 aplicability");
                    }
                }
                catch (Throwable t)
                {
                    LOGGER.warn("Failure in checking for CVE-2007-0450 aplicability", t);
                }
            }

        }

        /**
         * This method will test for know issues in certain versions of Tomcat,
         * JBOSS, glassfish, and other embedded uses of Tomcat where %2F is
         * blocked from use in certain URL s. It will emit a warning to the
         * logger if the configuration of Tomcat causes the URL processing to
         * fail on %2F.
         *
         * @return true if it recognizes Tomcat, false if it does not recognize
         *         Tomcat
         */
        private static boolean logCVE_2007_0450Tomcat()
        {
            try
            {
                byte[] test = "http://server.domain:8080/context/servlet/param%2fparam".getBytes();

                // ByteChunk mb=new ByteChunk();
                Class<?> cByteChunk = Class.forName("org.apache.tomcat.util.buf.ByteChunk");
                Object mb = cByteChunk.newInstance();

                // mb.setBytes(test, 0, test.length);
                Method mByteChunck_setBytes = cByteChunk.getMethod("setBytes", byte[].class, int.class, int.class);
                mByteChunck_setBytes.invoke(mb, test, (int) 0, test.length);

                // UDecoder ud=new UDecoder();
                Class<?> cUDecoder = Class.forName("org.apache.tomcat.util.buf.UDecoder");
                Object ud = cUDecoder.newInstance();

                // ud.convert(mb,false);
                Method mUDecoder_convert = cUDecoder.getMethod("convert", cByteChunk, boolean.class);

                try
                {
                    mUDecoder_convert.invoke(ud, mb, false);
                }
                catch (InvocationTargetException e)
                {
                    if (e.getTargetException() != null && e.getTargetException() instanceof CharConversionException)
                    {
                        LOGGER.warn("You are using a Tomcat-based server and your current settings will prevent grouped repositories, forks, personal repositories, and tree navigation from working properly. Please review the FAQ for details about running Gitblit on Tomcat. http://gitblit.com/faq.html and http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0450");
                        return true;
                    }
                    throw e;
                }
            }
            catch (Throwable t)
            {
                // The apache url decoder internals are different, this is not a
                // Tomcat matching the failure pattern for CVE-2007-0450
                if (t instanceof ClassNotFoundException || t instanceof NoSuchMethodException
                        || t instanceof IllegalArgumentException)
                    return false;
                LOGGER.debug("This is a tomcat, but the test operation failed somehow", t);
            }
            return true;
        }
    }

}


text:
package org.corundummc.biomes.interfaces.types;

import org.corundummc.biomes.Biome.BiomeType;

public interface PlateauBiomeType<B extends BiomeType<B, ?, ?>> extends VariantBiomeType<B> {
    // nothing needs to be here
}


text:
    <md-toolbar class="my-profile-toolbar _content-nav"
                ng-class="{'_sm': $mdMedia('sm'), '_gt-sm': $mdMedia('gt-sm')}">

Public Profile

    </md-toolbar>

{{ profile.user.handle }}

                        <md-button ng-if="profile.user.is_worker" class="md-accent" tabindex="-1"
                                   ui-sref="bonus({handle: profile.user.handle})">
                            Bonus
                        </md-button>

                <ng-pluralize ng-if="profile.user && profile.user.tasks_completed" count="profile.user.tasks_completed"
                              when="{'one': '1 task completed', 'other': '{} tasks completed'}"></ng-pluralize>

Member
                    since {{ profile.user.member_since | date:'MMMM, yyyy' }}

                <md-progress-circular md-diameter="20" class="_centered"
                                      md-mode="indeterminate"></md-progress-circular>

Loading ...

Projects {{ profile.user.handle }} completed for me:

{{ project.name }}

                            <ng-pluralize flex="10"
                                          count="project.tasks_completed"
                                          when="{'one': '1 task', 'other': '{} tasks'}"></ng-pluralize>

                                <md-button tabindex="-1" ng-click="profile.setRating(project, 3.0, 2)"
                                           ng-class="{'_button-active': project.rating==3.0}">
                                    <md-icon md-font-set="material-icons">trending_up</md-icon>
                                    <md-tooltip>This worker gets access to my tasks before everyone else.</md-tooltip>
                                    PRIORITY
                                </md-button>
                                <md-button tabindex="-1"
                                           ng-click="profile.setRating(project, 2.0, 2)"
                                           ng-class="{'_button-active': project.rating==2.0 || project.rating==1.99}">
                                    <md-icon md-font-set="material-icons">trending_flat</md-icon>
                                    <md-tooltip>This worker gets access to your tasks at the usual time.
                                    </md-tooltip>
                                    Normal
                                </md-button>
                                <md-button tabindex="-1" style="margin-right: 0;"
                                           ng-click="profile.setRating(project, 1.0, 2)"
                                           ng-class="{'_button-active': project.rating==1.0}">
                                    <md-icon md-font-set="material-icons">trending_down</md-icon>
                                    <md-tooltip>This worker gets access to your tasks after everyone
                                        else, only if others aren't available.
                                    </md-tooltip>
                                    Late
                                </md-button>

                        <md-divider ng-if="!last"></md-divider>

Projects I completed for {{ profile.user.handle }}:

{{ project.name }}

                            <ng-pluralize flex="10"
                                          count="project.tasks_completed"
                                          when="{'one': '1 task', 'other': '{} tasks'}"></ng-pluralize>

                                <md-button tabindex="-1" ng-click="profile.setRating(project, 3.0, 1)"
                                           ng-class="{'_button-active': project.rating==3.0}">
                                    <md-icon md-font-set="material-icons">trending_up</md-icon>
                                    <md-tooltip>This requester's tasks appear at the top of your task feed.</md-tooltip>
                                    TOP
                                </md-button>
                                <md-button tabindex="-1"
                                           ng-click="profile.setRating(project, 2.0, 1)"
                                           ng-class="{'_button-active': project.rating==2.0 || project.rating==1.99}">
                                    <md-icon md-font-set="material-icons">trending_flat</md-icon>
                                    <md-tooltip>This requester's tasks appear in the default position in your task feed.
                                    </md-tooltip>
                                    Normal
                                </md-button>
                                <md-button tabindex="-1" style="margin-right: 0;"
                                           ng-click="profile.setRating(project, 1.0, 1)"
                                           ng-class="{'_button-active': project.rating==1.0}">
                                    <md-icon md-font-set="material-icons">trending_down</md-icon>
                                    <md-tooltip>This requester's tasks appear at the bottom of your task feed.
                                    </md-tooltip>
                                    BOTTOM
                                </md-button>

                        <md-divider ng-if="!last"></md-divider>


text:
package com.basho.riak.client.api.commands.mapreduce;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

/**
 * Serializes a {@link LinkPhase} to a Riak MapReduce JSON format.
 */
class LinkPhaseSerializer extends JsonSerializer<LinkPhase>
{
    @Override
    public void serialize(LinkPhase phase, JsonGenerator jg, SerializerProvider sp) throws IOException
    {
        jg.writeStartObject();
        jg.writeFieldName(phase.getType().toString());

        jg.writeStartObject();
        jg.writeStringField("bucket", phase.getBucket());
        jg.writeStringField("tag", phase.getTag());
        jg.writeEndObject();

        jg.writeEndObject();
    }
}


text:
/**
 * @file rule.h
 * @author Hightman Mar
 * @editor set number ; syntax on ; set autoindent ; set tabstop=4 (vim)
 * $Id$
 */

#ifndef	_SCWS_RULE_20070525_H_
#define	_SCWS_RULE_20070525_H_

/* xtree required */
#include "xtree.h"

#define	SCWS_RULE_MAX			32
#define	SCWS_RULE_SPECIAL		0x80000000
#define	SCWS_RULE_NOSTATS		0x40000000

/* flag: 0x00 ~ 0x4000 */
#define	SCWS_ZRULE_NONE			0x00
#define	SCWS_ZRULE_PREFIX		0x01
#define	SCWS_ZRULE_SUFFIX		0x02
#define	SCWS_ZRULE_INCLUDE		0x04	/* with include */
#define	SCWS_ZRULE_EXCLUDE		0x08	/* with exclude */
#define	SCWS_ZRULE_RANGE		0x10	/* with znum range */

/* data structure */
typedef struct scws_rule_item
{
	short flag;
	char zmin;
	char zmax;
	char name[17];
	char attr[3];
	float tf;
	float idf;
	unsigned int bit;	/* my bit  */
	unsigned int inc;	/* include */
	unsigned int exc;	/* exclude */
}	*rule_item_t;

/* special attrs ratio list(single chain, 12bytes) */
typedef struct scws_rule_attr *rule_attr_t;
struct scws_rule_attr
{
	char attr1[2];
	char attr2[2];
	unsigned char npath[2];
	short ratio;
	rule_attr_t next;
};

typedef struct scws_rule
{
	xtree_t tree;
	rule_attr_t attr;
	struct scws_rule_item items[SCWS_RULE_MAX];
	int ref;	// hightman.20130110: refcount (zero to really free/close)
}	rule_st, *rule_t;

/* scws ruleset: api */

/* create & load ruleset, by fpath & charset */
rule_t scws_rule_new(const char *fpath, unsigned char *mblen);

/* fork ruleset */
rule_t scws_rule_fork(rule_t r);

/* free the memory & resource for ruleset */
void scws_rule_free(rule_t r);

/* get the rule tree record by str */
rule_item_t scws_rule_get(rule_t r, const char *str, int len);

/* check bit */
int scws_rule_checkbit(rule_t r, const char *str, int len, unsigned int bit);

/* get rule attr x */
int scws_rule_attr_ratio(rule_t r, const char *attr1, const char *attr2, const unsigned char *npath);

/* check exclude or include */
int scws_rule_check(rule_t r, rule_item_t cr, const char *str, int len);

#endif


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>{% block title %}{{ SITENAME }}{% endblock %}</title>
  <meta name="author" content="{{ AUTHOR }}">

  {% if FEED_ATOM %}
  <link href="{{ FEED_DOMAIN }}/{{ FEED_ATOM }}" type="application/atom+xml" rel="alternate"
        title="{{ SITENAME }} Atom Feed" />
  {% endif %}
  {% if FEED_RSS %}
  <link href="{{ FEED_DOMAIN }}/{{ FEED_RSS }}" type="application/rss+xml" rel="alternate"
        title="{{ SITENAME }} RSS Feed" />
  {% endif %}

  {% if EXTRA_HEADER %}
    {{ EXTRA_HEADER }}
  {% endif %}

  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link href="{{ SITEURL }}/favicon.png" rel="icon">
  <link href="{{ SITEURL }}/theme/css/{{ CSS_FILE }}" media="screen, projection"
        rel="stylesheet" type="text/css">

  <link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic"
        rel="stylesheet" type="text/css">
  <link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic"
        rel="stylesheet" type="text/css">

  {% include '_includes/header.html' %}
  {% include '_includes/navigation.html' %}

      {% block content %}{% endblock %}
      {% include '_includes/sidebar.html' %}

  {% include '_includes/footer.html' %}
  {% include '_includes/after_footer.html' %}


text:
package com.drew.metadata.heif;

import com.drew.imaging.heif.HeifHandler;
import com.drew.lang.SequentialByteArrayReader;
import com.drew.lang.SequentialReader;
import com.drew.lang.annotations.NotNull;
import com.drew.metadata.Metadata;
import com.drew.metadata.heif.boxes.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * @author Payton Garland
 */
public class HeifBoxHandler extends HeifHandler<HeifDirectory>
{
    HandlerBox handlerBox;

    private HeifHandlerFactory handlerFactory = new HeifHandlerFactory(this);

    public HeifBoxHandler(Metadata metadata)
    {
        super(metadata);
    }

    @Override
    protected HeifDirectory getDirectory()
    {
        return new HeifDirectory();
    }

    @Override
    public boolean shouldAcceptBox(@NotNull Box box)
    {
        List<String> boxes = Arrays.asList(HeifBoxTypes.BOX_FILE_TYPE,
            HeifBoxTypes.BOX_HANDLER,
            HeifBoxTypes.BOX_HVC1);

        return boxes.contains(box.type);
    }

    @Override
    public boolean shouldAcceptContainer(Box box)
    {
        return box.type.equals(HeifContainerTypes.BOX_METADATA)
            || box.type.equals(HeifContainerTypes.BOX_IMAGE_PROPERTY)
            || box.type.equals(HeifContainerTypes.BOX_ITEM_PROPERTY);
    }

    @Override
    public HeifHandler processBox(@NotNull Box box, @NotNull byte[] payload) throws IOException
    {
        if (payload != null) {
            SequentialReader reader = new SequentialByteArrayReader(payload);
            if (box.type.equals(HeifBoxTypes.BOX_FILE_TYPE)) {
                processFileType(reader, box);
            }else if (box.type.equals(HeifBoxTypes.BOX_HANDLER)) {
                handlerBox = new HandlerBox(reader, box);
                return handlerFactory.getHandler(handlerBox, metadata);
            }
        }
        return this;
    }

    @Override
    public void processContainer(@NotNull Box box, @NotNull SequentialReader reader) throws IOException
    {
        if (box.type.equals(HeifContainerTypes.BOX_METADATA)) {
            new FullBox(reader, box);
        }
    }

    private void processFileType(@NotNull SequentialReader reader, @NotNull Box box) throws IOException
    {
        FileTypeBox fileTypeBox = new FileTypeBox(reader, box);
        fileTypeBox.addMetadata(directory);
        if (!fileTypeBox.getCompatibleBrands().contains("mif1")) {
            directory.addError("File Type Box does not contain required brand, mif1");
        }
    }
}


text:
public class Context {
	private State mState;

	public Context() {
		mState = null;
	}

	public void setState(State state) {
		this.mState = state;
	}

	public State getState() {
		return mState;
	}
}


text:
package org.pentaho.di.trans.steps.transexecutor;

import java.util.ArrayList;

import com.google.common.annotations.VisibleForTesting;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.Result;
import org.pentaho.di.core.ResultFile;
import org.pentaho.di.core.RowMetaAndData;
import org.pentaho.di.core.RowSet;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.logging.KettleLogStore;
import org.pentaho.di.core.logging.LoggingRegistry;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.DelegationListener;
import org.pentaho.di.trans.StepWithMappingMeta;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransExecutionConfiguration;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStep;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.steps.TransStepUtil;

/**
 * Execute a transformation for every input row, set parameters.
 *

 *     Note:

 *     Be aware, logic of the classes methods is very similar to corresponding methods of
 *     {@link org.pentaho.di.trans.steps.jobexecutor.JobExecutor JobExecutor}.
 *     If you change something in this class, consider copying your changes to JobExecutor as well.
 *

 *
 * @author Matt
 * @since 18-mar-2013
 */
public class TransExecutor extends BaseStep implements StepInterface {
  private static final Class<?> PKG = TransExecutorMeta.class; // for i18n purposes, needed by Translator2!!

  private TransExecutorMeta meta;
  private TransExecutorData data;

  public TransExecutor( StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta,
                        Trans trans ) {
    super( stepMeta, stepDataInterface, copyNr, transMeta, trans );
  }

  /**
   * Process a single row. In our case, we send one row of data to a piece of transformation. In the transformation, we
   * look up the MappingInput step to send our rows to it. As a consequence, for the time being, there can only be one
   * MappingInput and one MappingOutput step in the TransExecutor.
   */
  public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
    try {
      meta = (TransExecutorMeta) smi;
      setData( (TransExecutorData) sdi );
      TransExecutorData transExecutorData = getData();
      // Wait for a row...
      Object[] row = getRow();
      if ( row == null ) {
        executeTransformation();
        setOutputDone();
        return false;
      }

      if ( first ) {
        first = false;
        initOnFirstProcessingIteration();
      }

      RowSet executorStepOutputRowSet = transExecutorData.getExecutorStepOutputRowSet();
      if ( transExecutorData.getExecutorStepOutputRowMeta() != null && executorStepOutputRowSet != null ) {
        putRowTo( transExecutorData.getExecutorStepOutputRowMeta(), row, executorStepOutputRowSet );
      }

      // Grouping by field and execution time works ONLY if grouping by size is disabled.
      if ( transExecutorData.groupSize < 0 ) {
        if ( transExecutorData.groupFieldIndex >= 0 ) { // grouping by field
          Object groupFieldData = row[ transExecutorData.groupFieldIndex ];
          if ( transExecutorData.prevGroupFieldData != null ) {
            if ( transExecutorData.groupFieldMeta.compare( transExecutorData.prevGroupFieldData, groupFieldData ) != 0 ) {
              executeTransformation();
            }
          }
          transExecutorData.prevGroupFieldData = groupFieldData;
        } else if ( transExecutorData.groupTime > 0 ) { // grouping by execution time
          long now = System.currentTimeMillis();
          if ( now - transExecutorData.groupTimeStart >= transExecutorData.groupTime ) {
            executeTransformation();
          }
        }
      }

      // Add next value AFTER transformation execution, in case we are grouping by field (see PDI-14958),
      // and BEFORE checking size of a group, in case we are grouping by size (see PDI-14121).
      transExecutorData.groupBuffer.add( new RowMetaAndData( getInputRowMeta(), row ) ); // should we clone for safety?

      // Grouping by size.
      // If group buffer size exceeds specified limit, then execute transformation and flush group buffer.
      if ( transExecutorData.groupSize > 0 ) {
        if ( transExecutorData.groupBuffer.size() >= transExecutorData.groupSize ) {
          executeTransformation();
        }
      }

      return true;
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "TransExecutor.UnexpectedError" ), e );
    }
  }

  private void initOnFirstProcessingIteration() throws KettleException {
    TransExecutorData transExecutorData = getData();
    // internal transformation's first step has exactly the same input
    transExecutorData.setInputRowMeta( getInputRowMeta() );

    // internal transformation's execution results
    transExecutorData.setExecutionResultsOutputRowMeta( new RowMeta() );
    if ( meta.getExecutionResultTargetStepMeta() != null ) {
      meta.prepareExecutionResultsFields( transExecutorData.getExecutionResultsOutputRowMeta(),
        meta.getExecutionResultTargetStepMeta() );
      transExecutorData
        .setExecutionResultRowSet( findOutputRowSet( meta.getExecutionResultTargetStepMeta().getName() ) );
    }
    // internal transformation's execution result's file
    transExecutorData.setResultFilesOutputRowMeta( new RowMeta() );
    if ( meta.getResultFilesTargetStepMeta() != null ) {
      meta.prepareExecutionResultsFileFields( transExecutorData.getResultFilesOutputRowMeta(),
        meta.getResultFilesTargetStepMeta() );
      transExecutorData.setResultFilesRowSet( findOutputRowSet( meta.getResultFilesTargetStepMeta().getName() ) );
    }
    // internal transformation's execution output
    transExecutorData.setResultRowsOutputRowMeta( new RowMeta() );
    if ( meta.getOutputRowsSourceStepMeta() != null ) {
      meta.prepareResultsRowsFields( transExecutorData.getResultRowsOutputRowMeta() );
      transExecutorData.setResultRowsRowSet( findOutputRowSet( meta.getOutputRowsSourceStepMeta().getName() ) );
    }

    // executor's self output is exactly its input
    if ( meta.getExecutorsOutputStepMeta() != null ) {
      transExecutorData.setExecutorStepOutputRowMeta( getInputRowMeta().clone() );
      transExecutorData.setExecutorStepOutputRowSet( findOutputRowSet( meta.getExecutorsOutputStepMeta().getName() ) );
    }

    // Remember which column to group on, if any...
    transExecutorData.groupFieldIndex = -1;
    if ( !Utils.isEmpty( transExecutorData.groupField ) ) {
      transExecutorData.groupFieldIndex = getInputRowMeta().indexOfValue( transExecutorData.groupField );
      if ( transExecutorData.groupFieldIndex < 0 ) {
        throw new KettleException( BaseMessages.getString(
          PKG, "TransExecutor.Exception.GroupFieldNotFound", transExecutorData.groupField ) );
      }
      transExecutorData.groupFieldMeta = getInputRowMeta().getValueMeta( transExecutorData.groupFieldIndex );
    }
  }

  private void executeTransformation() throws KettleException {
    TransExecutorData transExecutorData = getData();
    // If we got 0 rows on input we don't really want to execute the transformation
    if ( transExecutorData.groupBuffer.isEmpty() ) {
      return;
    }
    transExecutorData.groupTimeStart = System.currentTimeMillis();

    if ( first ) {
      discardLogLines( transExecutorData );
    }

    Trans executorTrans = createInternalTrans();
    transExecutorData.setExecutorTrans( executorTrans );

    // Pass parameter values
    passParametersToTrans();

    // keep track for drill down in Spoon...
    getTrans().addActiveSubTransformation( getStepname(), executorTrans );

    Result result = new Result();
    result.setRows( transExecutorData.groupBuffer );
    executorTrans.setPreviousResult( result );

    try {
      executorTrans.prepareExecution( getTrans().getArguments() );

      // run transformation
      executorTrans.startThreads();

      // Inform the parent transformation we started something here...
      for ( DelegationListener delegationListener : getTrans().getDelegationListeners() ) {
        // TODO: copy some settings in the transformation execution configuration, not strictly needed
        // but the execution configuration information is useful in case of a transformation re-start on Carte
        delegationListener.transformationDelegationStarted( executorTrans, new TransExecutionConfiguration() );
      }

      // Wait a while until we're done with the transformation
      executorTrans.waitUntilFinished();

      result = executorTrans.getResult();
    } catch ( KettleException e ) {
      log.logError( "An error occurred executing the transformation: ", e );
      result.setResult( false );
      result.setNrErrors( 1 );
    }

    if ( result.isSafeStop() ) {
      getTrans().safeStop();
    } else if ( result.getNrErrors() > 0 ) {
      getTrans().stopAll();
    }

    collectTransResults( result );
    collectExecutionResults( result );
    collectExecutionResultFiles( result );

    transExecutorData.groupBuffer.clear();
  }

  @VisibleForTesting
  void discardLogLines( TransExecutorData transExecutorData ) {
    // Keep the strain on the logging back-end conservative.
    // TODO: make this optional/user-defined later
    Trans executorTrans = transExecutorData.getExecutorTrans();
    if ( executorTrans != null ) {
      KettleLogStore.discardLines( executorTrans.getLogChannelId(), false );
      LoggingRegistry.getInstance().removeIncludingChildren( executorTrans.getLogChannelId() );
    }
  }

  @VisibleForTesting
  Trans createInternalTrans() throws KettleException {
    Trans executorTrans = new Trans( getData().getExecutorTransMeta(), this );

    executorTrans.setParentTrans( getTrans() );
    executorTrans.setRepository( getTrans().getRepository() );
    executorTrans.setLogLevel( getLogLevel() );
    executorTrans.setArguments( getTrans().getArguments() );

    executorTrans.setInternalKettleVariables( this );

    executorTrans.setPreview( getTrans().isPreview() );

    TransStepUtil.initServletConfig( getTrans(), executorTrans );

    return executorTrans;
  }

  @VisibleForTesting
  void passParametersToTrans() throws KettleException {
    // Set parameters, when fields are used take the first row in the set.
    TransExecutorParameters parameters = meta.getParameters();

    Trans internalTrans = getData().getExecutorTrans();

    StepWithMappingMeta.activateParams( internalTrans, internalTrans, this, internalTrans.listParameters(),
      parameters.getVariable(), parameters.getInput() );

  }

  @VisibleForTesting
  void collectTransResults( Result result ) throws KettleException {
    RowSet transResultsRowSet = getData().getResultRowsRowSet();
    if ( meta.getOutputRowsSourceStepMeta() != null && transResultsRowSet != null ) {
      for ( RowMetaAndData metaAndData : result.getRows() ) {
        putRowTo( metaAndData.getRowMeta(), metaAndData.getData(), transResultsRowSet );
      }
    }
  }

  @VisibleForTesting
  void collectExecutionResults( Result result ) throws KettleException {
    RowSet executionResultsRowSet = getData().getExecutionResultRowSet();
    if ( meta.getExecutionResultTargetStepMeta() != null && executionResultsRowSet != null ) {
      Object[] outputRow = RowDataUtil.allocateRowData( getData().getExecutionResultsOutputRowMeta().size() );
      int idx = 0;

      if ( !Utils.isEmpty( meta.getExecutionTimeField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( System.currentTimeMillis() - getData().groupTimeStart );
      }
      if ( !Utils.isEmpty( meta.getExecutionResultField() ) ) {
        outputRow[ idx++ ] = Boolean.valueOf( result.getResult() );
      }
      if ( !Utils.isEmpty( meta.getExecutionNrErrorsField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrErrors() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesReadField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesRead() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesWrittenField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesWritten() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesInputField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesInput() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesOutputField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesOutput() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesRejectedField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesRejected() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesUpdatedField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesUpdated() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLinesDeletedField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrLinesDeleted() );
      }
      if ( !Utils.isEmpty( meta.getExecutionFilesRetrievedField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getNrFilesRetrieved() );
      }
      if ( !Utils.isEmpty( meta.getExecutionExitStatusField() ) ) {
        outputRow[ idx++ ] = Long.valueOf( result.getExitStatus() );
      }
      if ( !Utils.isEmpty( meta.getExecutionLogTextField() ) ) {
        String channelId = getData().getExecutorTrans().getLogChannelId();
        String logText = KettleLogStore.getAppender().getBuffer( channelId, false ).toString();
        outputRow[ idx++ ] = logText;
      }
      if ( !Utils.isEmpty( meta.getExecutionLogChannelIdField() ) ) {
        outputRow[ idx++ ] = getData().getExecutorTrans().getLogChannelId();
      }

      putRowTo( getData().getExecutionResultsOutputRowMeta(), outputRow, executionResultsRowSet );
    }
  }

  @VisibleForTesting
  void collectExecutionResultFiles( Result result ) throws KettleException {
    RowSet resultFilesRowSet = getData().getResultFilesRowSet();
    if ( meta.getResultFilesTargetStepMeta() != null && result.getResultFilesList() != null && resultFilesRowSet != null ) {
      for ( ResultFile resultFile : result.getResultFilesList() ) {
        Object[] targetRow = RowDataUtil.allocateRowData( getData().getResultFilesOutputRowMeta().size() );
        int idx = 0;
        targetRow[ idx++ ] = resultFile.getFile().getName().toString();

        // TODO: time, origin, ...

        putRowTo( getData().getResultFilesOutputRowMeta(), targetRow, resultFilesRowSet );
      }
    }
  }

  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
    meta = (TransExecutorMeta) smi;
    setData( (TransExecutorData) sdi );
    TransExecutorData transExecutorData = getData();
    if ( super.init( smi, sdi ) ) {
      // First we need to load the mapping (transformation)
      try {
        // Pass the repository down to the metadata object...
        meta.setRepository( getTransMeta().getRepository() );

        transExecutorData.setExecutorTransMeta( loadExecutorTransMeta() );

        // Do we have a transformation at all?
        if ( transExecutorData.getExecutorTransMeta() != null ) {
          transExecutorData.groupBuffer = new ArrayList<RowMetaAndData>();

          // How many rows do we group together for the transformation?
          if ( !Utils.isEmpty( meta.getGroupSize() ) ) {
            transExecutorData.groupSize = Const.toInt( environmentSubstitute( meta.getGroupSize() ), -1 );
          } else {
            transExecutorData.groupSize = -1;
          }
          // Is there a grouping time set?
          if ( !Utils.isEmpty( meta.getGroupTime() ) ) {
            transExecutorData.groupTime = Const.toInt( environmentSubstitute( meta.getGroupTime() ), -1 );
          } else {
            transExecutorData.groupTime = -1;
          }
          transExecutorData.groupTimeStart = System.currentTimeMillis();

          // Is there a grouping field set?
          if ( !Utils.isEmpty( meta.getGroupField() ) ) {
            transExecutorData.groupField = environmentSubstitute( meta.getGroupField() );
          }
          // That's all for now...
          return true;
        } else {
          logError( "No valid transformation was specified nor loaded!" );
          return false;
        }
      } catch ( Exception e ) {
        logError( "Unable to load the transformation executor because of an error : ", e );
      }

    }
    return false;
  }

  @VisibleForTesting
  TransMeta loadExecutorTransMeta() throws KettleException {
    return TransExecutorMeta.loadMappingMeta( meta, meta.getRepository(), meta.getMetaStore(), this, meta.getParameters().isInheritingAllVariables() );
  }

  public void dispose( StepMetaInterface smi, StepDataInterface sdi ) {
    TransExecutorData transExecutorData = getData();
    transExecutorData.groupBuffer = null;
    super.dispose( smi, sdi );
  }

  public void stopRunning( StepMetaInterface stepMetaInterface, StepDataInterface stepDataInterface )
    throws KettleException {
    if ( getData().getExecutorTrans() != null ) {
      getData().getExecutorTrans().stopAll();
    }
  }

  public void stopAll() {
    // Stop the transformation execution.
    if ( getData().getExecutorTrans() != null ) {
      getData().getExecutorTrans().stopAll();
    }

    // Also stop this step
    super.stopAll();
  }

  public Trans getExecutorTrans() {
    return getData().getExecutorTrans();
  }

  @VisibleForTesting
  TransExecutorData getData() {
    return data;
  }

  private void setData( TransExecutorData data ) {
    this.data = data;
  }
}


text:
package mud.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import mud.rulesets.d20.Abilities;

/* Class Array hold classes for whom the skill is a class skill */
public class Skill
{
	private String name;       // name of the skill (string)
	private int id;            // id of the skills (unique integer)
	private Ability ability;   // ability that modifies the skill (string)
	private PClass[] classes;  // array of classes for which this is a class skill

	private static final HashMap<String, Ability> abilityMap = new HashMap<String, Ability>() {
		{
			put("STR", Abilities.STRENGTH);
			put("DEX", Abilities.DEXTERITY);
			put("CON", Abilities.CONSTITUTION);
			put("INT", Abilities.INTELLIGENCE);
			put("WIS", Abilities.WISDOM);
			put("CHA", Abilities.CHARISMA);
		}
	};

	public Skill() {
		this.name = "new_skill";
		this.id = -1;
		this.ability = null;
		this.classes = new PClass[0];
	}

	/**
	 * Class Constructor for Skills
	 *
	 * @param name
	 * @param id
	 * @param ability
	 * @param classes
	 */
	public Skill(final String name, final int id, final String ability, final PClass[] classes) {
		this(name, id, abilityMap.get(ability), classes);
	}

	/**
	 * Class Constructor2 for Skills
	 *
	 * @param name
	 * @param id
	 * @param ability
	 * @param classes
	 */
	public Skill(final String name, final int id, final Ability ability, final PClass[] classes) {
		this.name = name;
		this.id = id;
		this.ability = ability;
		this.classes = classes;
	}

	public String getName() {
		return this.name;
	}

	public Ability getAbility() {
		return this.ability;
	}

	public int getId() {
		return this.id;
	}

	public ArrayList<PClass> getClasses() {
		return new ArrayList<PClass>(Arrays.asList(this.classes));
	}

	public void setClasses(List<PClass> classes) {
		this.classes = classes.toArray(new PClass[classes.size()]);
	}

	public String toString() {
		//return this.name + " " + Arrays.asList(this.classes);
		return this.name;
	}
}


text:
import _ from 'underscore'

export class CodeExtraction {
  constructor(model){
    this.model = model

    this.blocks = {}

    this.elements.map(el => {
      let bucket = this.blocks[el.lang] = this.blocks[el.lang] || []
      bucket.push(el.value)
    })

    let extraction = this

    this.languages.forEach(lang => {
      Object.defineProperty(this, lang, {
        configurable: true,
        get: function(){
          return extraction.blocks[lang]
        }
      })
    })
  }

  get languages(){
    return Object.keys(this.blocks)
  }

  get elements(){
    return this.model.document.getCodeBlocks()
  }
}

export class ExtractionRule {
  type: "single"

  valid: false

  get the(){ return this }

  first(selector){
    this.type = "single"
    this.selector = selector
    return this
  }

  all(selector){
    this.type = "multiple"
    this.selector = selector
    return this
  }

  as(attributeName){
    this.attributeName = attributeName
    this.valid = true
    return this
  }
}


text:
from msrest.serialization import Model

class PropertyBatchOperation(Model):
    """Represents the base type for property operations that can be put into a
    batch and submitted.

    You probably want to use the sub-classes and not this class directly. Known
    sub-classes are: CheckExistsPropertyBatchOperation,
    CheckSequencePropertyBatchOperation, CheckValuePropertyBatchOperation,
    DeletePropertyBatchOperation, GetPropertyBatchOperation,
    PutPropertyBatchOperation

    :param property_name: The name of the Service Fabric property.
    :type property_name: str
    :param kind: Constant filled by server.
    :type kind: str
    """

    _validation = {
        'property_name': {'required': True},
        'kind': {'required': True},
    }

    _attribute_map = {
        'property_name': {'key': 'PropertyName', 'type': 'str'},
        'kind': {'key': 'Kind', 'type': 'str'},
    }

    _subtype_map = {
        'kind': {'CheckExists': 'CheckExistsPropertyBatchOperation', 'CheckSequence': 'CheckSequencePropertyBatchOperation', 'CheckValue': 'CheckValuePropertyBatchOperation', 'Delete': 'DeletePropertyBatchOperation', 'Get': 'GetPropertyBatchOperation', 'Put': 'PutPropertyBatchOperation'}
    }

    def __init__(self, property_name):
        super(PropertyBatchOperation, self).__init__()
        self.property_name = property_name
        self.kind = None


text:
package de.maxikg.osuapi.client.request.builder;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import de.maxikg.osuapi.model.GameMode;
import de.maxikg.osuapi.model.UserScore;
import org.apache.http.client.HttpClient;

import java.util.Collection;

/**
 * @author maxikg
 */
public class DefaultGetUserBestRequestBuilder extends AbstractRequestBuilder implements GetUserBestRequestBuilder {

    private static final String ENDPOINT = "get_user_best";
    private static final String PARAM_USER = "u";
    private static final String PARAM_USER_TYPE = "type";
    private static final String PARAM_MODE = "m";
    private static final String PARAM_LIMIT = "limit";

    public DefaultGetUserBestRequestBuilder(ObjectMapper objectMapper, HttpClient client, String baseUrl, String apiKey, int userId) {
        super(objectMapper, client, baseUrl, apiKey);

        parameters.put(PARAM_USER, userId);
        parameters.put(PARAM_USER_TYPE, "id");
    }

    public DefaultGetUserBestRequestBuilder(ObjectMapper objectMapper, HttpClient client, String baseUrl, String apiKey, String username) {
        super(objectMapper, client, baseUrl, apiKey);

        parameters.put(PARAM_USER, Preconditions.checkNotNull(username, "Required parameter username cannot be null."));
        parameters.put(PARAM_USER_TYPE, "string");
    }

    @Override
    public GetUserBestRequestBuilder mode(GameMode mode) {
        parameters.put(PARAM_MODE, Preconditions.checkNotNull(mode, "mode must be not null. Use unsetMode() to unset mode.").getValue());

        return this;
    }

    @Override
    public GetUserBestRequestBuilder unsetMode() {
        parameters.remove(PARAM_MODE);

        return this;
    }

    @Override
    public GetUserBestRequestBuilder limit(int limit) {
        parameters.put(PARAM_LIMIT, limit);

        return this;
    }

    @Override
    public GetUserBestRequestBuilder unsetLimit() {
        parameters.remove(PARAM_LIMIT);

        return this;
    }

    @Override
    public Collection<UserScore> query() {
        return execute(ENDPOINT, new TypeReference<Collection<UserScore>>() {
        });
    }
}


text:
(function(F){
	F.Filter = F.Class.extend(/** @lends FooTable.Filter */{
		/**
		 * The filter object contains the query to filter by and the columns to apply it to.
		 * @constructs
		 * @extends FooTable.Class
		 * @param {string} name - The name for the filter.
		 * @param {string} query - The query for the filter.
		 * @param {Array.<FooTable.Column>} columns - The columns to apply the query to.
		 * @param {string} [space="AND"] - How the query treats space chars.
		 * @param {boolean} [connectors=true] - Whether or not to replace phrase connectors (+.-_) with spaces.
		 * @returns {FooTable.Filter}
		 */
		construct: function(name, query, columns, space, connectors){
			/**
			 * The name of the filter.
			 * @instance
			 * @type {string}
			 */
			this.name = name;
			/**
			 * A string specifying how the filter treats space characters. Can be either "OR" or "AND".
			 * @instance
			 * @type {string}
			 */
			this.space = F.is.string(space) && (space == 'OR' || space == 'AND') ? space : 'AND';
			/**
			 * Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
			 * @instance
			 * @type {boolean}
			 */
			this.connectors = F.is.boolean(connectors) ? connectors : true;
			/**
			 * The query for the filter.
			 * @instance
			 * @type {(string|FooTable.Query)}
			 */
			this.query = new F.Query(query, this.space, this.connectors);
			/**
			 * The columns to apply the query to.
			 * @instance
			 * @type {Array.<FooTable.Column>}
			 */
			this.columns = columns;
		},
		/**
		 * Checks if the current filter matches the supplied string.
		 * If the current query property is a string it will be auto converted to a {@link FooTable.Query} object to perform the match.
		 * @instance
		 * @param {string} str - The string to check.
		 * @returns {boolean}
		 */
		match: function(str){
			if (!F.is.string(str)) return false;
			if (F.is.string(this.query)){
				this.query = new F.Query(this.query, this.space, this.connectors);
			}
			return this.query instanceof F.Query ? this.query.match(str) : false;
		},
		/**
		 * Checks if the current filter matches the supplied {@link FooTable.Row}.
		 * @instance
		 * @param {FooTable.Row} row - The row to check.
		 * @returns {boolean}
		 */
		matchRow: function(row){
			var self = this, text = F.arr.map(row.cells, function(cell){
				return F.arr.contains(self.columns, cell.column) ? cell.filterValue : null;
			}).join(' ');
			return self.match(text);
		}
	});

})(FooTable);
(function ($, F) {
	F.Filtering = F.Component.extend(/** @lends FooTable.Filtering */{
		/**
		 * The filtering component adds a search input and column selector dropdown to the table allowing users to filter the using space delimited queries.
		 * @constructs
		 * @extends FooTable.Component
		 * @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
		 * @returns {FooTable.Filtering}
		 */
		construct: function (table) {
			// call the constructor of the base class
			this._super(table, table.o.filtering.enabled);

			/* PUBLIC */
			/**
			 * The filters to apply to the current {@link FooTable.Rows#array}.
			 * @instance
			 * @type {Array.<FooTable.Filter>}
			 */
			this.filters = table.o.filtering.filters;
			/**
			 * The delay in milliseconds before the query is auto applied after a change.
			 * @instance
			 * @type {number}
			 */
			this.delay = table.o.filtering.delay;
			/**
			 * The minimum number of characters allowed in the search input before it is auto applied.
			 * @instance
			 * @type {number}
			 */
			this.min = table.o.filtering.min;
			/**
			 * Specifies how whitespace in a filter query is handled.
			 * @instance
			 * @type {string}
			 */
			this.space = table.o.filtering.space;
			/**
			 * Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
			 * @instance
			 * @type {boolean}
			 */
			this.connectors = table.o.filtering.connectors;
			/**
			 * The placeholder text to display within the search $input.
			 * @instance
			 * @type {string}
			 */
			this.placeholder = table.o.filtering.placeholder;
			/**
			 * The position of the $search input within the filtering rows cell.
			 * @type {string}
			 */
			this.position = table.o.filtering.position;
			/**
			 * The jQuery row object that contains all the filtering specific elements.
			 * @instance
			 * @type {jQuery}
			 */
			this.$row = null;
			/**
			 * The jQuery cell object that contains the search input and column selector.
			 * @instance
			 * @type {jQuery}
			 */
			this.$cell = null;
			/**
			 * The jQuery object of the column selector dropdown.
			 * @instance
			 * @type {jQuery}
			 */
			this.$dropdown = null;
			/**
			 * The jQuery object of the search input.
			 * @instance
			 * @type {jQuery}
			 */
			this.$input = null;
			/**
			 * The jQuery object of the search button.
			 * @instance
			 * @type {jQuery}
			 */
			this.$button = null;

			/* PRIVATE */
			/**
			 * The timeout ID for the filter changed event.
			 * @instance
			 * @private
			 * @type {?number}
			 */
			this._filterTimeout = null;
		},

		/* PROTECTED */
		/**
		 * Checks the supplied data and options for the filtering component.
		 * @instance
		 * @protected
		 * @param {object} data - The jQuery data object from the parent table.
		 * @fires FooTable.Filtering#"preinit.ft.filtering"
		 */
		preinit: function(data){
			var self = this;
			/**
			 * The preinit.ft.filtering event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
			 * Calling preventDefault on this event will disable the component.
			 * @event FooTable.Filtering#"preinit.ft.filtering"
			 * @param {jQuery.Event} e - The jQuery.Event object for the event.
			 * @param {FooTable.Table} ft - The instance of the plugin raising the event.
			 * @param {object} data - The jQuery data object of the table raising the event.
			 */
			this.ft.raise('preinit.ft.filtering').then(function(){
				// first check if filtering is enabled via the class being applied
				if (self.ft.$el.hasClass('footable-filtering'))
					self.enabled = true;
				// then check if the data-filtering-enabled attribute has been set
				self.enabled = F.is.boolean(data.filtering)
					? data.filtering
					: self.enabled;

				// if filtering is not enabled exit early as we don't need to do anything else
				if (!self.enabled) return;

				self.space = F.is.string(data.filterSpace)
					? data.filterSpace
					: self.space;

				self.min = F.is.number(data.filterMin)
					? data.filterMin
					: self.min;

				self.connectors = F.is.number(data.filterConnectors)
					? data.filterConnectors
					: self.connectors;

				self.delay = F.is.number(data.filterDelay)
					? data.filterDelay
					: self.delay;

				self.placeholder = F.is.number(data.filterPlaceholder)
					? data.filterPlaceholder
					: self.placeholder;

				self.filters = F.is.array(data.filterFilters)
					? self.ensure(data.filterFilters)
					: self.ensure(self.filters);

				if (self.ft.$el.hasClass('footable-filtering-left'))
					self.position = 'left';
				if (self.ft.$el.hasClass('footable-filtering-center'))
					self.position = 'center';
				if (self.ft.$el.hasClass('footable-filtering-right'))
					self.position = 'right';

				self.position = F.is.string(data.filterPosition)
					? data.filterPosition
					: self.position;
			},function(){
				self.enabled = false;
			});
		},
		/**
		 * Initializes the filtering component for the plugin.
		 * @instance
		 * @protected
		 * @fires FooTable.Filtering#"init.ft.filtering"
		 */
		init: function () {
			var self = this;
			/**
			 * The init.ft.filtering event is raised before its UI is generated.
			 * Calling preventDefault on this event will disable the component.
			 * @event FooTable.Filtering#"init.ft.filtering"
			 * @param {jQuery.Event} e - The jQuery.Event object for the event.
			 * @param {FooTable.Table} ft - The instance of the plugin raising the event.
			 */
			this.ft.raise('init.ft.filtering').then(function(){
				self.$create();
			}, function(){
				self.enabled = false;
			});
		},
		/**
		 * Destroys the filtering component removing any UI from the table.
		 * @instance
		 * @protected
		 * @fires FooTable.Filtering#"destroy.ft.filtering"
		 */
		destroy: function () {
			/**
			 * The destroy.ft.filtering event is raised before its UI is removed.
			 * Calling preventDefault on this event will prevent the component from being destroyed.
			 * @event FooTable.Filtering#"destroy.ft.filtering"
			 * @param {jQuery.Event} e - The jQuery.Event object for the event.
			 * @param {FooTable.Table} ft - The instance of the plugin raising the event.
			 */
			var self = this;
			this.ft.raise('destroy.ft.filtering').then(function(){
				self.ft.$el.removeClass('footable-filtering')
					.find('thead > tr.footable-filtering').remove();
			});
		},
		/**
		 * Creates the filtering UI from the current options setting the various jQuery properties of this component.
		 * @instance
		 * @protected
		 * @this FooTable.Filtering
		 */
		$create: function () {
			var self = this;
			// generate the cell that actually contains all the UI.
			var $form_grp = $('<div/>', {'class': 'form-group'})
					.append($('<label/>', {'class': 'sr-only', text: 'Search'})),
				$input_grp = $('<div/>', {'class': 'input-group'}).appendTo($form_grp),
				$input_grp_btn = $('<div/>', {'class': 'input-group-btn'}),
				$dropdown_toggle = $('<button/>', {type: 'button', 'class': 'btn btn-default dropdown-toggle'})
					.on('click', { self: self }, self._onDropdownToggleClicked)
					.append($('<span/>', {'class': 'caret'})),
				position;

			switch (self.position){
				case 'left': position = 'footable-filtering-left'; break;
				case 'center': position = 'footable-filtering-center'; break;
				default: position = 'footable-filtering-right'; break;
			}
			self.ft.$el.addClass('footable-filtering').addClass(position);

			// add it to a row and then populate it with the search input and column selector dropdown.
			self.$row = $('<tr/>', {'class': 'footable-filtering'}).prependTo(self.ft.$el.children('thead'));
			self.$cell = $('<th/>').attr('colspan', self.ft.columns.visibleColspan).appendTo(self.$row);
			self.$form = $('<form/>', {'class': 'form-inline'}).append($form_grp).appendTo(self.$cell);

			self.$input = $('<input/>', {type: 'text', 'class': 'form-control', placeholder: self.placeholder});

			self.$button = $('<button/>', {type: 'button', 'class': 'btn btn-primary'})
				.on('click', { self: self }, self._onSearchButtonClicked)
				.append($('<span/>', {'class': 'fooicon fooicon-search'}));

			self.$dropdown = $('<ul/>', {'class': 'dropdown-menu dropdown-menu-right'}).append(
				F.arr.map(self.ft.columns.array, function (col) {
					return col.filterable && col.visible ? $('<li/>').append(
						$('<a/>', {'class': 'checkbox'}).append(
							$('<label/>', {text: col.title}).prepend(
								$('<input/>', {type: 'checkbox', checked: true}).data('__FooTableColumn__', col)
							)
						)
					) : null;
				})
			);

			if (self.delay > 0){
				self.$input.on('keypress keyup', { self: self }, self._onSearchInputChanged);
				self.$dropdown.on('click', 'input[type="checkbox"]', {self: self}, self._onSearchColumnClicked);
			}

			$input_grp_btn.append(self.$button, $dropdown_toggle, self.$dropdown);
			$input_grp.append(self.$input, $input_grp_btn);
		},
		/**
		 * Performs the filtering of rows before they are appended to the page.
		 * @instance
		 * @protected
		 */
		predraw: function(){
			if (F.is.emptyArray(this.filters))
				return;

			var self = this;
			self.ft.rows.array = $.grep(self.ft.rows.array, function(r){
				return r.filtered(self.filters);
			});
		},
		/**
		 * As the rows are drawn by the {@link FooTable.Rows#draw} method this simply updates the colspan for the UI.
		 * @instance
		 * @protected
		 */
		draw: function(){
			this.$cell.attr('colspan', this.ft.columns.visibleColspan);
		},

		/* PUBLIC */
		/**
		 * Adds or updates the filter using the supplied name, query and columns.
		 * @param {string} name - The name for the filter.
		 * @param {(string|FooTable.Query)} query - The query for the filter.
		 * @param {(Array.<number>|Array.<string>|Array.<FooTable.Column>)} columns - The columns to apply the filter to.
		 */
		addFilter: function(name, query, columns){
			var f = F.arr.first(this.filters, function(f){ return f.name == name; });
			if (f instanceof F.Filter){
				f.name = name;
				f.query = query;
				f.columns = columns;
			} else {
				this.filters.push({name: name, query: query, columns: columns});
			}
		},
		/**
		 * Removes the filter using the supplied name if it exists.
		 * @param {string} name - The name of the filter to remove.
		 */
		removeFilter: function(name){
			F.arr.remove(this.filters, function(f){ return f.name == name; });
		},
		/**
		 * Creates a new search filter from the supplied parameters and applies it to the rows. If no parameters are supplied the current search input value
		 * and selected columns are used to create or update the search filter. If there is no search input value then the search filter is removed.
		 * @instance
		 * @param {string} [query] - The query to filter the rows by.
		 * @param {(Array.<string>|Array.<number>|Array.<FooTable.Column>)} [columns] - The columns to apply the filter to in each row.
		 * @returns {jQuery.Promise}
		 * @fires FooTable.Filtering#"before.ft.filtering"
		 * @fires FooTable.Filtering#"after.ft.filtering"
		 */
		filter: function(query, columns){
			if (F.is.undef(query)){
				query = $.trim(this.$input.val() || '');
			} else {
				this.$input.val(query);
			}
			if (!F.is.emptyString(query)) {
				this.addFilter('search', query, columns);
			} else {
				this.removeFilter('search');
			}
			this.$button.children('.fooicon').removeClass('fooicon-search').addClass('fooicon-remove');
			return this._filter();
		},
		/**
		 * Removes the current search filter.
		 * @instance
		 * @returns {jQuery.Promise}
		 * @fires FooTable.Filtering#"before.ft.filtering"
		 * @fires FooTable.Filtering#"after.ft.filtering"
		 */
		clear: function(){
			this.$button.children('.fooicon').removeClass('fooicon-remove').addClass('fooicon-search');
			this.$input.val(null);
			this.removeFilter('search');
			return this._filter();
		},
		/**
		 * Gets an array of {@link FooTable.Column} to apply the search filter to. This also doubles as the default columns for filters which do not specify any columns.
		 * @instance
		 * @returns {Array.<FooTable.Column>}
		 */
		columns: function(){
			if (F.is.jq(this.$dropdown)){
				// if we have a dropdown containing the column names get the selected columns from there
				return this.$dropdown.find('input:checked').map(function(){
					return $(this).data('__FooTableColumn__');
				}).get();
			} else {
				// otherwise find all columns that are set to be filterable.
				return this.ft.columns.get(function(c){ return c.filterable; });
			}
		},
		/**
		 * Takes an array of plain objects containing the filter values or actual {@link FooTable.Filter} objects and ensures that an array of only {@link FooTable.Filter} is returned.
		 * If supplied a plain object that object must contain a name, query and columns properties which are used to create a new {@link FooTable.Filter}.
		 * @instance
		 * @param {({name: string, query: (string|FooTable.Query), columns: (Array.<string>|Array.<number>|Array.<FooTable.Column>)}|Array.<FooTable.Filter>)} filters - The array of filters to check.
		 * @returns {Array.<FooTable.Filter>}
		 */
		ensure: function(filters){
			var self = this, parsed = [], filterable = self.columns();
			if (!F.is.emptyArray(filters)){
				F.arr.each(filters, function(f){
					if (F.is.object(f) && (!F.is.emptyString(f.query) || f.query instanceof F.Query)) {
						f.name = F.is.emptyString(f.name) ? 'anon' : f.name;
						f.columns = F.is.emptyArray(f.columns) ? filterable : self.ft.columns.ensure(f.columns);
						parsed.push(f instanceof F.Filter ? f : new F.Filter(f.name, f.query, f.columns, self.space, self.connectors));
					}
				});
			}
			return parsed;
		},

		/* PRIVATE */
		/**
		 * Performs the required steps to handle filtering including the raising of the {@link FooTable.Filtering#"before.ft.filtering"} and {@link FooTable.Filtering#"after.ft.filtering"} events.
		 * @instance
		 * @private
		 * @returns {jQuery.Promise}
		 * @fires FooTable.Filtering#"before.ft.filtering"
		 * @fires FooTable.Filtering#"after.ft.filtering"
		 */
		_filter: function(){
			var self = this;
			self.filters = self.ensure(self.filters);
			/**
			 * The before.ft.filtering event is raised before a filter is applied and allows listeners to modify the filter or cancel it completely by calling preventDefault on the jQuery.Event object.
			 * @event FooTable.Filtering#"before.ft.filtering"
			 * @param {jQuery.Event} e - The jQuery.Event object for the event.
			 * @param {FooTable.Table} ft - The instance of the plugin raising the event.
			 * @param {Array.<FooTable.Filter>} filters - The filters that are about to be applied.
			 */
			return self.ft.raise('before.ft.filtering', [self.filters]).then(function(){
				self.filters = self.ensure(self.filters);
				return self.ft.draw().then(function(){
					/**
					 * The after.ft.filtering event is raised after a filter has been applied.
					 * @event FooTable.Filtering#"after.ft.filtering"
					 * @param {jQuery.Event} e - The jQuery.Event object for the event.
					 * @param {FooTable.Table} ft - The instance of the plugin raising the event.
					 * @param {FooTable.Filter} filter - The filters that were applied.
					 */
					self.ft.raise('after.ft.filtering', [self.filters]);
				});
			});
		},
		/**
		 * Handles the change event for the {@link FooTable.Filtering#$input}.
		 * @instance
		 * @private
		 * @param {jQuery.Event} e - The event object for the event.
		 */
		_onSearchInputChanged: function (e) {
			var self = e.data.self;
			var alpha = e.type == 'keypress' && !F.is.emptyString(String.fromCharCode(e.charCode)),
				ctrl = e.type == 'keyup' && (e.which == 8 || e.which == 46); // backspace & delete

			// if alphanumeric characters or specific control characters
			if(alpha || ctrl) {
				if (e.which == 13) e.preventDefault();
				if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
				self._filterTimeout = setTimeout(function(){
					self._filterTimeout = null;
					self.filter();
				}, self.delay);
			}
		},
		/**
		 * Handles the click event for the {@link FooTable.Filtering#$button}.
		 * @instance
		 * @private
		 * @param {jQuery.Event} e - The event object for the event.
		 */
		_onSearchButtonClicked: function (e) {
			e.preventDefault();
			var self = e.data.self;
			if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
			var $icon = self.$button.children('.fooicon');
			if ($icon.hasClass('fooicon-remove')) self.clear();
			else self.filter();
		},
		/**
		 * Handles the click event for the column checkboxes in the {@link FooTable.Filtering#$dropdown}.
		 * @instance
		 * @private
		 * @param {jQuery.Event} e - The event object for the event.
		 */
		_onSearchColumnClicked: function (e) {
			var self = e.data.self;
			if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
			self._filterTimeout = setTimeout(function(){
				self._filterTimeout = null;
				var $icon = self.$button.children('.fooicon');
				if ($icon.hasClass('fooicon-remove')){
					$icon.removeClass('fooicon-remove').addClass('fooicon-search');
					self.filter();
				}
			}, self.delay);
		},
		/**
		 * Handles the click event for the {@link FooTable.Filtering#$dropdown} toggle.
		 * @instance
		 * @private
		 * @param {jQuery.Event} e - The event object for the event.
		 */
		_onDropdownToggleClicked: function (e) {
			e.preventDefault();
			e.stopPropagation();
			var self = e.data.self;
			self.$dropdown.parent().toggleClass('open');
			if (self.$dropdown.parent().hasClass('open')) $(document).on('click.footable', { self: self }, self._onDocumentClicked);
			else $(document).off('click.footable', self._onDocumentClicked);
		},
		/**
		 * Checks all click events when the dropdown is visible and closes the menu if the target is not the dropdown.
		 * @instance
		 * @private
		 * @param {jQuery.Event} e - The event object for the event.
		 */
		_onDocumentClicked: function(e){
			if ($(e.target).closest('.dropdown-menu').length == 0){
				e.preventDefault();
				var self = e.data.self;
				self.$dropdown.parent().removeClass('open');
				$(document).off('click.footable', self._onDocumentClicked);
			}
		}
	});

	F.components.core.register('filtering', F.Filtering, 10);

})(jQuery, FooTable);
(function(F){
	F.Query = F.Class.extend(/** @lends FooTable.Query */{
		/**
		 * The query object is used to parse and test the filtering component's queries
		 * @constructs
		 * @extends FooTable.Class
		 * @param {string} query - The string value of the query.
		 * @param {string} [space="AND"] - How the query treats whitespace.
		 * @param {boolean} [connectors=true] - Whether or not to replace phrase connectors (+.-_) with spaces.
		 * @returns {FooTable.Query}
		 */
		construct: function(query, space, connectors){
			/* PRIVATE */
			/**
			 * Holds the previous value of the query and is used internally in the {@link FooTable.Query#val} method.
			 * @type {string}
			 * @private
			 */
			this._original = null;
			/**
			 * Holds the value for the query. Access to this variable is provided through the {@link FooTable.Query#val} method.
			 * @type {string}
			 * @private
			 */
			this._value = null;
			/* PUBLIC */
			/**
			 * A string specifying how the query treats whitespace. Can be either "OR" or "AND".
			 * @type {string}
			 */
			this.space = F.is.string(space) && (space == 'OR' || space == 'AND') ? space : 'AND';
			/**
			 * Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
			 * @instance
			 * @type {boolean}
			 */
			this.connectors = F.is.boolean(connectors) ? connectors : true;
			/**
			 * The left side of the query if one exists. OR takes precedence over AND.
			 * @type {FooTable.Query}
			 * @example <caption>The below shows what is meant by the "left" side of a query</caption>
			 * query = "Dave AND Mary" - "Dave" is the left side of the query.
			 * query = "Dave AND Mary OR John" - "Dave and Mary" is the left side of the query.
			 */
			this.left = null;
			/**
			 * The right side of the query if one exists. OR takes precedence over AND.
			 * @type {FooTable.Query}
			 * @example <caption>The below shows what is meant by the "right" side of a query</caption>
			 * query = "Dave AND Mary" - "Mary" is the right side of the query.
			 * query = "Dave AND Mary OR John" - "John" is the right side of the query.
			 */
			this.right = null;
			/**
			 * The parsed parts of the query. This contains the information used to actually perform a match against a string.
			 * @type {Array}
			 */
			this.parts = [];
			/**
			 * The type of operand to apply to the results of the individual parts of the query.
			 * @type {string}
			 */
			this.operator = null;
			this.val(query);
		},
		/**
		 * Gets or sets the value for the query. During set the value is parsed setting all properties as required.
		 * @param {string} [value] - If supplied the value to set for this query.
		 * @returns {(string|undefined)}
		 */
		val: function(value){
			// get
			if (F.is.emptyString(value)) return this._value;

			// set
			if (F.is.emptyString(this._original)) this._original = value;
			else if (this._original == value) return;

			this._value = value;
			this._parse();
		},
		/**
		 * Tests the supplied string against the query.
		 * @param {string} str - The string to test.
		 * @returns {boolean}
		 */
		match: function(str){
			if (F.is.emptyString(this.operator) || this.operator === 'OR')
				return this._left(str, false) || this._match(str, false) || this._right(str, false);
			if (this.operator === 'AND')
				return this._left(str, true) && this._match(str, true) && this._right(str, true);
		},
		/**
		 * Matches this queries parts array against the supplied string.
		 * @param {string} str - The string to test.
		 * @param {boolean} def - The default value to return based on the operand.
		 * @returns {boolean}
		 * @private
		 */
		_match: function(str, def){
			var self = this, result = false;
			if (F.is.emptyArray(self.parts) && self.left instanceof F.Query) return def;
			if (F.is.emptyArray(self.parts)) return result;
			if (self.space === 'OR'){
				// with OR we give the str every part to test and if any match it is a success, we do exit early if a negated match occurs
				F.arr.each(self.parts, function(p){
					var match = F.str.contains(str, p.query, true);
					if (match && !p.negate) result = true;
					if (match && p.negate) {
						result = false;
						return result;
					}
				});
			} else {
				// otherwise with AND we check until the first failure and then exit
				result = true;
				F.arr.each(self.parts, function(p){
					var match = F.str.contains(str, p.query, true);
					if ((!match && !p.negate) || (match && p.negate)) result = false;
					return result;
				});
			}
			return result;
		},
		/**
		 * Matches the left side of the query if one exists with the supplied string.
		 * @param {string} str - The string to test.
		 * @param {boolean} def - The default value to return based on the operand.
		 * @returns {boolean}
		 * @private
		 */
		_left: function(str, def){
			return (this.left instanceof F.Query) ? this.left.match(str) : def;
		},
		/**
		 * Matches the right side of the query if one exists with the supplied string.
		 * @param {string} str - The string to test.
		 * @param {boolean} def - The default value to return based on the operand.
		 * @returns {boolean}
		 * @private
		 */
		_right: function(str, def){
			return (this.right instanceof F.Query) ? this.right.match(str) : def;
		},
		/**
		 * Parses the private {@link FooTable.Query#_value} property and populates the object.
		 * @private
		 */
		_parse: function(){
			if (F.is.emptyString(this._value)) return;
			// OR takes precedence so test for it first
			if (/\sOR\s/.test(this._value)){
				// we have an OR so split the value on the first occurrence of OR to get the left and right sides of the statement
				this.operator = 'OR';
				var or = this._value.split(/(?:\sOR\s)(.*)?/);
				this.left = new F.Query(or[0], this.space, this.connectors);
				this.right = new F.Query(or[1], this.space, this.connectors);
			} else if (/\sAND\s/.test(this._value)) {
				// there are no more OR's so start with AND
				this.operator = 'AND';
				var and = this._value.split(/(?:\sAND\s)(.*)?/);
				this.left = new F.Query(and[0], this.space, this.connectors);
				this.right = new F.Query(and[1], this.space, this.connectors);
			} else {
				// we have no more statements to parse so set the parts array by parsing each part of the remaining query
				var self = this;
				this.parts = F.arr.map(this._value.match(/(?:[^\s"]+|"[^"]*")+/g), function(str){
					return self._part(str);
				});
			}
		},
		/**
		 * Parses a single part of a query into an object to use during matching.
		 * @param {string} str - The string representation of the part.
		 * @returns {{query: string, negate: boolean, phrase: boolean, exact: boolean}}
		 * @private
		 */
		_part: function(str){
			var p = {
				query: str,
				negate: false,
				phrase: false,
				exact: false
			};
			// support for NEGATE operand - (minus sign). Remove this first so we can get onto phrase checking
			if (F.str.startsWith(p.query, '-')){
				p.query = F.str.from(p.query, '-');
				p.negate = true;
			}
			// support for PHRASES (exact matches)
			if (/^"(.*?)"$/.test(p.query)){ // if surrounded in quotes strip them and nothing else
				p.query = p.query.replace(/^"(.*?)"$/, '$1');
				p.phrase = true;
				p.exact = true;
			} else if (this.connectors && /(?:\w)+?([-_\+\.])(?:\w)+?/.test(p.query)) { // otherwise replace supported phrase connectors (-_+.) with spaces
				p.query = p.query.replace(/(?:\w)+?([-_\+\.])(?:\w)+?/g, function(match, p1){
					return match.replace(p1, ' ');
				});
				p.phrase = true;
			}
			return p;
		}
	});

})(FooTable);
(function(F){

	/**
	 * The value used by the filtering component during filter operations. Must be a string and can be set using the data-filter-value attribute on the cell itself.
	 * If this is not supplied it is set to the result of the toString method called on the value for the cell. Added by the {@link FooTable.Filtering} component.
	 * @type {string}
	 * @default null
	 */
	F.Cell.prototype.filterValue = null;

	// this is used to define the filtering specific properties on cell creation
	F.Cell.prototype.__filtering_define__ = function(valueOrElement){
		this.filterValue = this.column.filterValue.call(this.column, valueOrElement);
	};

	// this is used to update the filterValue property whenever the cell value is changed
	F.Cell.prototype.__filtering_val__ = function(value){
		if (F.is.defined(value)){
			// set only
			this.filterValue = this.column.filterValue.call(this.column, value);
		}
	};

	// overrides the public define method and replaces it with our own
	F.Cell.extend('define', function(valueOrElement){
		this._super(valueOrElement);
		this.__filtering_define__(valueOrElement);
	});
	// overrides the public val method and replaces it with our own
	F.Cell.extend('val', function(value){
		var val = this._super(value);
		this.__filtering_val__(value);
		return val;
	});
})(FooTable);
(function($, F){
	/**
	 * Whether or not the column can be used during filtering. Added by the {@link FooTable.Filtering} component.
	 * @type {boolean}
	 * @default true
	 */
	F.Column.prototype.filterable = true;

	/**
	 * This is supplied either the cell value or jQuery object to parse. A string value must be returned from this method and will be used during filtering operations.
	 * @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
	 * @returns {string}
	 * @this FooTable.Column
	 */
	F.Column.prototype.filterValue = function(valueOrElement){
		// if we have an element or a jQuery object use jQuery to get the value
		if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('filterValue') || $(valueOrElement).text();
		// if options are supplied with the value
		if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
			if (F.is.string(valueOrElement.options.filterValue)) return valueOrElement.options.filterValue;
			if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
		}
		if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement+''; // use the native toString of the value
		return ''; // otherwise we have no value so return an empty string
	};

	// this is used to define the filtering specific properties on column creation
	F.Column.prototype.__filtering_define__ = function(definition){
		this.filterable = F.is.boolean(definition.filterable) ? definition.filterable : this.filterable;
	};

	// overrides the public define method and replaces it with our own
	F.Column.extend('define', function(definition){
		this._super(definition); // call the base so we don't have to redefine any previously set properties
		this.__filtering_define__(definition); // then call our own
	});
})(jQuery, FooTable);
(function(F){
	/**
	 * An object containing the filtering options for the plugin. Added by the {@link FooTable.Filtering} component.
	 * @type {object}
	 * @prop {boolean} enabled=false - Whether or not to allow filtering on the table.
	 * @prop {({name: string, query: (string|FooTable.Query), columns: (Array.<string>|Array.<number>|Array.<FooTable.Column>)}|Array.<FooTable.Filter>)} filters - The filters to apply to the current {@link FooTable.Rows#array}.
	 * @prop {number} delay=1200 - The delay in milliseconds before the query is auto applied after a change (any value equal to or less than zero will disable this).
	 * @prop {number} min=3 - The minimum number of characters allowed in the search input before it is auto applied.
	 * @prop {string} space="AND" - Specifies how whitespace in a filter query is handled.
	 * @prop {string} placeholder="Search" - The string used as the placeholder for the search input.
	 * @prop {string} position="right" - The string used to specify the alignment of the search input.
	 * @prop {string} connectors=true - Whether or not to replace phrase connectors (+.-_) with space before executing the query.
	 */
	F.Defaults.prototype.filtering = {
		enabled: false,
		filters: [],
		delay: 1200,
		min: 3,
		space: 'AND',
		placeholder: 'Search',
		position: 'right',
		connectors: true
	};
})(FooTable);
(function(F){
	/**
	 * Checks if the row is filtered using the supplied filters.
	 * @this FooTable.Row
	 * @param {Array.<FooTable.Filter>} filters - The filters to apply.
	 * @returns {boolean}
	 */
	F.Row.prototype.filtered = function(filters){
		var result = true, self = this;
		F.arr.each(filters, function(f){
			if ((result = f.matchRow(self)) == false) return false;
		});
		return result;
	};
})(FooTable);
(function(F){
	/**
	 * Filter the table using the supplied query and columns. Added by the {@link FooTable.Filtering} component.
	 * @instance
	 * @param {string} query - The query to filter the rows by.
	 * @param {(Array.<string>|Array.<number>|Array.<FooTable.Column>)} [columns] - The columns to apply the filter to in each row.
	 * @returns {jQuery.Promise}
	 * @fires FooTable.Filtering#before.ft.filtering
	 * @fires FooTable.Filtering#after.ft.filtering
	 * @see FooTable.Filtering#filter
	 */
	F.Table.prototype.applyFilter = function(query, columns){
		return this.use(F.Filtering).filter(query, columns);
	};

	/**
	 * Clear the current filter from the table. Added by the {@link FooTable.Filtering} component.
	 * @instance
	 * @returns {jQuery.Promise}
	 * @fires FooTable.Filtering#before.ft.filtering
	 * @fires FooTable.Filtering#after.ft.filtering
	 * @see FooTable.Filtering#clear
	 */
	F.Table.prototype.clearFilter = function(){
		return this.use(F.Filtering).clear();
	};
})(FooTable);


text:
layout: post
title: {{title}}
description:
date: {{date}}
comments: true
categories: blog
published: false
tags:
---