text:
<?php
/**
 * Comment API: WP_Comment_Query class
 *
 * @package WordPress
 * @subpackage Comments
 * @since 4.4.0
 */

/**
 * Core class used for querying comments.
 *
 * @since 3.1.0
 *
 * @see WP_Comment_Query::__construct() for accepted arguments.
 */
class WP_Comment_Query {

	/**
	 * SQL for database query.
	 *
	 * @since 4.0.1
	 * @access public
	 * @var string
	 */
	public $request;

	/**
	 * Metadata query container
	 *
	 * @since 3.5.0
	 * @access public
	 * @var object WP_Meta_Query
	 */
	public $meta_query = false;

	/**
	 * Metadata query clauses.
	 *
	 * @since 4.4.0
	 * @access protected
	 * @var array
	 */
	protected $meta_query_clauses;

	/**
	 * Date query container
	 *
	 * @since 3.7.0
	 * @access public
	 * @var object WP_Date_Query
	 */
	public $date_query = false;

	/**
	 * Query vars set by the user.
	 *
	 * @since 3.1.0
	 * @access public
	 * @var array
	 */
	public $query_vars;

	/**
	 * Default values for query vars.
	 *
	 * @since 4.2.0
	 * @access public
	 * @var array
	 */
	public $query_var_defaults;

	/**
	 * List of comments located by the query.
	 *
	 * @since 4.0.0
	 * @access public
	 * @var array
	 */
	public $comments;

	/**
	 * Make private/protected methods readable for backwards compatibility.
	 *
	 * @since 4.0.0
	 * @access public
	 *
	 * @param callable $name      Method to call.
	 * @param array    $arguments Arguments to pass when calling.
	 * @return mixed|false Return value of the callback, false otherwise.
	 */
	public function __call( $name, $arguments ) {
		if ( 'get_search_sql' === $name ) {
			return call_user_func_array( array( $this, $name ), $arguments );
		}
		return false;
	}

	/**
	 * Constructor.
	 *
	 * Sets up the comment query, based on the query vars passed.
	 *
	 * @since 4.2.0
	 * @since 4.4.0 `$parent__in` and `$parent__not_in` were added.
	 * @since 4.4.0 Order by `comment__in` was added. `$update_comment_meta_cache` was added.
	 * @access public
	 *
	 * @param string|array $query {
	 *     Optional. Array or query string of comment query parameters. Default empty.
	 *
	 *     @type string       $author_email        Comment author email address. Default empty.
	 *     @type array        $author__in          Array of author IDs to include comments for. Default empty.
	 *     @type array        $author__not_in      Array of author IDs to exclude comments for. Default empty.
	 *     @type array        $comment__in         Array of comment IDs to include. Default empty.
	 *     @type array        $comment__not_in     Array of comment IDs to exclude. Default empty.
	 *     @type bool         $count               Whether to return a comment count (true) or array of comment
	 *                                             objects (false). Default false.
	 *     @type array        $date_query          Date query clauses to limit comments by. See WP_Date_Query.
	 *                                             Default null.
	 *     @type string       $fields              Comment fields to return. Accepts 'ids' for comment IDs only or
	 *                                             empty for all fields. Default empty.
	 *     @type int          $ID                  Currently unused.
	 *     @type array        $include_unapproved  Array of IDs or email addresses of users whose unapproved comments
	 *                                             will be returned by the query regardless of `$status`. Default empty.
	 *     @type int          $karma               Karma score to retrieve matching comments for. Default empty.
	 *     @type string       $meta_key            Include comments with a matching comment meta key. Default empty.
	 *     @type string       $meta_value          Include comments with a matching comment meta value. Requires
	 *                                             `$meta_key` to be set. Default empty.
	 *     @type array        $meta_query          Meta query clauses to limit retrieved comments by.
	 *                                             See WP_Meta_Query. Default empty.
	 *     @type int          $number              Maximum number of comments to retrieve. Default null (no limit).
	 *     @type int          $offset              Number of comments to offset the query. Used to build LIMIT clause.
	 *                                             Default 0.
	 *     @type string|array $orderby             Comment status or array of statuses. To use 'meta_value' or
	 *                                             'meta_value_num', `$meta_key` must also be defined. To sort by
	 *                                             a specific `$meta_query` clause, use that clause's array key.
	 *                                             Accepts 'comment_agent', 'comment_approved', 'comment_author',
	 *                                             'comment_author_email', 'comment_author_IP',
	 *                                             'comment_author_url', 'comment_content', 'comment_date',
	 *                                             'comment_date_gmt', 'comment_ID', 'comment_karma',
	 *                                             'comment_parent', 'comment_post_ID', 'comment_type', 'user_id',
	 *                                             'comment__in', 'meta_value', 'meta_value_num', the value of $meta_key, and the
	 *                                             array keys of `$meta_query`. Also accepts false, an empty array,
	 *                                             or 'none' to disable `ORDER BY` clause.
	 *                                             Default: 'comment_date_gmt'.
	 *     @type string       $order               How to order retrieved comments. Accepts 'ASC', 'DESC'.
	 *                                             Default: 'DESC'.
	 *     @type int          $parent              Parent ID of comment to retrieve children of. Default empty.
	 *     @type array        $parent__in          Array of parent IDs of comments to retrieve children for. Default empty.
	 *     @type array        $parent__not_in      Array of parent IDs of comments *not* to retrieve children for. Default empty.
	 *     @type array        $post_author__in     Array of author IDs to retrieve comments for. Default empty.
	 *     @type array        $post_author__not_in Array of author IDs *not* to retrieve comments for. Default empty.
	 *     @type int          $post_ID             Currently unused.
	 *     @type int          $post_id             Limit results to those affiliated with a given post ID. Default 0.
	 *     @type array        $post__in            Array of post IDs to include affiliated comments for. Default empty.
	 *     @type array        $post__not_in        Array of post IDs to exclude affiliated comments for. Default empty.
	 *     @type int          $post_author         Comment author ID to limit results by. Default empty.
	 *     @type string       $post_status         Post status to retrieve affiliated comments for. Default empty.
	 *     @type string       $post_type           Post type to retrieve affiliated comments for. Default empty.
	 *     @type string       $post_name           Post name to retrieve affiliated comments for. Default empty.
	 *     @type int          $post_parent         Post parent ID to retrieve affiliated comments for. Default empty.
	 *     @type string       $search              Search term(s) to retrieve matching comments for. Default empty.
	 *     @type string       $status              Comment status to limit results by. Accepts 'hold'
	 *                                             (`comment_status=0`), 'approve' (`comment_status=1`), 'all', or a
	 *                                             custom comment status. Default 'all'.
	 *     @type string|array $type                Include comments of a given type, or array of types. Accepts
	 *                                             'comment', 'pings' (includes 'pingback' and 'trackback'), or any
	 *                                             custom type string. Default empty.
	 *     @type array        $type__in            Include comments from a given array of comment types. Default empty.
	 *     @type array        $type__not_in        Exclude comments from a given array of comment types. Default empty.
	 *     @type int          $user_id             Include comments for a specific user ID. Default empty.
	 *     @type bool         $update_comment_meta_cache Whether to prime the metadata cache for found comments.
	 *                                                   Default true.
	 * }
	 */
	public function __construct( $query = '' ) {
		$this->query_var_defaults = array(
			'author_email' => '',
			'author__in' => '',
			'author__not_in' => '',
			'include_unapproved' => '',
			'fields' => '',
			'ID' => '',
			'comment__in' => '',
			'comment__not_in' => '',
			'karma' => '',
			'number' => '',
			'offset' => '',
			'orderby' => '',
			'order' => 'DESC',
			'parent' => '',
			'post_author__in' => '',
			'post_author__not_in' => '',
			'post_ID' => '',
			'post_id' => 0,
			'post__in' => '',
			'post__not_in' => '',
			'post_author' => '',
			'post_name' => '',
			'post_parent' => '',
			'post_status' => '',
			'post_type' => '',
			'status' => 'all',
			'type' => '',
			'type__in' => '',
			'type__not_in' => '',
			'user_id' => '',
			'search' => '',
			'count' => false,
			'meta_key' => '',
			'meta_value' => '',
			'meta_query' => '',
			'date_query' => null, // See WP_Date_Query
			'update_comment_meta_cache' => true,
		);

		if ( ! empty( $query ) ) {
			$this->query( $query );
		}
	}

	/**
	 * Parse arguments passed to the comment query with default query parameters.
	 *
	 * @since  4.2.0 Extracted from WP_Comment_Query::query().
	 *
	 * @access public
	 *
	 * @param string|array $query WP_Comment_Query arguments. See WP_Comment_Query::__construct()
	 */
	public function parse_query( $query = '' ) {
		if ( empty( $query ) ) {
			$query = $this->query_vars;
		}

		$this->query_vars = wp_parse_args( $query, $this->query_var_defaults );
		do_action_ref_array( 'parse_comment_query', array( &$this ) );
	}

	/**
	 * Sets up the WordPress query for retrieving comments.
	 *
	 * @since 3.1.0
	 * @since 4.1.0 Introduced 'comment__in', 'comment__not_in', 'post_author__in',
	 *              'post_author__not_in', 'author__in', 'author__not_in', 'post__in',
	 *              'post__not_in', 'include_unapproved', 'type__in', and 'type__not_in'
	 *              arguments to $query_vars.
	 * @since 4.2.0 Moved parsing to WP_Comment_Query::parse_query().
	 * @access public
	 *
	 * @param string|array $query Array or URL query string of parameters.
	 * @return array|int List of comments, or number of comments when 'count' is passed as a query var.
	 */
	public function query( $query ) {
		$this->query_vars = wp_parse_args( $query );
		return $this->get_comments();
	}

	/**
	 * Get a list of comments matching the query vars.
	 *
	 * @since 4.2.0
	 * @access public
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @return int|array The list of comments.
	 */
	public function get_comments() {
		global $wpdb;

		$this->parse_query();

		// Parse meta query
		$this->meta_query = new WP_Meta_Query();
		$this->meta_query->parse_query_vars( $this->query_vars );

		/**
		 * Fires before comments are retrieved.
		 *
		 * @since 3.1.0
		 *
		 * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
		 */
		do_action_ref_array( 'pre_get_comments', array( &$this ) );

		// Reparse query vars, in case they were modified in a 'pre_get_comments' callback.
		$this->meta_query->parse_query_vars( $this->query_vars );
		if ( ! empty( $this->meta_query->queries ) ) {
			$this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
		}

		// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
		$key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
		$last_changed = wp_cache_get( 'last_changed', 'comment' );
		if ( ! $last_changed ) {
			$last_changed = microtime();
			wp_cache_set( 'last_changed', $last_changed, 'comment' );
		}
		$cache_key = "get_comment_ids:$key:$last_changed";

		$comment_ids = wp_cache_get( $cache_key, 'comment' );
		if ( false === $comment_ids ) {
			$comment_ids = $this->get_comment_ids();
			wp_cache_add( $cache_key, $comment_ids, 'comment' );
		}

		// If querying for a count only, there's nothing more to do.
		if ( $this->query_vars['count'] ) {
			// $comment_ids is actually a count in this case.
			return intval( $comment_ids );
		}

		$comment_ids = array_map( 'intval', $comment_ids );

		if ( 'ids' == $this->query_vars['fields'] ) {
			$this->comments = $comment_ids;
			return $this->comments;
		}

		_prime_comment_caches( $comment_ids, $this->query_vars['update_comment_meta_cache'] );

		// Fetch full comment objects from the primed cache.
		$_comments = array();
		foreach ( $comment_ids as $comment_id ) {
			if ( $_comment = wp_cache_get( $comment_id, 'comment' ) ) {
				$_comments[] = $_comment;
			}
		}

		/**
		 * Filter the comment query results.
		 *
		 * @since 3.1.0
		 *
		 * @param array            $results  An array of comments.
		 * @param WP_Comment_Query &$this    Current instance of WP_Comment_Query, passed by reference.
		 */
		$_comments = apply_filters_ref_array( 'the_comments', array( $_comments, &$this ) );

		// Convert to WP_Comment instances
		$comments = array_map( 'get_comment', $_comments );

		$this->comments = $comments;
		return $this->comments;
	}

	/**
	 * Used internally to get a list of comment IDs matching the query vars.
	 *
	 * @since 4.4.0
	 * @access protected
	 *
	 * @global wpdb $wpdb
	 */
	protected function get_comment_ids() {
		global $wpdb;

		$groupby = '';
		$where = array();

		// Assemble clauses related to 'comment_approved'.
		$approved_clauses = array();

		// 'status' accepts an array or a comma-separated string.
		$status_clauses = array();
		$statuses = $this->query_vars['status'];
		if ( ! is_array( $statuses ) ) {
			$statuses = preg_split( '/[\s,]+/', $statuses );
		}

		// 'any' overrides other statuses.
		if ( ! in_array( 'any', $statuses ) ) {
			foreach ( $statuses as $status ) {
				switch ( $status ) {
					case 'hold' :
						$status_clauses[] = "comment_approved = '0'";
						break;

					case 'approve' :
						$status_clauses[] = "comment_approved = '1'";
						break;

					case 'all' :
					case '' :
						$status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )";
						break;

					default :
						$status_clauses[] = $wpdb->prepare( "comment_approved = %s", $status );
						break;
				}
			}

			if ( ! empty( $status_clauses ) ) {
				$approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )';
			}
		}

		// User IDs or emails whose unapproved comments are included, regardless of $status.
		if ( ! empty( $this->query_vars['include_unapproved'] ) ) {
			$include_unapproved = $this->query_vars['include_unapproved'];

			// Accepts arrays or comma-separated strings.
			if ( ! is_array( $include_unapproved ) ) {
				$include_unapproved = preg_split( '/[\s,]+/', $include_unapproved );
			}

			$unapproved_ids = $unapproved_emails = array();
			foreach ( $include_unapproved as $unapproved_identifier ) {
				// Numeric values are assumed to be user ids.
				if ( is_numeric( $unapproved_identifier ) ) {
					$approved_clauses[] = $wpdb->prepare( "( user_id = %d AND comment_approved = '0' )", $unapproved_identifier );

				// Otherwise we match against email addresses.
				} else {
					$approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier );
				}
			}
		}

		// Collapse comment_approved clauses into a single OR-separated clause.
		if ( ! empty( $approved_clauses ) ) {
			if ( 1 === count( $approved_clauses ) ) {
				$where[] = $approved_clauses[0];
			} else {
				$where[] = '( ' . implode( ' OR ', $approved_clauses ) . ' )';
			}
		}

		$order = ( 'ASC' == strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';

		// Disable ORDER BY with 'none', an empty array, or boolean false.
		if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) {
			$orderby = '';
		} elseif ( ! empty( $this->query_vars['orderby'] ) ) {
			$ordersby = is_array( $this->query_vars['orderby'] ) ?
				$this->query_vars['orderby'] :
				preg_split( '/[,\s]/', $this->query_vars['orderby'] );

			$orderby_array = array();
			$found_orderby_comment_ID = false;
			foreach ( $ordersby as $_key => $_value ) {
				if ( ! $_value ) {
					continue;
				}

				if ( is_int( $_key ) ) {
					$_orderby = $_value;
					$_order = $order;
				} else {
					$_orderby = $_key;
					$_order = $_value;
				}

				if ( ! $found_orderby_comment_ID && in_array( $_orderby, array( 'comment_ID', 'comment__in' ) ) ) {
					$found_orderby_comment_ID = true;
				}

				$parsed = $this->parse_orderby( $_orderby );

				if ( ! $parsed ) {
					continue;
				}

				if ( 'comment__in' === $_orderby ) {
					$orderby_array[] = $parsed;
					continue;
				}

				$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
			}

			// If no valid clauses were found, order by comment_date_gmt.
			if ( empty( $orderby_array ) ) {
				$orderby_array[] = "$wpdb->comments.comment_date_gmt $order";
			}

			// To ensure determinate sorting, always include a comment_ID clause.
			if ( ! $found_orderby_comment_ID ) {
				$comment_ID_order = '';

				// Inherit order from comment_date or comment_date_gmt, if available.
				foreach ( $orderby_array as $orderby_clause ) {
					if ( preg_match( '/comment_date(?:_gmt)*\ (ASC|DESC)/', $orderby_clause, $match ) ) {
						$comment_ID_order = $match[1];
						break;
					}
				}

				// If no date-related order is available, use the date from the first available clause.
				if ( ! $comment_ID_order ) {
					foreach ( $orderby_array as $orderby_clause ) {
						if ( false !== strpos( 'ASC', $orderby_clause ) ) {
							$comment_ID_order = 'ASC';
						} else {
							$comment_ID_order = 'DESC';
						}

						break;
					}
				}

				// Default to DESC.
				if ( ! $comment_ID_order ) {
					$comment_ID_order = 'DESC';
				}

				$orderby_array[] = "$wpdb->comments.comment_ID $comment_ID_order";
			}

			$orderby = implode( ', ', $orderby_array );
		} else {
			$orderby = "$wpdb->comments.comment_date_gmt $order";
		}

		$number = absint( $this->query_vars['number'] );
		$offset = absint( $this->query_vars['offset'] );

		if ( ! empty( $number ) ) {
			if ( $offset ) {
				$limits = 'LIMIT ' . $offset . ',' . $number;
			} else {
				$limits = 'LIMIT ' . $number;
			}
		} else {
			$limits = '';
		}

		if ( $this->query_vars['count'] ) {
			$fields = 'COUNT(*)';
		} else {
			$fields = "$wpdb->comments.comment_ID";
		}

		$join = '';

		$post_id = absint( $this->query_vars['post_id'] );
		if ( ! empty( $post_id ) ) {
			$where[] = $wpdb->prepare( 'comment_post_ID = %d', $post_id );
		}

		// Parse comment IDs for an IN clause.
		if ( ! empty( $this->query_vars['comment__in'] ) ) {
			$where[] = "$wpdb->comments.comment_ID IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )';
		}

		// Parse comment IDs for a NOT IN clause.
		if ( ! empty( $this->query_vars['comment__not_in'] ) ) {
			$where[] = "$wpdb->comments.comment_ID NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )';
		}

		// Parse comment parent IDs for an IN clause.
		if ( ! empty( $this->query_vars['parent__in'] ) ) {
			$where[] = 'comment_parent IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__in'] ) ) . ' )';
		}

		// Parse comment parent IDs for a NOT IN clause.
		if ( ! empty( $this->query_vars['parent__not_in'] ) ) {
			$where[] = 'comment_parent NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__not_in'] ) ) . ' )';
		}

		// Parse comment post IDs for an IN clause.
		if ( ! empty( $this->query_vars['post__in'] ) ) {
			$where[] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )';
		}

		// Parse comment post IDs for a NOT IN clause.
		if ( ! empty( $this->query_vars['post__not_in'] ) ) {
			$where[] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )';
		}

		if ( '' !== $this->query_vars['author_email'] ) {
			$where[] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] );
		}

		if ( '' !== $this->query_vars['karma'] ) {
			$where[] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] );
		}

		// Filtering by comment_type: 'type', 'type__in', 'type__not_in'.
		$raw_types = array(
			'IN' => array_merge( (array) $this->query_vars['type'], (array) $this->query_vars['type__in'] ),
			'NOT IN' => (array) $this->query_vars['type__not_in'],
		);

		$comment_types = array();
		foreach ( $raw_types as $operator => $_raw_types ) {
			$_raw_types = array_unique( $_raw_types );

			foreach ( $_raw_types as $type ) {
				switch ( $type ) {
					// An empty translates to 'all', for backward compatibility
					case '':
					case 'all' :
						break;

					case 'comment':
					case 'comments':
						$comment_types[ $operator ][] = "''";
						break;

					case 'pings':
						$comment_types[ $operator ][] = "'pingback'";
						$comment_types[ $operator ][] = "'trackback'";
						break;

					default:
						$comment_types[ $operator ][] = $wpdb->prepare( '%s', $type );
						break;
				}
			}

			if ( ! empty( $comment_types[ $operator ] ) ) {
				$types_sql = implode( ', ', $comment_types[ $operator ] );
				$where[] = "comment_type $operator ($types_sql)";
			}
		}

		if ( '' !== $this->query_vars['parent'] ) {
			$where[] = $wpdb->prepare( 'comment_parent = %d', $this->query_vars['parent'] );
		}

		if ( is_array( $this->query_vars['user_id'] ) ) {
			$where[] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')';
		} elseif ( '' !== $this->query_vars['user_id'] ) {
			$where[] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] );
		}

		if ( '' !== $this->query_vars['search'] ) {
			$search_sql = $this->get_search_sql(
				$this->query_vars['search'],
				array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' )
			);

			// Strip leading 'AND'.
			$where[] = preg_replace( '/^\s*AND\s*/', '', $search_sql );
		}

		// If any post-related query vars are passed, join the posts table.
		$join_posts_table = false;
		$plucked = wp_array_slice_assoc( $this->query_vars, array( 'post_author', 'post_name', 'post_parent', 'post_status', 'post_type' ) );
		$post_fields = array_filter( $plucked );

		if ( ! empty( $post_fields ) ) {
			$join_posts_table = true;
			foreach ( $post_fields as $field_name => $field_value ) {
				// $field_value may be an array.
				$esses = array_fill( 0, count( (array) $field_value ), '%s' );
				$where[] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $field_value );
			}
		}

		// Comment author IDs for an IN clause.
		if ( ! empty( $this->query_vars['author__in'] ) ) {
			$where[] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )';
		}

		// Comment author IDs for a NOT IN clause.
		if ( ! empty( $this->query_vars['author__not_in'] ) ) {
			$where[] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )';
		}

		// Post author IDs for an IN clause.
		if ( ! empty( $this->query_vars['post_author__in'] ) ) {
			$join_posts_table = true;
			$where[] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )';
		}

		// Post author IDs for a NOT IN clause.
		if ( ! empty( $this->query_vars['post_author__not_in'] ) ) {
			$join_posts_table = true;
			$where[] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )';
		}

		if ( $join_posts_table ) {
			$join = "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
		}

		if ( ! empty( $this->meta_query_clauses ) ) {
			$join .= $this->meta_query_clauses['join'];

			// Strip leading 'AND'.
			$where[] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] );

			if ( ! $this->query_vars['count'] ) {
				$groupby = "{$wpdb->comments}.comment_ID";
			}
		}

		$date_query = $this->query_vars['date_query'];
		if ( ! empty( $date_query ) && is_array( $date_query ) ) {
			$date_query_object = new WP_Date_Query( $date_query, 'comment_date' );
			$where[] = preg_replace( '/^\s*AND\s*/', '', $date_query_object->get_sql() );
		}

		$where = implode( ' AND ', $where );

		$pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
		/**
		 * Filter the comment query clauses.
		 *
		 * @since 3.1.0
		 *
		 * @param array            $pieces A compacted array of comment query clauses.
		 * @param WP_Comment_Query &$this  Current instance of WP_Comment_Query, passed by reference.
		 */
		$clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) );

		$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
		$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
		$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
		$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
		$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
		$groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';

		if ( $where ) {
			$where = 'WHERE ' . $where;
		}

		if ( $groupby ) {
			$groupby = 'GROUP BY ' . $groupby;
		}

		if ( $orderby ) {
			$orderby = "ORDER BY $orderby";
		}

		$this->request = "SELECT $fields FROM $wpdb->comments $join $where $groupby $orderby $limits";

		if ( $this->query_vars['count'] ) {
			return intval( $wpdb->get_var( $this->request ) );
		} else {
			$comment_ids = $wpdb->get_col( $this->request );
			return array_map( 'intval', $comment_ids );
		}
	}

	/**
	 * Used internally to generate an SQL string for searching across multiple columns
	 *
	 * @since 3.1.0
	 * @access protected
	 *
	 * @global wpdb $wpdb
	 *
	 * @param string $string
	 * @param array $cols
	 * @return string
	 */
	protected function get_search_sql( $string, $cols ) {
		global $wpdb;

		$like = '%' . $wpdb->esc_like( $string ) . '%';

		$searches = array();
		foreach ( $cols as $col ) {
			$searches[] = $wpdb->prepare( "$col LIKE %s", $like );
		}

		return ' AND (' . implode(' OR ', $searches) . ')';
	}

	/**
	 * Parse and sanitize 'orderby' keys passed to the comment query.
	 *
	 * @since 4.2.0
	 * @access protected
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $orderby Alias for the field to order by.
	 * @return string|false Value to used in the ORDER clause. False otherwise.
	 */
	protected function parse_orderby( $orderby ) {
		global $wpdb;

		$allowed_keys = array(
			'comment_agent',
			'comment_approved',
			'comment_author',
			'comment_author_email',
			'comment_author_IP',
			'comment_author_url',
			'comment_content',
			'comment_date',
			'comment_date_gmt',
			'comment_ID',
			'comment_karma',
			'comment_parent',
			'comment_post_ID',
			'comment_type',
			'user_id',
		);

		if ( ! empty( $this->query_vars['meta_key'] ) ) {
			$allowed_keys[] = $this->query_vars['meta_key'];
			$allowed_keys[] = 'meta_value';
			$allowed_keys[] = 'meta_value_num';
		}

		$meta_query_clauses = $this->meta_query->get_clauses();
		if ( $meta_query_clauses ) {
			$allowed_keys = array_merge( $allowed_keys, array_keys( $meta_query_clauses ) );
		}

		$parsed = false;
		if ( $orderby == $this->query_vars['meta_key'] || $orderby == 'meta_value' ) {
			$parsed = "$wpdb->commentmeta.meta_value";
		} elseif ( $orderby == 'meta_value_num' ) {
			$parsed = "$wpdb->commentmeta.meta_value+0";
		} elseif ( $orderby == 'comment__in' ) {
			$comment__in = implode( ',', array_map( 'absint', $this->query_vars['comment__in'] ) );
			$parsed = "FIELD( {$wpdb->comments}.comment_ID, $comment__in )";
		} elseif ( in_array( $orderby, $allowed_keys ) ) {

			if ( isset( $meta_query_clauses[ $orderby ] ) ) {
				$meta_clause = $meta_query_clauses[ $orderby ];
				$parsed = sprintf( "CAST(%s.meta_value AS %s)", esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) );
			} else {
				$parsed = "$wpdb->comments.$orderby";
			}
		}

		return $parsed;
	}

	/**
	 * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
	 *
	 * @since 4.2.0
	 * @access protected
	 *
	 * @param string $order The 'order' query variable.
	 * @return string The sanitized 'order' query variable.
	 */
	protected function parse_order( $order ) {
		if ( ! is_string( $order ) || empty( $order ) ) {
			return 'DESC';
		}

		if ( 'ASC' === strtoupper( $order ) ) {
			return 'ASC';
		} else {
			return 'DESC';
		}
	}
}


text:
package com.almasb.common.net;

import java.io.Serializable;

/**
 * Unified data packet used by both UDP and TCP connections
 * If a DataPacket was received it is guaranteed that no null
 * data will be present, i.e. there is no need to check for null in stringData or byteData, etc
 *
 * Note: an empty packet's size is currently 499 bytes
 * Note: excessive use of short names allows smaller size of the serialized version
 *
 *
 * @author Almas
 * @version 1.4
 *
 *          v 1.1 - added signature fromServer
 *          v 1.2 - simplified packet
 *                  construction, it is no longer required to specify who sent the packet
 *                  depending on end of connection, the sender will
 *                  sign the packet with appropriate signature
 *          v 1.3 - added objectData, now datapacket can carry serializable objects
 *                  fixed wrong javadoc comments
 *                  support for sending arrays
 *          v 1.4 - added "ip" and port fields and accessors to hold ip of the sender
 *                  if you are the sender ip is empty string and port 0
 */
public class DataPacket implements Serializable {

    /**
     * Serializable
     */
    private static final long serialVersionUID = 3256232093228720518L;

    enum Signature {
        NONE, SERVER, CLIENT
    }

    /**
     * Identifies who sent the packet
     */
    private Signature signature = Signature.NONE;

    /**
     * Holds value in milliseconds when the packet was sent
     * To be precise when packet was signed
     * It is up to the user to sign just before sending
     *
     */
    private long timeSent = 0;

    /**
     * Shows where packet came from
     * The packet that is being sent has empty string instead of IP
     */
    private transient String ip = "";

    /**
     * Shows where packet came from
     * The packet that is being sent has 0 as port
     */
    private transient int port = 0;

    /**
     * Data carried in a String, separate from {@link #byteData} Useful for
     * sending text
     */
    public final String stringData;

    /**
     * Data carried in a byte array, separate from {@link #stringData} Useful
     * for sending files or raw bytes
     */
    public final byte[] byteData;

    /**
     * Data carried as an object, the receiver MUST check if it's the type
     * they are expecting, for example use "instanceof"
     *
     * The object MUST also be a serializable object otherwise exceptions
     * might be thrown
     */
    public final Serializable objectData;

    /**
     * Data carried as an array of objects, the receiver MUST check if it's the type
     * they are expecting, for example use "instanceof"
     *
     * The object MUST also be a serializable object otherwise exceptions
     * might be thrown
     */
    public final Serializable[] multipleObjectData;

    /**
     * Constructs a packet with given type which carries byte data
     *
     * @param byteData
     */
    public DataPacket(byte[] byteData) {
        this("", byteData, new S(), new Serializable[] {});
    }

    /**
     * Constructs a packet with given type which carries string data
     *
     * @param stringData
     */
    public DataPacket(String stringData) {
        this(stringData, new byte[] {}, new S(), new Serializable[] {});
    }

    /**
     * Constructs a packet with given object data
     *
     * @param objectData
     */
    public DataPacket(Serializable objectData) {
        this("", new byte[] {}, objectData, new Serializable[] {});
    }

    /**
     * Constructs a packet with given object data
     *
     * @param multipleObjectsData
     */
    public DataPacket(Serializable[] multipleObjectData) {
        this("", new byte[] {}, new S(), multipleObjectData);
    }

    /**
     * Constructs a packet with given type which carries byte data,
     * string data and object data
     *
     * @param stringData
     * @param byteData
     * @param objectData
     * @param multipleObjectData
     */
    public DataPacket(String stringData, byte[] byteData, Serializable objectData, Serializable[] multipleObjectData) {
        this.stringData = stringData;
        this.byteData = byteData;
        this.objectData = objectData;
        this.multipleObjectData = multipleObjectData;
    }

    /**
     * Constructs a packet with given type which carries byte data,
     * string data and object data
     *
     * @param stringData
     * @param byteData
     */
    public DataPacket(String stringData, byte[] byteData) {
        this(stringData, byteData, new S(), new Serializable[] {});
    }

    /**
     * Signs the packet
     *
     * @param signature
     *            either server or client
     */
    /*package-private*/ void sign(Signature signature) {
        this.signature = signature;
        timeSent = System.currentTimeMillis();
    }

    /**
     * Get packet signature
     *
     * @return packet signature
     */
    /*package-private*/ Signature getSignature() {
        return signature;
    }

    /**
     *
     * @return
     *          ip of the packet origin,
     *          empty string if the packet is originated on this machine
     */
    public String getIP() {
        return ip;
    }

    /**
     * Set ip, will be done automatically
     * upon receiving
     *
     * @param ip
     */
    public void setIP(String ip) {
        this.ip = ip;
    }

    /**
     *
     * @return
     *          port of the packet origin,
     *          0 if the packet is originated on this machine
     */
    public int getPort() {
        return port;
    }

    /**
     * Set port, will be done automatically
     * upon receiving
     *
     * @param port
     */
    public void setPort(int port) {
        this.port = port;
    }

    public long getTime() {
        return timeSent;
    }

    /**
     * Serializable Object, just a dummy object that implements java.io.Serializable
     *
     * @author Almas Baimagambetov (ab607@uni.brighton.ac.uk)
     * @version 1.0
     *
     */
    static class S implements Serializable {
        /**
         *
         */
        private static final long serialVersionUID = 8229037616837666038L;

    }
}

redpajama_set_name: RedPajamaGithub


text:
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding model 'Trade'
        db.create_table(u'stexchange_trade', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['stexchange.Category'])),
            ('seller', self.gf('django.db.models.fields.related.ForeignKey')(related_name='seller_for_trade', to=orm['stexchange.Member'])),
            ('buyer', self.gf('django.db.models.fields.related.ForeignKey')(related_name='buyer_for_trade', to=orm['stexchange.Member'])),
            ('value', self.gf('django.db.models.fields.PositiveIntegerField')()),
            ('description', self.gf('django.db.models.fields.TextField')()),
            ('date', self.gf('django.db.models.fields.DateField')()),
        ))
        db.send_create_signal(u'stexchange', ['Trade'])

        # Adding model 'Category'
        db.create_table(u'stexchange_category', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
        ))
        db.send_create_signal(u'stexchange', ['Category'])

    def backwards(self, orm):
        # Deleting model 'Trade'
        db.delete_table(u'stexchange_trade')

        # Deleting model 'Category'
        db.delete_table(u'stexchange_category')

    models = {
        u'auth.group': {
            'Meta': {'object_name': 'Group'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
        },
        u'auth.permission': {
            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
        },
        u'auth.user': {
            'Meta': {'object_name': 'User'},
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
        },
        u'contenttypes.contenttype': {
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
        },
        u'stexchange.category': {
            'Meta': {'object_name': 'Category'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
        },
        u'stexchange.member': {
            'Meta': {'object_name': 'Member'},
            'balance': ('django.db.models.fields.IntegerField', [], {}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'member_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '6'}),
            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
        },
        u'stexchange.trade': {
            'Meta': {'object_name': 'Trade'},
            'buyer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buyer_for_trade'", 'to': u"orm['stexchange.Member']"}),
            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stexchange.Category']"}),
            'date': ('django.db.models.fields.DateField', [], {}),
            'description': ('django.db.models.fields.TextField', [], {}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'seller': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'seller_for_trade'", 'to': u"orm['stexchange.Member']"}),
            'value': ('django.db.models.fields.PositiveIntegerField', [], {})
        }
    }

    complete_apps = ['stexchange']


text:
extern "C" int vsnprintf(char *, size_t, const char *, va_list);

using namespace std;

string string_format(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    size_t size = vsnprintf(NULL, 0, format, args) + 1u;
    char buf[size];
    vsnprintf(buf, size, format, args);
    return string(buf);
}

static int static_map_comp(const void *a, const void *b)
{
    return strcmp(((static_map_entry *) a)->key, ((static_map_entry *) b)->key);
}

const void *static_map_find(const char *key, const static_map_entry table[], size_t table_size)
{
    static_map_entry needle = {key, NULL};
    static_map_entry *e = (static_map_entry *) bsearch(&needle, table, table_size / sizeof(static_map_entry), sizeof(static_map_entry), static_map_comp);
    return e ? e->value : NULL;
}


text:
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <link rel="shortcut icon" href="/static/images/favicon.ico"/>
    <link rel="bookmark" href="/static/images/favicon.ico"/>
    <title>{% block title%}{% endblock %}</title>
    {% block styleLink %}{% endblock %}
    <style>
    body{
      font-family: "Microsoft Yahei",tahoma,arial,"Hiragino Sans GB","helvetica neue",helvetica,arial,Sans-serif,"Hiragino Sans GB","Hiragino Sans GB W3","SimHei";
      background-color: #f5f5f5;
      position: relative;
    }
    html,body,section,h1,p,input,label,textarea,span,ul,li,dl,dt,dd,button,h2{
      appearance: none;
      -webkit-appearance: none;
      margin:0;  padding:0;
      box-sizing: border-box;
      /*height= +边框  */
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
    }
    h2{font-weight: normal;}
    button,textarea{
      outline:0px none;
      border:0 none;
      background: transparent;
    }
    ul li{
      list-style: none;
    }
    </style>
  </head>
  <body>
    {% block content %} {% endblock %}
    <!-- 打包后,静态文件路径 -->
    <script type="text/javascript">
        (function(win) {
         var doc = win.document;
         var docEl = doc.documentElement;
         var tid;
         function refreshRem() {
            var width = docEl.getBoundingClientRect().width;
            var rem = width / 37.5; // 将屏幕宽度分成10份, 1份为1rem
            docEl.style.fontSize = rem + 'px';
         }
         win.addEventListener('resize', function() {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
         }, false);
         win.addEventListener('pageshow', function(e) {
            if (e.persisted) {
               clearTimeout(tid);
               tid = setTimeout(refreshRem, 300);
            }
         }, false);
         refreshRem();
      })(window);
    </script>
  </body>
</html>


text:
module Utensils
  module Generators
    class InstallGenerator < Rails::Generators::Base
      desc 'Install the base assets for setting up a new project using utensils.'
      source_root File.expand_path('../../../../../spec/dummy', __FILE__)

      def cleanup_assets
        remove_file "app/assets/stylesheets/application.css"
        remove_file "app/assets/javascripts/application.js"
        remove_dir "public"
      end

      def create_sass_files
        copy_file 'app/assets/stylesheets/_config.sass'
        copy_file 'app/assets/stylesheets/application.sass'
        copy_file 'app/assets/stylesheets/dinosaur.sass'
      end

      def create_coffee_files
        copy_file 'app/assets/javascripts/application.coffee'
        copy_file 'app/assets/javascripts/dinosaur.coffee'
        copy_file 'app/assets/javascripts/polyfill.coffee'
      end

      def create_haml_files
        copy_file 'app/views/layouts/pages.html.haml', 'app/views/layouts/application.html.haml'
        empty_directory 'app/views/layouts/shared'
        copy_file 'app/views/layouts/shared/_flash_message.html.haml'
        copy_file 'app/views/layouts/shared/_upgrade.html.haml'
      end

      def create_public_assets
        empty_directory 'public'
        copy_file 'public/404.html'
        copy_file 'public/422.html'
        copy_file 'public/500.html'
        copy_file 'public/apple-touch-icon-114x114-precomposed.png'
        copy_file 'public/apple-touch-icon-144x144.png'
        copy_file 'public/apple-touch-icon-57x57-precomposed.png'
        copy_file 'public/apple-touch-icon-72x72-precomposed.png'
        copy_file 'public/apple-touch-icon-precomposed.png'
        copy_file 'public/apple-touch-icon.png'
        copy_file 'public/error.html'
        copy_file 'public/favicon.ico'
        copy_file 'public/maintenance.html'
      end

    end
  end
end


text:
const socket = io();
const o = false;
function get(id) {
	return document.getElementById(id);
}
//-------------------------------------------------------------------------
// game variables (initialized during reset)
//-------------------------------------------------------------------------

const tetris = {
	/*
  init: function(){
    this.dx, this.dy,        // pixel size of a single tetris block
    this.blocks,        // 2 dimensional array (nx*ny) representing tetris court - either empty block or occupied by a 'piece'
    this.actions,       // queue of user actions (inputs)
    this.playing,       // true|false - game is in progress
    this.dt,            // time since starting this game
    this.current,       // the current piece
    this.next,          // the next piece
    this.score,         // the current score
    this.vscore,        // the currently displayed score (it catches up to score in small chunks - like a spinning slot machine)
    this.rows,          // number of completed rows in the current game
    this.step;          // how long before current piece drops by 1 row

    this.ucanvas = get('upcoming'),
    this.uctx    = ucanvas.getContext('2d'),
    this.speed   = { start: 0.6, decrement: 0.005, min: 0.1 }, // how long before piece drops by 1 row (seconds)
    this.nx      = 10, // width of tetris court (in blocks)
    this.ny      = 20, // height of tetris court (in blocks)
    this.nu      = 5;  // width/height of upcoming preview (in blocks)
      //console.log(ucanvas, uctx)
    this.invalid = {};
  },
  invalidate:       function()  { this.invalid.court  = true; },
  invalidateNext:   function () { this.invalid.next   = true; },
  invalidateScore:  function () { this.invalid.score  = true; },
  invalidateRows:   function () { this.invalid.rows   = true; },

  resize: function(event){
    //canvas.width   = canvas.clientWidth;  // set canvas logical size equal to its physical size
    //canvas.height  = canvas.clientHeight; // (ditto)
    this.ucanvas.width  = this.ucanvas.clientWidth;
    this.ucanvas.height = this.ucanvas.clientHeight;

    this.dx = 200  / this.nx; // pixel size of a single tetris block
    this.dy = 400 / this.ny; // (ditto)

    this.invalidate();
    this.invalidateNext();
  }
*/
};
const pieceObj = {
	/*
    init: function(){

    },
    eachblock: function (type, x, y, dir, fn) {
      var bit, result, row = 0, col = 0, blocks = type.blocks[dir];
      for(bit = 0x8000 ; bit > 0 ; bit = bit >> 1) {
        if (blocks & bit) {
          fn(x + col, y + row);
        }
        if (++col === 4) {
          col = 0;
          ++row;
        }
      }
    },
    dropPiece: function () {
      this.eachblock(current.type, current.x, current.y, current.dir, function(x, y) {
        setBlock(x, y, current.type);
      });
    },
    drawPiece: function (ctx, type, x, y, dir) {
      var loc = this;
      this.eachblock(type, x, y, dir, function(x, y) {
      loc.drawBlock(ctx, x, y, type.color);
      });
    },

    drawBlock: function (ctx, x, y, color) {
      ctx.fillStyle = color;
      ctx.fillRect(x*dx, y*dy, dx, dy);
      ctx.strokeRect(x*dx, y*dy, dx, dy)
    }
    */
};

let isCurrentPlayer = false;

let dx; let dy; // pixel size of a single tetris block
let blocks; // 2 dimensional array (nx*ny) representing tetris court - either empty block or occupied by a 'piece'
let actions; // queue of user actions (inputs)
let playing; // true|false - game is in progress
let dt; // time since starting this game
let pieceToDraw; // a dynamic piece that will be show to user
let current; // the current piece
let next; // the next piece
let score; // the current score
let vscore; // the currently displayed score (it catches up to score in small chunks - like a spinning slot machine)
let rows; // number of completed rows in the current game
let step; // how long before current piece drops by 1 row

const ucanvas = get('upcoming');
const uctx = ucanvas.getContext('2d');
const speed = { start: 0.6, decrement: 0.005, min: 0.1 }; // how long before piece drops by 1 row (seconds)
const nx = 10; // width of tetris court (in blocks)
const ny = 20; // height of tetris court (in blocks)
const nu = 5; // width/height of upcoming preview (in blocks)
// console.log(ucanvas, uctx)
const invalid = {};

function invalidate() {
	invalid.court = true;
}
function invalidateNext() {
	invalid.next = true;
}
function invalidateScore() {
	invalid.score = true;
}
function invalidateRows() {
	invalid.rows = true;
}

function resize(event) {
	// canvas.width   = canvas.clientWidth;  // set canvas logical size equal to its physical size
	// canvas.height  = canvas.clientHeight; // (ditto)
	// ucanvas.width  = ucanvas.clientWidth;
	// ucanvas.height = ucanvas.clientHeight;

	dx = 200 / nx; // pixel size of a single tetris block
	dy = 400 / ny; // (ditto)

	console.log(dx);
	invalidate();
	invalidateNext();
}
resize();
//------------------------------------------------
// do the bit manipulation and iterate through each
// occupied block (x,y) for a given piece
//------------------------------------------------
function drawBlock(ctx, x, y, color) {
	ctx.fillStyle = color;
	ctx.fillRect(x * dx + 1, y * dy + 1, dx - 2, dy - 2);
	ctx.strokeRect(x * dx, y * dy, dx, dy);
}
function eachblock(type, x, y, dir, fn) {
	// console.log(type, x, y, dir)
	let bit; let result; let row = 0; let col = 0; const
		blocks = type.blocks[dir];
	for (bit = 0x8000; bit > 0; bit >>= 1) {
		if (blocks & bit) {
			fn(x + col, y + row);
		}
		if (++col === 4) {
			col = 0;
			++row;
		}
	}
}
function drawPiece(ctx, type, x, y, color, dir) {
	// var color = 'rgba('+type.color.r+','+type.color.g+','+type.color.b+', 0.5)';
	eachblock(type, x, y, dir, (x, y) => {
		drawBlock(ctx, x, y, color);
	});
}
function drawDisplayPiece() {
	if (invalid.next) {
		// console.log(padding)
		uctx.save();
		uctx.translate(0.5, 0.5);
		uctx.clearRect(0, 0, nu * dx, nu * dy);
		// console.log(uctx)
		if (pieceToDraw) var padding = (nu - pieceToDraw.type.size) / 2; // half-arsed attempt at centering next piece display
		if (pieceToDraw) drawPiece(uctx, pieceToDraw.type, padding, padding, pieceToDraw.color, pieceToDraw.dir);
		// uctx.strokeStyle = 'black';
		// uctx.strokeRect(0, 0, nu*dx - 1, nu*dy - 1);
		uctx.restore();
		invalid.next = false;
	}
}
invalidate();
invalidateNext();
invalidateScore();
invalidateRows();

/*
  socket.on('render', function(data){
    //next = data.next;
    current = data.current;

    //console.log(next.type);
    invalid.next = true;
    pieceToDraw = ( isCurrentPlayer )? current : next;
    //pieceToDraw.type.color = data.color;

    drawDisplayPiece();

    //
    $('.keys').toggleClass('paused',!data.playing);
  }); */

socket.on('user-render', (data) => {
	// next = data.next;
	// current = data.current;

	// console.log(next.type);
	invalid.next = true;
	pieceToDraw = data.piece;// ( isCurrentPlayer )? current : next;
	// pieceToDraw.type.color = data.color;
	$('.points').html(data.score);
	drawDisplayPiece();

	//
	$('.keys').toggleClass('paused', data.status !== 3);
});

socket.on('added user', (data) => {
	next = data;
	console.log('added', data);
});

socket.on('start turn', (data) => {
	isCurrentPlayer = true;
	$('.msg').html('Seu turno.');
	$('.keys').toggleClass('off', false);
});

socket.on('next turn', (data) => {
	$('.msg').html('Você é o próximo.');
});

socket.on('end turn', (data) => {
	next = data;
	isCurrentPlayer = false;
	$('.msg').html('');
	$('.keys').toggleClass('off', true);
});

socket.on('connect', (data) => {
	console.log('Conexão estabelecida');
});
socket.on('reconnect', (data) => {
	console.log('Conexão restabelecida');
});
socket.on('connect_error', (data) => {
	console.error('Conexão deu erro');
});
socket.on('reconnect_error', (data) => {
	console.error('Conexão deu erro');
});


text:
const express  = require('express');
const path = require('path');
const cors = require('cors');
const jwt = require('express-jwt');
const jwks = require('jwks-rsa');
const jwtAuthz = require('express-jwt-authz');

const { Config } = require('./config');

const config = Config;
config.Auth.domain = process.env.AO_AUTH_DOMAIN || config.Auth.domain;
config.Auth.audience = process.env.AO_AUTH_AUDIENCE || config.Auth.audience;

console.log(`Auth0 domain set to ${config.Auth.domain}`);
console.log(`Auth0 audience set to ${config.Auth.audience}`);

const app = express();

app.use(cors());

let stateTaxRates = {};

stateTaxRates["IA"] = {state: "IA", rate: 5.0};
stateTaxRates["IL"] = {state: "IL", rate: 6.0};
stateTaxRates["MI"] = {state: "MI", rate: 3.0};
stateTaxRates["MN"] = {state: "MN", rate: 7.5};
stateTaxRates["WI"] = {state: "WI", rate: 4.25};

const authCheck = jwt({
  secret: jwks.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://${config.Auth.domain}/.well-known/jwks.json`
  }),
  audience: Config.Auth.audience,
  issuer: `https://${config.Auth.domain}/`,
  algorithms: ['RS256']
});

app.use(authCheck);

app.get('/api/tax', authCheck, jwtAuthz(['readall:tax']), (req, res) => {
  res.send(stateTaxRates);
});

app.get('/api/tax/:state', authCheck, jwtAuthz(['read:tax']), (req, res) => {
  let state = req.params.state.toUpperCase();

  let stateTaxModel = stateTaxRates[state];

  if(stateTaxModel) {
    res.send(stateTaxModel);
  } else {
    res.sendStatus(404);
  }
});

const port = process.env.PORT || 5003;

app.listen(port);

console.log(`Amart Online tax status service listening on port ${port}`);


text: Tom's Homepage


text:
'use strict';

var _ = require('lodash');
var path = require('path');
var assert = require('assert');
var fs = require('fs');
var async = require('async');
var hbase = require('hbase');
var moment = require('moment');

var settings = require('./config/app/settings');
var db = require('./db/scripts/db');
var turnstileModel = require('./db/models/model-turnstile').Model;
var monthwiseAvModel = require('./db/models/model-monthwise-av').Model;

var client = new hbase({
	host: '127.0.0.1',
	port: 8080
});

var log;

var stationDataPath = path.join(__dirname, './data/stations.json');
var stations = JSON.parse(fs.readFileSync(stationDataPath));

/**
 * Function to load the config
 */
var loadConfig = function() {
	var env = process.env.NODE_ENV || 'development',
		configPath = path.resolve(__dirname, '../config'),
		configFile = path.join(configPath + '/', env + '.json'),
		config = fs.readFileSync(configFile, 'utf8');
	settings.setConfig(config);
};

async.series([
	function(done) {
		loadConfig();
		done();
	},
	function(done) {
		settings.log = log;
		done();
	},
	function(done) {
		console.log('Connecting to mongoDb');
		db.connect(settings.getConfig().dbURL, done, done);
	},
	function(done) {
		_fetchAndSaveDataForAllStations(done, done);
	}
], function(error) {
	if(error) {
		console.log(error);
	} else {
		process.exit(0);
	}
});

function _fetchAndSaveDataForAllStations(success, failure) {

	async.eachSeries(stations, function(station, next) {
		var stationCode = _.findKey(station);
		_fetchAllForStation(stationCode, function(error, docs) {
			if(error) {
				next(error);
			} else {
				console.log('Saving to mongo for', stationCode);
				_saveToMongo(docs, next, next);
			}
		});
	}, function(error) {
		if(error) {
			failure(error);
		} else {
			success();
		}
	});
}

function _fetchAllForStation(code, callback) {
	console.log('Fetching from turnstileDatas for', code);
	var res = [],
		years = [2010, 2011, 2012, 2013, 2014, 2015];

	async.eachSeries(years, function(y, next) {
		_fetchForYear(code, y, function(err, docs) {
			if(err) {
				next(err);
			} else {
				res = _.union(res, docs);
				setImmediate(next);
			}
		});
	}, function(error) {
		if(error) {
			callback(error);
		} else {
			callback(null, res);
		}
	});
}

function _fetchForYear(code, year, callback) {
	var months = [1,2,3,4,5,6,7,8,9,10,11,12],
		res = [];

	async.eachSeries(months, function(m, next) {
		new turnstileModel().retrieve({remote: code, date: {"$gte": new Date(year, m, 1), "$lt": new Date(year, m+1, 1)}}, function(docs) {
			_consolidateForOneMonth(code, m, year, docs, function(ans) {
				res = _.union(res, ans);
				setImmediate(next);
			});
		}, next);
	}, function(error) {
		if(error) {
			callback(error);
		} else {
			callback(null, res);
		}
	});
}

function _consolidateForOneMonth(code, month, year, arr, callback) {
	var ans = [];
	if(arr.length > 1) {
		var x = {
			remote: code,
			month: month,
			year: year,
			entries: arr[0].entries,
			exits: arr[0].exits
		};

		ans.push(x);

		var entries = 0,
			exits = 0;
		async.eachSeries(arr, function(arr, next) {
			ans[0].entries = Number(ans[0].entries) + Number(_.get(arr, 'entries'));
			ans[0].exits = Number(ans[0].exits)  + Number(_.get(arr, 'exits'));
			setImmediate(next);
		}, function(err) {
			if(err) {
				callback(err);
			} else {

				callback(ans);
			}
		});
	} else {
		callback(arr);
	}
}

function _saveToMongo(docs, success, failure) {
	new monthwiseAvModel().bulkInsert(docs, success, function(error) {
		console.log(error);
		success();
	});
}


text:
package org.ohdsi.webapi.cohortdefinition.converter;

import org.apache.commons.lang3.StringUtils;
import org.ohdsi.webapi.cohortdefinition.CohortDefinition;
import org.ohdsi.webapi.cohortdefinition.dto.CohortMetadataDTO;
import org.ohdsi.webapi.service.converters.BaseCommonDTOExtToEntityExtConverter;

public abstract class BaseCohortDTOToCohortDefinitionConverter<V extends CohortMetadataDTO> extends BaseCommonDTOExtToEntityExtConverter<V, CohortDefinition> {

    @Override
    protected void doConvert(V source, CohortDefinition target) {
        target.setId(source.getId());
        target.setName(StringUtils.trim(source.getName()));
        target.setDescription(source.getDescription());
    }

    @Override
    protected CohortDefinition createResultObject() {
        return new CohortDefinition();
    }
}


text:
class Drawer

  attr_reader :contents

# Are there any more methods needed in this class?

  def initialize
    @contents = []
    @open = true
  end

  def open
    @open = true
  end

  def close
    @open = false
  end

  def add_item(item)
    @contents << item
  end

  def remove_item(item = @contents.pop) #what is `#pop` doing?
    @contents.delete(item)
  end

  def dump  # what should this method return?
    puts "Your drawer is empty."
    @contents = []
  end

  def view_contents
    puts "The drawer contains:"
    @contents.each {|silverware| puts "- " + silverware.utensil }
  end

end

class Silverware
   attr_reader :utensil

   # Are there any more methods needed in this class?

  def initialize(utensil, clean = true)
    @utensil = utensil
    @clean = clean
  end

  def eat
    puts "eating with the #{utensil}"
    @clean = false
  end

  def clean_silverware
    @clean = true
  end

  def clean
    @clean = false
  end

end

# DO NOT MODIFY THE DRIVER CODE UNLESS DIRECTED TO DO SO
knife1 = Silverware.new("knife")

silverware_drawer = Drawer.new
silverware_drawer.add_item(knife1)
silverware_drawer.add_item(Silverware.new("spoon"))
silverware_drawer.add_item(Silverware.new("fork"))
silverware_drawer.view_contents

silverware_drawer.remove_item
silverware_drawer.view_contents
sharp_knife = Silverware.new("sharp_knife")

silverware_drawer.add_item(sharp_knife)

silverware_drawer.view_contents

removed_knife = silverware_drawer.remove_item(sharp_knife)
removed_knife.eat
removed_knife.clean_silverware
raise Exception.new("Your silverware is not actually clean!") unless removed_knife.clean_silverware == true

silverware_drawer.view_contents
silverware_drawer.dump
raise Exception.new("Your drawer is not actually empty") unless silverware_drawer.contents.empty?
silverware_drawer.view_contents

# What will you need here in order to remove a spoon? You may modify the driver code for this error.
spoon = Silverware.new("spoon")
silverware_drawer.add_item(spoon)

raise Exception.new("You don't have a spoon to remove") unless silverware_drawer.contents.include?(spoon)
silverware_drawer.remove_item(spoon) #What is happening when you run this the first time?
spoon.eat
puts spoon.clean #=> this should be false

# DRIVER TESTS GO BELOW THIS LINE

# Reflection
# What concepts did you review in this challenge?
#  I reviewed how to debug a piece of code. This was more or less just trying to figure out what is going on and what something is doing.

# What is still confusing to you about Ruby?
#  Debugging is still a little bit confusing, but it is getting better. Its confusing because of trying to understand what the code is doing and why it's there.

# What are you going to study to get more prepared for Phase 1?
#  I'm just going to continue studying and preparing mentally for what is about to come.


text:
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using NUnit.Framework;

// ReSharper disable PossibleNullReferenceException

namespace Commander.Tests.CodeQuality
{
    [TestFixture]
    public class PublicAPITests : CodeQualityTestBase
    {
        [Test]
        [TestCaseSource(nameof(AllPublicTypes))]
        [Conditional("JETBRAINS_ANNOTATIONS")]
        public void PublicType_IsTaggedWithPublicAPIAttribute(Type type)
        {
            bool attributeIsPresent = type.GetCustomAttributes(typeof(PublicAPIAttribute), true).Any();
            Assert.That(attributeIsPresent, "Type " + type.Name + " is not tagged with [PublicAPI]");
        }

        [Test]
        [TestCaseSource(nameof(AllPublicMethods))]
        [Conditional("JETBRAINS_ANNOTATIONS")]
        public void PublicMethod_IsTaggedWithPublicAPIAttribute(MethodInfo method)
        {
            bool attributeIsPresent = method.GetCustomAttributes(typeof(PublicAPIAttribute), true).Any();
            Assume.That(method.DeclaringType != null);
            Assert.That(attributeIsPresent, "Method " + method.Name + " of type " + method.DeclaringType.Name + " is not tagged with [PublicAPI]");
        }

        [Test]
        [TestCaseSource(nameof(AllPublicConstructors))]
        [Conditional("JETBRAINS_ANNOTATIONS")]
        public void PublicConstructor_IsTaggedWithPublicAPIAttribute(ConstructorInfo constructor)
        {
            bool attributeIsPresent = constructor.GetCustomAttributes(typeof(PublicAPIAttribute), true).Any();
            Assume.That(constructor.DeclaringType != null);
            Assert.That(attributeIsPresent, "Constructor (" + string.Join(", ", constructor.GetParameters().Select(p => p.ParameterType.Name)) + " of type " + constructor.DeclaringType.Name + " is not tagged with [PublicAPI]");
        }

        [Test]
        [TestCaseSource(nameof(AllPublicProperties))]
        [Conditional("JETBRAINS_ANNOTATIONS")]
        public void PublicProperty_IsTaggedWithPublicAPIAttribute(PropertyInfo property)
        {
            bool attributeIsPresent = property.GetCustomAttributes(typeof(PublicAPIAttribute), true).Any();
            Assume.That(property.DeclaringType != null);
            Assert.That(attributeIsPresent, "Property " + property.Name + " of type " + property.DeclaringType.Name + " is not tagged with [PublicAPI]");
        }
    }
}


text:
// Copyright 2020-present the Material Components for iOS authors. All Rights Reserved.
//
// 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.

#import <UIKit/UIKit.h>

@class MDCFlexibleHeaderView;
@class MDCFlexibleHeaderViewController;

/**
 An object may conform to this protocol in order to receive layout change events caused by a
 MDCFlexibleHeaderView.
 */
@protocol MDCFlexibleHeaderViewLayoutDelegate <NSObject>
@required

/**
 Informs the receiver that the flexible header view's frame has changed.

 The receiver should use the MDCFlexibleHeader scrollPhase APIs in order to react to the frame
 changes.
 */
- (void)flexibleHeaderViewController:
            (nonnull MDCFlexibleHeaderViewController *)flexibleHeaderViewController
    flexibleHeaderViewFrameDidChange:(nonnull MDCFlexibleHeaderView *)flexibleHeaderView;

@end


text:
[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)

## Description
< 1KB lightweight, fast & powerful JavaScript templating engine with zero
dependencies. Compatible with server-side environments like node.js, module
loaders like RequireJS and all web browsers.

## Usage

### Client-side
Include the (minified) JavaScript Templates script in your HTML markup:

```html
<script src="js/tmpl.min.js"></script>
```

Add a script section with type **"text/x-tmpl"**, a unique **id** property and
your template definition as content:

```html
<script type="text/x-tmpl" id="tmpl-demo">
<h3>{%=o.title%}</h3>
<p>Released under the
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
<h4>Features</h4>
<ul>
{% for (var i=0; i<o.features.length; i++) { %}
    <li>{%=o.features[i]%}</li>
{% } %}
</ul>
</script>
```

**"o"** (the lowercase letter) is a reference to the data parameter of the
template function (see the API section on how to modify this identifier).

In your application code, create a JavaScript object to use as data for the
template:

```js
var data = {
    "title": "JavaScript Templates",
    "license": {
        "name": "MIT license",
        "url": "http://www.opensource.org/licenses/MIT"
    },
    "features": [
        "lightweight & fast",
        "powerful",
        "zero dependencies"
    ]
};
```

In a real application, this data could be the result of retrieving a
[JSON](http://json.org/) resource.

Render the result by calling the **tmpl()** method with the id of the template
and the data object as arguments:

```js
document.getElementById("result").innerHTML = tmpl("tmpl-demo", data);
```

### Server-side

The following is an example how to use the JavaScript Templates engine on the
server-side with [node.js](http://nodejs.org/).

Create a new directory and add the **tmpl.js** file. Or alternatively, install
the **blueimp-tmpl** package with [npm](https://www.npmjs.org/):

```sh
npm install blueimp-tmpl
```

Add a file **template.html** with the following content:

```html
<!DOCTYPE HTML>
<title>{%=o.title%}</title>
<h3><a href="{%=o.url%}">{%=o.title%}</a></h3>
<h4>Features</h4>
<ul>
{% for (var i=0; i<o.features.length; i++) { %}
    <li>{%=o.features[i]%}</li>
{% } %}
</ul>
```

Add a file **server.js** with the following content:

```js
require("http").createServer(function (req, res) {
    var fs = require("fs"),
        // The tmpl module exports the tmpl() function:
        tmpl = require("./tmpl").tmpl,
        // Use the following version if you installed the package with npm:
        // tmpl = require("blueimp-tmpl").tmpl,
        // Sample data:
        data = {
            "title": "JavaScript Templates",
            "url": "https://github.com/blueimp/JavaScript-Templates",
            "features": [
                "lightweight & fast",
                "powerful",
                "zero dependencies"
            ]
        };
    // Override the template loading method:
    tmpl.load = function (id) {
        var filename = id + ".html";
        console.log("Loading " + filename);
        return fs.readFileSync(filename, "utf8");
    };
    res.writeHead(200, {"Content-Type": "text/x-tmpl"});
    // Render the content:
    res.end(tmpl("template", data));
}).listen(8080, "localhost");
console.log("Server running at http://localhost:8080/");
```

Run the application with the following command:

```sh
node server.js
```

## Requirements
The JavaScript Templates script has zero dependencies.

## API

### tmpl() function
The **tmpl()** function is added to the global **window** object and can be
called as global function:

```js
var result = tmpl("tmpl-demo", data);
```

The **tmpl()** function can be called with the id of a template, or with a
template string:

```js
var result = tmpl("<h3>{%=o.title%}</h3>", data);
```

If called without second argument, **tmpl()** returns a reusable template
function:

```js
var func = tmpl("<h3>{%=o.title%}</h3>");
document.getElementById("result").innerHTML = func(data);
```

### Templates cache
Templates loaded by id are cached in the map **tmpl.cache**:

```js
var func = tmpl("tmpl-demo"), // Loads and parses the template
    cached = typeof tmpl.cache["tmpl-demo"] === "function", // true
    result = tmpl("tmpl-demo", data); // Uses cached template function

tmpl.cache["tmpl-demo"] = null;
result = tmpl("tmpl-demo", data); // Loads and parses the template again
```

### Output encoding
The method **tmpl.encode** is used to escape HTML special characters in the
template output:

```js
var output = tmpl.encode("<>&\"'\x00"); // Renders "<>&"'"
```

**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the
encoding map **tmpl.encMap** to match and replace special characters, which can
be modified to change the behavior of the output encoding.
Strings matched by the regular expression, but not found in the encoding map are
removed from the output. This allows for example to automatically trim input
values (removing whitespace from the start and end of the string):

```js
tmpl.encReg = /(^\s+)|(\s+$)|[<>&"'\x00]/g;
var output = tmpl.encode("    Banana!    "); // Renders "Banana" (without whitespace)
```

### Local helper variables
The local variables available inside the templates are the following:

* **o**: The data object given as parameter to the template function
(see the next section on how to modify the parameter name).
* **tmpl**: A reference to the **tmpl** function object.
* **_s**: The string for the rendered result content.
* **_e**: A reference to the **tmpl.encode** method.
* **print**: Helper function to add content to the rendered result string.
* **include**: Helper function to include the return value of a different
template in the result.

To introduce additional local helper variables, the string **tmpl.helper** can
be extended. The following adds a convenience function for *console.log* and a
streaming function, that streams the template rendering result back to the
callback argument
(note the comma at the beginning of each variable declaration):

```js
tmpl.helper += ",log=function(){console.log.apply(console, arguments)}" +
    ",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}";
```

Those new helper functions could be used to stream the template contents to the
console output:

```html
<script type="text/x-tmpl" id="tmpl-demo">
<h3>{%=o.title%}</h3>
{% stream(log); %}
<p>Released under the
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
{% stream(log); %}
<h4>Features</h4>
<ul>
{% stream(log); %}
{% for (var i=0; i<o.features.length; i++) { %}
    <li>{%=o.features[i]%}</li>
    {% stream(log); %}
{% } %}
</ul>
{% stream(log); %}
</script>
```

### Template function argument
The generated template functions accept one argument, which is the data object
given to the **tmpl(id, data)** function. This argument is available inside the
template definitions as parameter **o** (the lowercase letter).

The argument name can be modified by overriding **tmpl.arg**:

```js
tmpl.arg = "p";

// Renders "<h3>JavaScript Templates</h3>":
var result = tmpl("<h3>{%=p.title%}</h3>", {title: "JavaScript Templates"});
```

### Template parsing
The template contents are matched and replaced using the regular expression
**tmpl.regexp** and the replacement function **tmpl.func**.
The replacement function operates based on the
[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).

To use different tags for the template syntax, override **tmpl.regexp** with a
modified regular expression, by exchanging all occurrences of "{%" and "%}",
e.g. with "[%" and "%]":

```js
tmpl.regexp = /([\s'\\])(?!(?:[^[]|\[(?!%))*%\])|(?:\[%(=|#)([\s\S]+?)%\])|(\[%)|(%\])/g;
```

By default, the plugin preserves whitespace
(newlines, carriage returns, tabs and spaces).
To strip unnecessary whitespace, you can override the **tmpl.func** function,
e.g. with the following code:

```js
var originalFunc = tmpl.func;
tmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {
    if (p1 && /\s/.test(p1)) {
        if (!offset || /\s/.test(str.charAt(offset - 1)) ||
                /^\s+$/g.test(str.slice(offset))) {
            return '';
        }
        return ' ';
    }
    return originalFunc.apply(tmpl, arguments);
};
```

## Templates syntax

### Interpolation
Print variable with HTML special characters escaped:

```html
<h3>{%=o.title%}</h3>
```

Print variable without escaping:

```html
<h3>{%#o.user_id%}</h3>
```

Print output of function calls:

```html
<a href="{%=encodeURI(o.url)%}">Website</a>
```

Use dot notation to print nested properties:

```html
<strong>{%=o.author.name%}</strong>
```

### Evaluation
Use **print(str)** to add escaped content to the output:

```html
<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>
```

Use **print(str, true)** to add unescaped content to the output:

```html
<span>{% print("Fast & powerful", true); %}</span>
```

Use **include(str, obj)** to include content from a different template:

```html
<div>
{% include('tmpl-link', {name: "Website", url: "https://example.org"}); %}
</div>
```

**If else condition**:

```html
{% if (o.author.url) { %}
    <a href="{%=encodeURI(o.author.url)%}">{%=o.author.name%}</a>
{% } else { %}
    <em>No author url.</em>
{% } %}
```

**For loop**:

```html
<ul>
{% for (var i=0; i<o.features.length; i++) { %}
    <li>{%=o.features[i]%}</li>
{% } %}
</ul>
```

## Compiled templates
The JavaScript Templates project comes with a compilation script, that allows
you to compile your templates into JavaScript code and combine them with a
minimal Templates runtime into one minified JavaScript file.

The compilation script is built for [node.js](http://nodejs.org/) and also
requires [UglifyJS](https://github.com/mishoo/UglifyJS).
To use it, first install both the JavaScript Templates project and UglifyJS via
[npm](https://www.npmjs.org/):

```sh
npm install uglify-js blueimp-tmpl
```

This will put the executables **uglifyjs** and **tmpl.js** into the folder
**node_modules/.bin**. It will also make them available on your PATH if you
install the packages globally
(by adding the **-g** flag to the install command).

The **tmpl.js** executable accepts the paths to one or multiple template files
as command line arguments and prints the generated JavaScript code to the
console output. The following command line shows you how to store the generated
code in a new JavaScript file that can be included in your project:

```sh
tmpl.js templates/upload.html templates/download.html > tmpl.min.js
```

The files given as command line arguments to **tmpl.js** can either be pure
template files or HTML documents with embedded template script sections.
For the pure template files, the file names (without extension) serve as
template ids.
The generated file can be included in your project as a replacement for the
original **tmpl.js** runtime. It provides you with the same API and provides a
**tmpl(id, data)** function that accepts the id of one of your templates as
first and a data object as optional second parameter.

## Tests
The JavaScript Templates project comes with
[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).
There are two different ways to run the tests:

* Open test/index.html in your browser or
* run `npm test` in the Terminal in the root path of the repository package.

The first one tests the browser integration,
the second one the[node.js](http://nodejs.org/) integration.

## License
The JavaScript Templates script is released under the
[MIT license](http://www.opensource.org/licenses/MIT).


text:
package es.uvigo.esei.daa.dao;

import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reset;
import static org.junit.Assert.assertEquals;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import es.uvigo.esei.daa.DatabaseQueryUnitTest;
import es.uvigo.esei.daa.entities.Event;

public class EventDAOUnitTest extends DatabaseQueryUnitTest {
	/*@Test
	public void testGet() throws Exception {
		final Person person = new Person(1, "Pepe", "Pérez");

		expect(result.next()).andReturn(true);
		expect(result.getInt("id")).andReturn(person.getId());
		expect(result.getString("name")).andReturn(person.getName());
		expect(result.getString("surname")).andReturn(person.getSurname());
		result.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();

		assertEquals("Unexpected person data",
			person, peopleDAO.get(person.getId())
		);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testGetMissing() throws Exception {
		expect(result.next()).andReturn(false);
		result.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.get(2);
	}

	@Test(expected = DAOException.class)
	public void testGetUnexpectedException() throws Exception {
		expect(result.next()).andThrow(new SQLException());
		result.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.get(2);
	}*/

	@Test
	public void testlistRecomended() throws Exception {
		final List<Event> events = Arrays.asList(
				new Event(3,"Pachanga en Ourense", new Timestamp(1439483400),new Timestamp(1442161800),new Timestamp(1442169000),"Partido de futbol entre amigos en el campo del campus de ourense","Fiesta", "Ourense", "img/prueba3.jpg","Pablo"),
				new Event(1,"Fiesta de Disfraces", new Timestamp(1436959800),new Timestamp(1439638200),new Timestamp(1439645400),"Fiesta de disfraces para celebrar el inicio de la primavera","Fiesta", "Ourense", "img/prueba1.jpg","Pablo"),
				new Event(4,"Parrillada en Vigo", new Timestamp(1433341800),new Timestamp(1433341800),new Timestamp(1434385800),"Cada uno debe pagar 5 euros para comprar comida y bebida","Fiesta", "Ourense","img/prueba4.jpg","Pablo"),
				new Event(2,"Club de lectura", new Timestamp(1433341800),new Timestamp(1433341800),new Timestamp(1434385800),"Hablaremos sobre algun libro, uno diferente cada semana","Fiesta", "Ourense","img/prueba2.jpg","Pablo")
			);

		for (Event event : events) {
			expect(result.next()).andReturn(true);
			expect(result.next()).andReturn(false);
			expect(result.next()).andReturn(true);
			expect(result.getInt("id")).andReturn(event.getId());
			expect(result.getString("nameEvent")).andReturn(event.getNameEvent());
			expect(result.getTimestamp("dateCreate")).andReturn(event.getDateCreate());
			expect(result.getTimestamp("dateInit")).andReturn(event.getDateInit());
			expect(result.getTimestamp("dateFinal")).andReturn(event.getDateFinal());
			expect(result.getString("description")).andReturn(event.getDescription());
			expect(result.getString("category")).andReturn("Fiesta").anyTimes();
			expect(result.getString("place")).andReturn(event.getPlace());
			expect(result.getString("image")).andReturn(event.getImage());
			expect(result.getString("author")).andReturn(event.getAuthor());
		}

		expect(result.next()).andReturn(false);
		result.close();
		result.close();
		replayAll();
		final EventDAO eventDAO = new EventDAO();

		assertEquals("Unexpected event data",
			events, eventDAO.listRecomended("Pablo", "Ourense")
		);
	}
	/*
	@Test(expected = DAOException.class)
	public void testListUnexpectedException() throws Exception {
		expect(result.next()).andThrow(new SQLException());
		result.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.list();
	}

	@Test
	public void testAdd() throws Exception {
		final Person person = new Person(1, "Pepe", "Pérez");

		reset(connection);
		expect(connection.prepareStatement(anyString(), eq(1)))
			.andReturn(statement);
		expect(statement.executeUpdate()).andReturn(1);
		expect(statement.getGeneratedKeys()).andReturn(result);
		expect(result.next()).andReturn(true);
		expect(result.getInt(1)).andReturn(person.getId()); // Key retrieval
		connection.close();
		result.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		final Person newPerson = peopleDAO.add(person.getName(), person.getSurname());

		assertEquals(person, newPerson);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testAddNullName() throws Exception {
		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();

		resetAll(); // No expectations

		peopleDAO.add(null, "Pepe");
	}

	@Test(expected = IllegalArgumentException.class)
	public void testAddNullSurname() throws Exception {
		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();

		resetAll(); // No expectations

		peopleDAO.add("Pepe", null);
	}

	@Test(expected = DAOException.class)
	public void testAddZeroUpdatedRows() throws Exception {
		reset(connection);
		expect(connection.prepareStatement(anyString(), eq(1)))
			.andReturn(statement);
		expect(statement.executeUpdate()).andReturn(0);
		connection.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.add("Paco", "Pérez");
	}

	@Test(expected = DAOException.class)
	public void testAddNoGeneratedKey() throws Exception {
		reset(connection);
		expect(connection.prepareStatement(anyString(), eq(1)))
			.andReturn(statement);
		expect(statement.executeUpdate()).andReturn(1);
		expect(statement.getGeneratedKeys()).andReturn(result);
		expect(result.next()).andReturn(false);
		result.close();
		connection.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.add("Paco", "Pérez");
	}

	@Test(expected = DAOException.class)
	public void testAddUnexpectedException() throws Exception {
		reset(connection);
		expect(connection.prepareStatement(anyString(), eq(1)))
			.andReturn(statement);
		expect(statement.executeUpdate()).andThrow(new SQLException());
		connection.close();

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.add("Paco", "Pérez");
	}

	@Test
	public void testDelete() throws Exception {
		expect(statement.executeUpdate()).andReturn(1);

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.delete(1);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testDeleteInvalidId() throws Exception {
		expect(statement.executeUpdate()).andReturn(0);

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.delete(1);
	}

	@Test(expected = DAOException.class)
	public void testDeleteUnexpectedException() throws Exception {
		expect(statement.executeUpdate()).andThrow(new SQLException());

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.delete(1);
	}

	@Test
	public void testModify() throws Exception {
		final Person person = new Person(1, "Pepe", "Pérez");

		expect(statement.executeUpdate()).andReturn(1);

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		final Person newPerson = peopleDAO.modify(
			person.getId(), person.getName(), person.getSurname()
		);

		assertEquals(person, newPerson);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testModifyNullName() throws Exception {
		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();

		resetAll(); // No expectations

		peopleDAO.modify(1, null, "Pepe");
	}

	@Test(expected = IllegalArgumentException.class)
	public void testModifyNullSurname() throws Exception {
		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();

		resetAll(); // No expectations

		peopleDAO.modify(1, "Pepe", null);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testModifyZeroUpdatedRows() throws Exception {
		expect(statement.executeUpdate()).andReturn(0);

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.modify(1, "Paco", "Pérez");
	}

	@Test(expected = DAOException.class)
	public void testModifyUnexpectedException() throws Exception {
		expect(statement.executeUpdate()).andThrow(new SQLException());

		replayAll();

		final PeopleDAO peopleDAO = new PeopleDAO();
		peopleDAO.modify(1, "Paco", "Pérez");
	}*/
}


text:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="@color/bg_tab_select" android:state_checked="true"/>
    <item android:color="@color/bg_tab_select" android:state_focused="true"/>
    <item android:color="@color/bg_tab_select" android:state_pressed="true"/>
    <item android:color="@color/bg_tab_unselect"/>

</selector>


text:
/*
 * CompassControl.java
 * (c) 2001 by Phil Scovis, all rights reserved.
 * This code is provided as-is, without warranty.
 * You may copy, use, or distribute this code,
 * provided that you add value to it and include
 * this notice.
 *
 * Modified on February 1, 2003, 2:53 PM (Peter Volgyesi):
 *  - converted to Swing
 */

import java.awt.SystemColor;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Polygon;
import java.awt.Font;
import java.awt.FontMetrics;

/**
 *
 * A component that displays a graphical representation of a compass.  The
 * compass "swings" when the setting is changed.
 * @author Phil Scovis
 * @author Peter Volgyesi
 */
public class CompassControl extends javax.swing.JPanel {

    /** Creates new panel CompassControl */
    public CompassControl() {
        setAngle(N);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents

        setLayout(new java.awt.BorderLayout());

    }//GEN-END:initComponents

    /**
     * Sets the angle of the compass.  This causes the compass to "swing" from
     * its current position to the new position.  The value set here is
     * immediately reflected in a subsequent call to getAngle() even
     * if the compass is still swinging.
     * @param angle the new angle of the compass, in radians.  Values are clockwise
     * beginning from North.
     * @see #getAngle()
     */
    public void setAngle(double angle) {
        theAngle = angle;
        theThread = new CompassSwingerThread();
        theThread.start();
    }

    /**
     * Returns the currently set angle on the compass.
     * @return the currently set angle on the compass, in radians.
     * @see #setAngle(double)
     */
    public double getAngle() {
        return theAngle;
    }

    /**
     * Returns the preferred size of this component
     * @return the preferred size of this component
     */
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

    /**
     * Returns the minimum size of this component
     * @return the minimum size of this component
     */
    public Dimension getMinimumSize() {
        return new Dimension(50, 50);
    }

    /**
     * Draws the component on the graphics context.  This is intended to be
     * called from the superclass update(Graphics) method.
     * @param g the graphics context
     */
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int w = getSize().width;
        int h = getSize().height;
        int r = Math.min(w, h) / 2;

        g.translate(w / 2 - r, h / 2 - r);

        // draw dial
        g.setColor(getBackground());
        g.fillRect(0, 0, w, h);
        g.setColor(SystemColor.controlShadow);
        g.fillArc(0, 0, 2 * r - 1, 2 * r - 1, 45, 180);
        g.setColor(SystemColor.controlDkShadow);
        g.fillArc(2, 2, 2 * r - 6, 2 * r - 6, 45, 180);
        g.setColor(SystemColor.controlLtHighlight);
        g.fillArc(0, 0, 2 * r - 1, 2 * r - 1, 225, 180);
        g.setColor(SystemColor.controlHighlight);
        g.fillArc(2, 2, 2 * r - 6, 2 * r - 6, 225, 180);
        g.setColor(SystemColor.control);
        g.fillOval(6, 6, 2 * r - 12, 2 * r - 12);

        int needleLength = r - 10;
        int needleWidth = r / 10;
        int dropShadowHeight = r / 30;
        int fontSize = r / 5;

        // draw letters
        g.setFont(new Font("sans-serif", Font.BOLD, fontSize));
        FontMetrics fm = g.getFontMetrics();
        g.setColor(SystemColor.controlText);
        g.drawString("N", r - fm.stringWidth("N") / 2, fm.getAscent() + 5);
        g.drawString("S", r - fm.stringWidth("S") / 2, 2 * r - 13);
        g.drawString("W", 10, r + fm.getAscent() / 2);
        g.drawString("E", 2 * r - 1 - fm.stringWidth("E") - 8, r + fm.getAscent() / 2);

        // draw ticks
        // I was having some interference between the ticks an the letters.
        // Perhaps someone else can figure out how to make this work.
        //
        g.setColor(SystemColor.controlText);
        for (int i = 0; i < 360; i++) {
            int length;
            int res = i % 90;
            if (res == 0) {
                continue;
            } else if (res == 22 || res == 67) {
                length = r / 10;
                int rs = r - 15;
                g.drawLine(
                        (int) (r + rs * Math.cos(Math.PI * 2 * i / 360)),
                        (int) (r + rs * Math.sin(Math.PI * 2 * i / 360)),
                        (int) (r + (rs - length) * Math.cos(Math.PI * 2 * i / 360)),
                        (int) (r + (rs - length) * Math.sin(Math.PI * 2 * i / 360))
                );
            } else if (res == 47) {
                length = r / 14;
                int rs = r - 20;
                g.fillOval(
                        (int) (r - 5 + rs * Math.cos(Math.PI * 2 * i / 360)),
                        (int) (r - 5 + rs * Math.sin(Math.PI * 2 * i / 360)),
                        10,
                        10
                );
            } else {
                continue;
            }
        }

        // draw needle shadow
        g.setColor(SystemColor.controlShadow);
        Polygon poly = new Polygon();
        poly.addPoint((int) (r + dropShadowHeight + needleLength * Math.sin(thePhysicalAngle)),
                (int) (r + dropShadowHeight - needleLength * Math.cos(thePhysicalAngle)));
        poly.addPoint((int) (r + dropShadowHeight + needleWidth * Math.cos(thePhysicalAngle)),
                (int) (r + dropShadowHeight + needleWidth * Math.sin(thePhysicalAngle)));
        poly.addPoint((int) (r + dropShadowHeight - needleLength * Math.sin(thePhysicalAngle)),
                (int) (r + dropShadowHeight + needleLength * Math.cos(thePhysicalAngle)));
        poly.addPoint((int) (r + dropShadowHeight - needleWidth * Math.cos(thePhysicalAngle)),
                (int) (r + dropShadowHeight - needleWidth * Math.sin(thePhysicalAngle)));
        g.fillPolygon(poly);

        // draw needle
        g.setColor(SystemColor.red);
        poly = new Polygon();
        poly.addPoint((int) (r + needleLength * Math.sin(thePhysicalAngle)), (int) (r - needleLength * Math.cos(thePhysicalAngle)));
        poly.addPoint((int) (r + needleWidth * Math.cos(thePhysicalAngle)), (int) (r + needleWidth * Math.sin(thePhysicalAngle)));
        poly.addPoint((int) (r - needleWidth * Math.cos(thePhysicalAngle)), (int) (r - needleWidth * Math.sin(thePhysicalAngle)));
        g.fillPolygon(poly);
        g.setColor(SystemColor.white);
        poly = new Polygon();
        poly.addPoint((int) (r - needleLength * Math.sin(thePhysicalAngle)), (int) (r + needleLength * Math.cos(thePhysicalAngle)));
        poly.addPoint((int) (r + needleWidth * Math.cos(thePhysicalAngle)), (int) (r + needleWidth * Math.sin(thePhysicalAngle)));
        poly.addPoint((int) (r - needleWidth * Math.cos(thePhysicalAngle)), (int) (r - needleWidth * Math.sin(thePhysicalAngle)));
        g.fillPolygon(poly);
        g.setColor(SystemColor.black);
        g.fillOval(r - needleWidth / 2, r - needleWidth / 2, needleWidth, needleWidth);
    }

    /**
     * An inner class whose instances manage the "swinging" of the compass.
     */
    private class CompassSwingerThread extends Thread {
        public void run() {
            while (theThread == Thread.currentThread()) {

                setName("CompassControl Swinger Thread");

                // calculate how far the needle has to swing
                double ang1 = thePhysicalAngle - Math.floor(thePhysicalAngle / (2 * Math.PI)) * 2 * Math.PI;
                double ang2 = theAngle - Math.floor(theAngle / (2 * Math.PI)) * 2 * Math.PI;
                double dif = ang2 - ang1;
                if (dif < -Math.PI) {
                    dif += 2 * Math.PI;
                } else if (dif > Math.PI) {
                    dif -= 2 * Math.PI;
                }

                // The speed of the "swing" is proportional to the
                // sine of the distance left to go.  This simulates
                // a compass needle moving in a damping fluid.
                double step = Math.sin(dif) * .05;

                // prevents the compass from getting "balanced"
                // at dead center away from the target direction.
                if (step < .001 && step > 0) {
                    step = .001;
                } else if (step >= -.001 && step <= 0) {
                    step = -.001;
                }

                // if we're close enough, put the needle where it should
                // be and exit the loop.
                if (Math.abs(step) > Math.abs(dif)) {
                    thePhysicalAngle = theAngle;
                    repaint();
                    break;
                }
                // otherwise, move the needle slightly.
                else {
                    thePhysicalAngle += step;
                    repaint();
                }

                // This controls the timing and lets other threads
                // have some time.
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
            }
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables

    /** the angle for N */
    public static final double N = 0 * Math.PI / 8;

    /** the angle for NNE */
    public static final double NNE = 1 * Math.PI / 8;

    /** the angle for NE */
    public static final double NE = 2 * Math.PI / 8;

    /** the angle for ENE */
    public static final double ENE = 3 * Math.PI / 8;

    /** the angle for E */
    public static final double E = 4 * Math.PI / 8;

    /** the angle for ESE */
    public static final double ESE = 5 * Math.PI / 8;

    /** the angle for SE */
    public static final double SE = 6 * Math.PI / 8;

    /** the angle for SSE */
    public static final double SSE = 7 * Math.PI / 8;

    /** the angle for S */
    public static final double S = 8 * Math.PI / 8;

    /** the angle for SSW */
    public static final double SSW = 9 * Math.PI / 8;

    /** the angle for SW */
    public static final double SW = 10 * Math.PI / 8;

    /** the angle for WSW */
    public static final double WSW = 11 * Math.PI / 8;

    /** the angle for W */
    public static final double W = 12 * Math.PI / 8;

    /** the angle for WNW */
    public static final double WNW = 13 * Math.PI / 8;

    /** the angle for NW */
    public static final double NW = 14 * Math.PI / 8;

    /** the angle for NNW */
    public static final double NNW = 15 * Math.PI / 8;

    /**
     * the angle set on the compass.  (note:  If the compass is "swinging", this
     * may be different than the apparent angle.
     */
    private double theAngle;

    /**
     * the apparent angle shown on the compass, distinguished from the set value
     * when the compass is swinging.
     */
    private double thePhysicalAngle;

    /**
     * the Thread that manages the "swinging" appearance of the compass.
     */
    private Thread theThread;

    // End of variables declaration//GEN-END:variables

}