<commit_before>import * as THREE from 'three';
import threeLine2d from 'three-line-2d';
import threeLine2dShader from 'three-line-2d-shader';

import COLOR from 'configs/colors';
import pileColors from 'components/fragments/pile-colors';

export const ANIMATION = true;

export const ARRANGE_MEASURES = [];

export const CAT_DATASET = 'dataset';

export const CAT_ZOOMOUT_LEVEL = 'zoomout-level';

export const CELL_SIZE = 6;

export const CELL_SIZE_HALF = CELL_SIZE / 2;

export const CELL_THRESHOLD = 0.0;  // only cells above are shown

export const CLICK_DELAY_TIME = 300;

export const CLUSTER_TSNE = '_cluster_tsne';

export const DBL_CLICK_DELAY_TIME = 250;

/**
 * External config to initialize fragments.
 *
 * @description
 * The config is different from the visual state of the app.
 *
 * @type  {Object}
 */
export const CONFIG = {};

export const DIAGONAL_VALUE = 0.11;

export const DURATION = 250;

export const FONT_URL = 'src/assets/fonts/rubik-regular.json';

export const FPS = 25;

export const GRID_CELL_SIZE_LOCK = true;

export const GRID_SIZE = CELL_SIZE;

export const HILBERT_CURVE = false;

export const HIGHLIGHT_FRAME_LINE_WIDTH = 5;

export const HIGLASS_SUB_SELECTION = true;

export const LABEL_DIST = 60;

export const LABEL_WIDTH = 130;

export const LABEL_TEXT_SPEC = {
  size: 6,
  height: 1,
  curveSegments: 3
};

export const LASSO_IS_ROUND = true;

export const LINE = threeLine2d(THREE);

export const LINE_SHADER = threeLine2dShader(THREE);

export const LASSO_LINE_WIDTH = 2;

export const LASSO_MIN_MOVE = 0.033;

export const LASSO_SHADER = threeLine2dShader(THREE)({
  side: THREE.DoubleSide,
  diffuse: COLOR.PRIMARY,
  thickness: LASSO_LINE_WIDTH
});

export const LASSO_MATERIAL = new THREE.ShaderMaterial(LASSO_SHADER);

export const LETTER_SPACE = 6;

export const MARGIN_BOTTOM = 2;

export const MARGIN_LEFT = 2;

export const MARGIN_RIGHT = 2;

export const MARGIN_TOP = 2;

export const MATRICES_COLORS = {};

export const MATRIX_FRAME_ENCODING = null;

export const MATRIX_FRAME_THICKNESS = 2;

export const MATRIX_FRAME_THICKNESS_MAX = 10;

export const MATRIX_GAP_HORIZONTAL = 6;

export const MATRIX_GAP_VERTICAL = 6;

export const MATRIX_ORIENTATION_UNDEF = 0;

export const MATRIX_ORIENTATION_INITIAL = 1;

export const MATRIX_ORIENTATION_5_TO_3 = 2;

export const MATRIX_ORIENTATION_3_TO_5 = 3;

/**
 * Mean
 *
 * @type {Number}
 */
export const MODE_MEAN = 0;

/**
 * Mean average deviation
 *
 * @type {Number}
 */
export const MODE_MAD = 1;

/**
 * Standard deviaton
 *
 * @type {Number}
 */
export const MODE_STD = 2;

export const ORDER_DATA = 0;

export const ORDER_GLOBAL = 1;

export const ORDER_LOCAL = 2;

export const PILE_LABEL_HEIGHT = 10;

export const PILE_MENU_CLOSING_DELAY = 200;

export const PILES = {};

export const PILE_COLORS_CATEGORICAL = pileColors.categorical.length;

export const PREVIEW_SIZE = 2;

export const PREVIEW_MAX = 8;

export const SHADER_ATTRIBUTES = {
  customColor: { type: 'c', value: [] }
};

export const SHOW_MATRICES = 1000;

export const SHOW_SPECIAL_CELLS = false;

export const SVG_MENU_HEIGHT = 30;

export const TIMELINE_HEIGHT = 130;

/**
 * Three.js's WebGL config
 *
 * @type  {Object}
 */
export const WEB_GL_CONFIG = {
  alpha: true,
  antialias: true
};

export const Z_BASE = 1;

export const Z_DRAG = 2;

export const Z_HIGHLIGHT = 1.5;

export const Z_LASSO = 2;

export const Z_MENU = 4;

export const Z_STACK_PILE_TARGET = 2;

export const ZOOM_DELAY_TIME = 500;
<commit_msg>Add default material for the pile area<commit_after>import * as THREE from 'three';
import threeLine2d from 'three-line-2d';
import threeLine2dShader from 'three-line-2d-shader';

import COLORS from 'configs/colors';
import pileColors from 'components/fragments/pile-colors';

export const ANIMATION = true;

export const ARRANGE_MEASURES = [];

export const CAT_DATASET = 'dataset';

export const CAT_ZOOMOUT_LEVEL = 'zoomout-level';

export const CELL_SIZE = 6;

export const CELL_SIZE_HALF = CELL_SIZE / 2;

export const CELL_THRESHOLD = 0.0;  // only cells above are shown

export const CLICK_DELAY_TIME = 300;

export const CLUSTER_TSNE = '_cluster_tsne';

export const DBL_CLICK_DELAY_TIME = 250;

/**
 * External config to initialize fragments.
 *
 * @description
 * The config is different from the visual state of the app.
 *
 * @type  {Object}
 */
export const CONFIG = {};

export const DIAGONAL_VALUE = 0.11;

export const DURATION = 250;

export const FONT_URL = 'src/assets/fonts/rubik-regular.json';

export const FPS = 25;

export const GRID_CELL_SIZE_LOCK = true;

export const GRID_SIZE = CELL_SIZE;

export const HILBERT_CURVE = false;

export const HIGHLIGHT_FRAME_LINE_WIDTH = 5;

export const HIGLASS_SUB_SELECTION = true;

export const LABEL_DIST = 60;

export const LABEL_WIDTH = 130;

export const LABEL_TEXT_SPEC = {
  size: 6,
  height: 1,
  curveSegments: 3
};

export const LASSO_IS_ROUND = true;

export const LINE = threeLine2d(THREE);

export const LINE_SHADER = threeLine2dShader(THREE);

export const LASSO_LINE_WIDTH = 2;

export const LASSO_MIN_MOVE = 0.033;

export const LASSO_SHADER = threeLine2dShader(THREE)({
  side: THREE.DoubleSide,
  diffuse: COLORS.PRIMARY,
  thickness: LASSO_LINE_WIDTH
});

export const LASSO_MATERIAL = new THREE.ShaderMaterial(LASSO_SHADER);

export const LETTER_SPACE = 6;

export const MARGIN_BOTTOM = 2;

export const MARGIN_LEFT = 2;

export const MARGIN_RIGHT = 2;

export const MARGIN_TOP = 2;

export const MATRICES_COLORS = {};

export const PILE_AREA_BG = new THREE.MeshBasicMaterial({
  color: COLORS.PRIMARY,
  transparent: true,
  opacity: 0.2
});

export const PILE_AREA_BORDER = new THREE.ShaderMaterial(LINE_SHADER({
  side: THREE.DoubleSide,
  diffuse: COLORS.PRIMARY,
  thickness: 1,
  opacity: 0.5
}));

export const PILE_AREA_POINTS = new THREE.MeshBasicMaterial({
  color: COLORS.PRIMARY,
  transparent: true,
  opacity: 1
});

export const MATRIX_FRAME_ENCODING = null;

export const MATRIX_FRAME_THICKNESS = 2;

export const MATRIX_FRAME_THICKNESS_MAX = 10;

export const MATRIX_GAP_HORIZONTAL = 6;

export const MATRIX_GAP_VERTICAL = 6;

export const MATRIX_ORIENTATION_UNDEF = 0;

export const MATRIX_ORIENTATION_INITIAL = 1;

export const MATRIX_ORIENTATION_5_TO_3 = 2;

export const MATRIX_ORIENTATION_3_TO_5 = 3;

/**
 * Mean
 *
 * @type {Number}
 */
export const MODE_MEAN = 0;

/**
 * Mean average deviation
 *
 * @type {Number}
 */
export const MODE_MAD = 1;

/**
 * Standard deviaton
 *
 * @type {Number}
 */
export const MODE_STD = 2;

export const ORDER_DATA = 0;

export const ORDER_GLOBAL = 1;

export const ORDER_LOCAL = 2;

export const PILE_LABEL_HEIGHT = 10;

export const PILE_MENU_CLOSING_DELAY = 200;

export const PILES = {};

export const PILE_COLORS_CATEGORICAL = pileColors.categorical.length;

export const PREVIEW_SIZE = 2;

export const PREVIEW_MAX = 8;

export const SHADER_ATTRIBUTES = {
  customColor: { type: 'c', value: [] }
};

export const SHOW_MATRICES = 1000;

export const SHOW_SPECIAL_CELLS = false;

export const SVG_MENU_HEIGHT = 30;

export const TIMELINE_HEIGHT = 130;

/**
 * Three.js's WebGL config
 *
 * @type  {Object}
 */
export const WEB_GL_CONFIG = {
  alpha: true,
  antialias: true
};

export const Z_BASE = 1;

export const Z_DRAG = 2;

export const Z_HIGHLIGHT = 3;

export const Z_HIGHLIGHT_AREA = 2.5;

export const Z_LASSO = 9;

export const Z_MENU = 9;

export const Z_STACK_PILE_TARGET = 2;

export const ZOOM_DELAY_TIME = 500;
<|endoftext|>


<commit_before>// @flow
import { Lbryio } from 'lbryinc';
import ReactGA from 'react-ga';
import { history } from './store';

type Analytics = {
  pageView: string => void,
  setUser: Object => void,
  toggle: (boolean, ?boolean) => void,
  apiLogView: (string, string, string, ?number, ?() => void) => void,
  apiLogPublish: () => void,
};

let analyticsEnabled: boolean = true;
const analytics: Analytics = {
  pageView: path => {
    if (analyticsEnabled) {
      ReactGA.pageview(path, IS_WEB ? ['web'] : ['desktop']);
    }
  },
  setUser: user => {
    // Commented out because currently there is some delay before we know the user
    // We should retrieve this server side so we have it immediately
    // if (analyticsEnabled && user.id) {
    //   ReactGA.set('userId', user.id);
    // }
  },
  toggle: (enabled: boolean): void => {
    // Always collect analytics on lbry.tv
    // @if TARGET='app'
    analyticsEnabled = enabled;
    // @endif
  },
  apiLogView: (uri, outpoint, claimId, timeToStart, onSuccessCb) => {
    if (analyticsEnabled) {
      const params: {
        uri: string,
        outpoint: string,
        claim_id: string,
        time_to_start?: number,
      } = {
        uri,
        outpoint,
        claim_id: claimId,
      };

      if (timeToStart) {
        params.time_to_start = timeToStart;
      }

      Lbryio.call('file', 'view', params)
        .then(() => {
          if (onSuccessCb) {
            onSuccessCb();
          }
        })
        .catch(() => {});
    }
  },
  apiLogSearch: () => {
    if (analyticsEnabled) {
      Lbryio.call('event', 'search');
    }
  },
  apiLogPublish: () => {
    if (analyticsEnabled) {
      Lbryio.call('event', 'publish');
    }
  },
  apiSearchFeedback: (query, vote) => {
    // We don't need to worry about analytics enabled here because users manually click on the button to provide feedback
    Lbryio.call('feedback', 'search', { query, vote });
  },
};

// Initialize google analytics
// Set `debug: true` for debug info
// Will change once we have separate ids for desktop/web
const UA_ID = IS_WEB ? 'UA-60403362-12' : 'UA-60403362-12';

ReactGA.initialize(UA_ID, {
  gaOptions: { name: IS_WEB ? 'web' : 'desktop' },
  testMode: process.env.NODE_ENV !== 'production',
  // debug: true,
});

// Manually call the first page view
// React Router doesn't include this on `history.listen`
analytics.pageView(window.location.pathname + window.location.search);

// Listen for url changes and report
// This will include search queries
history.listen(location => {
  const { pathname, search } = location;

  const page = `${pathname}${search}`;
  analytics.pageView(page);
});

export default analytics;
<commit_msg>enable desktop ga<commit_after>// @flow
import { Lbryio } from 'lbryinc';
import ReactGA from 'react-ga';
import { history } from './store';

type Analytics = {
  pageView: string => void,
  setUser: Object => void,
  toggle: (boolean, ?boolean) => void,
  apiLogView: (string, string, string, ?number, ?() => void) => void,
  apiLogPublish: () => void,
};

let analyticsEnabled: boolean = true;
const analytics: Analytics = {
  pageView: path => {
    if (analyticsEnabled) {
      ReactGA.pageview(path, IS_WEB ? ['web'] : ['desktop']);
    }
  },
  setUser: user => {
    // Commented out because currently there is some delay before we know the user
    // We should retrieve this server side so we have it immediately
    // if (analyticsEnabled && user.id) {
    //   ReactGA.set('userId', user.id);
    // }
  },
  toggle: (enabled: boolean): void => {
    // Always collect analytics on lbry.tv
    // @if TARGET='app'
    analyticsEnabled = enabled;
    // @endif
  },
  apiLogView: (uri, outpoint, claimId, timeToStart, onSuccessCb) => {
    if (analyticsEnabled) {
      const params: {
        uri: string,
        outpoint: string,
        claim_id: string,
        time_to_start?: number,
      } = {
        uri,
        outpoint,
        claim_id: claimId,
      };

      if (timeToStart) {
        params.time_to_start = timeToStart;
      }

      Lbryio.call('file', 'view', params)
        .then(() => {
          if (onSuccessCb) {
            onSuccessCb();
          }
        })
        .catch(() => {});
    }
  },
  apiLogSearch: () => {
    if (analyticsEnabled) {
      Lbryio.call('event', 'search');
    }
  },
  apiLogPublish: () => {
    if (analyticsEnabled) {
      Lbryio.call('event', 'publish');
    }
  },
  apiSearchFeedback: (query, vote) => {
    // We don't need to worry about analytics enabled here because users manually click on the button to provide feedback
    Lbryio.call('feedback', 'search', { query, vote });
  },
};

// Initialize google analytics
// Set `debug: true` for debug info
// Will change once we have separate ids for desktop/web
const UA_ID = IS_WEB ? 'UA-60403362-12' : 'UA-60403362-13';

ReactGA.initialize(UA_ID, {
  gaOptions: { name: IS_WEB ? 'web' : 'desktop' },
  testMode: process.env.NODE_ENV !== 'production',
  // debug: true,
});

// Manually call the first page view
// React Router doesn't include this on `history.listen`
analytics.pageView(window.location.pathname + window.location.search);

// Listen for url changes and report
// This will include search queries
history.listen(location => {
  const { pathname, search } = location;

  const page = `${pathname}${search}`;
  analytics.pageView(page);
});

export default analytics;
<|endoftext|>


<commit_before>require('proof')(2, require('cadence')(prove))

function prove (async, assert) {
    var stream = require('stream')
    var Queue = require('../queue')
    var queue
    async(function () {
        queue = new Queue(new stream.PassThrough)
        queue.write(1 + '\n')
        queue.write(2 + '\n')
        queue.write(3 + '\n')
        queue.flush(async())
    }, function () {
        var chunk = queue._stream.read().toString()
        assert(chunk, '% 0 aaaaaaaa 811c9dc5 1\n% 1 811c9dc5 fdaf7437 6\n1\n2\n3\n', 'initialize')
        queue.flush(async())
    }, function () {
        queue.exit(null)
        queue.exit(null)
        queue.flush(async())
    }, function () {
        queue = new Queue(new stream.PassThrough)
        var stderr = new stream.PassThrough
        queue.exit(stderr)
        var chunk = stderr.read().toString()
        assert(chunk, '% 0 aaaaaaaa 811c9dc5 0\n% 0 aaaaaaaa 811c9dc5 1\n', 'exit')
    })
}
<commit_msg>Fix Queue test.<commit_after>require('proof')(2, require('cadence')(prove))

function prove (async, assert) {
    var stream = require('stream')
    var Queue = require('../queue')
    var queue
    async(function () {
        queue = new Queue(new stream.PassThrough)
        queue.write(1 + '\n')
        queue.write(2 + '\n')
        queue.write(3 + '\n')
        queue.flush(async())
    }, function () {
        var chunk = queue._stream.read().toString()
        assert(chunk, '% 0 aaaaaaaa 811c9dc5 1\n% 1 811c9dc5 fdaf7437 6\n1\n2\n3\n', 'initialize')
        queue.flush(async())
    }, function () {
        queue.exit(null)
        queue.exit(null)
        queue.flush(async())
    }, function () {
        queue = new Queue(new stream.PassThrough)
        var stderr = new stream.PassThrough
        queue.exit(stderr)
        var chunk = stderr.read().toString()
        assert(chunk, '% 0 aaaaaaaa 811c9dc5 0\n% 0 811c9dc5 811c9dc5 1\n', 'exit')
    })
}
<|endoftext|>


<commit_before>'use strict';

/**
 * MySQL allows you to connect to a MySQL database and make queries to it.
 * @namespace
 */

var MySQL = function () {

	this.connections = {};
};

/**
 * @implements {MySQL}
 * @param {string} database - This is a alias for you to use to refrence a database connection.
 * @param {object} options
 *		username - Required
 *		password - Required
 *		database - Required
 *		url      - Required
 */

MySQL.prototype.connect = function ( database, options ) {

	if ( typeof options !== 'object' ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): Invalid options parameter type:'
			+ ( typeof options )
		);
	}

	if ( options.username === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.username is required' );
	}

	if ( options.password === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.password is required' );
	}

	if ( options.database === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.database is required' );
	}

	if ( options.url === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.url is required' );
	}

	if ( options.url.match( /:[0-9]+$/ ) ) {
		options.port = '';

	} else {
		options.port = ':' + ( options.port || 3306 );
	}

	var Properties = Java.type( 'java.util.Properties' );
	var Driver     = Java.type( 'com.mysql.jdbc.Driver' );
	var driver     = new Driver();
	var properties = new Properties();
	var connection = null;

	try {
		properties.setProperty( 'user',     options.username );
		properties.setProperty( 'password', options.password );

		connection = driver.connect( 'jdbc:mysql://' + options.url + options.port + '/' + options.database, properties );

		MCJS.addCleanupTask( function () {

			connection.close();
		} );

		this.connections[ database ] = connection;

	} catch ( error ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', options ): connection failed: ' + error );
	}
};

/**
 * @implements {MySQL}
 * @param {string} database - Alias for refrencing a database connection.
 * @param {string} query - Query to be sent to the target mysql database.
 * @param {array} arguments - Arguments to be passed into the query.
 */

MySQL.prototype.query = function ( database, rawQuery, rawArgs ) {

	if ( !this.connections[ database ] ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): invalid database connection' );
	}

	var args    = rawArgs || [];
	var query   = rawQuery;
	var indexes = [];

	var i = -1;

	while ( ( i = query.indexOf( '?', i + 1 ) ) >= 0 ) {
		indexes.push( i );
	}

	if ( args.length !== indexes.length ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): number of arguments does not match number of replacements' );
	}

	for ( var i = args.length - 1; i > -1; i-- ) {
		var arg   = args[ i ].replace( /\\/g, '\\\\' ).replace( /'/g, '\\\'' );
		var index = indexes[ i ];

		query = query.substr( 0, index ) + '\'' + arg + '\'' + query.substr( index + 1 );
	}

	var results = [];

	var resultSet;
	var statement;

	try {
		statement = this.connections[ database ].prepareStatement( query );

		if ( statement.execute() ) {
			resultSet = statement.getResultSet();

			resultSet.last();

			var resultAmount = resultSet.getRow();

			resultSet.first();

			var meta         = resultSet.getMetaData();
			var columnAmount = meta.getColumnCount();

			var columns = [];

			for ( var i = 1; i < columnAmount + 1; i++ ) {
				columns.push(  meta.getColumnName( i ) );
			}

			for ( var resultIndex = 1; resultIndex < resultAmount + 1; resultIndex++ ) {

				var object = {};

				for ( var i in columns ) {
					var column = columns[ i ];

					object[ column ] = resultSet.getString( columns[ i ] );
				}

				results.push( object );

				if ( resultIndex !== resultAmount ) {
					resultSet.next();
				}
			}
		}
	} catch ( error ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): ' + error );

	} finally {

		if ( resultSet ) {

			try {
				resultSet.close();
			} catch ( error ) {
				// Do Nothing
			}
		}

		if ( statement ) {

			try {
				statement.close();
			} catch ( error ) {
				// Do Nothing
			}
		}
	}

	return results;
};

module.exports = new MySQL();
<commit_msg>JSDoc comments<commit_after>'use strict';

/**
 * MySQL allows you to connect to a MySQL database and make queries to it.
 * @namespace
 */

var MySQL = function () {

	this.connections = {};
};

/**
 * @implements {MySQL}
 * @param {String} database - This is a alias for you to use to refrence a database connection.
 * @param {Object} options
 * @param {String} options.username - Required
 * @param {String} options.password - Required
 * @param {String} options.database - Required
 * @param {String} options.url - Required
 */

MySQL.prototype.connect = function ( database, options ) {

	if ( typeof options !== 'object' ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): Invalid options parameter type:'
			+ ( typeof options )
		);
	}

	if ( options.username === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.username is required' );
	}

	if ( options.password === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.password is required' );
	}

	if ( options.database === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.database is required' );
	}

	if ( options.url === undefined ) {
		throw new Error( 'Error in MySQL.connect( \'' + database + '\', options ): options.url is required' );
	}

	if ( options.url.match( /:[0-9]+$/ ) ) {
		options.port = '';

	} else {
		options.port = ':' + ( options.port || 3306 );
	}

	var Properties = Java.type( 'java.util.Properties' );
	var Driver     = Java.type( 'com.mysql.jdbc.Driver' );
	var driver     = new Driver();
	var properties = new Properties();
	var connection = null;

	try {
		properties.setProperty( 'user',     options.username );
		properties.setProperty( 'password', options.password );

		connection = driver.connect( 'jdbc:mysql://' + options.url + options.port + '/' + options.database, properties );

		MCJS.addCleanupTask( function () {

			connection.close();
		} );

		this.connections[ database ] = connection;

	} catch ( error ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', options ): connection failed: ' + error );
	}
};

/**
 * @implements {MySQL}
 * @param {string} database - Alias for refrencing a database connection.
 * @param {string} query - Query to be sent to the target mysql database.
 * @param {array} arguments - Arguments to be passed into the query.
 */

MySQL.prototype.query = function ( database, rawQuery, rawArgs ) {

	if ( !this.connections[ database ] ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): invalid database connection' );
	}

	var args    = rawArgs || [];
	var query   = rawQuery;
	var indexes = [];

	var i = -1;

	while ( ( i = query.indexOf( '?', i + 1 ) ) >= 0 ) {
		indexes.push( i );
	}

	if ( args.length !== indexes.length ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): number of arguments does not match number of replacements' );
	}

	for ( var i = args.length - 1; i > -1; i-- ) {
		var arg   = args[ i ].replace( /\\/g, '\\\\' ).replace( /'/g, '\\\'' );
		var index = indexes[ i ];

		query = query.substr( 0, index ) + '\'' + arg + '\'' + query.substr( index + 1 );
	}

	var results = [];

	var resultSet;
	var statement;

	try {
		statement = this.connections[ database ].prepareStatement( query );

		if ( statement.execute() ) {
			resultSet = statement.getResultSet();

			resultSet.last();

			var resultAmount = resultSet.getRow();

			resultSet.first();

			var meta         = resultSet.getMetaData();
			var columnAmount = meta.getColumnCount();

			var columns = [];

			for ( var i = 1; i < columnAmount + 1; i++ ) {
				columns.push(  meta.getColumnName( i ) );
			}

			for ( var resultIndex = 1; resultIndex < resultAmount + 1; resultIndex++ ) {

				var object = {};

				for ( var i in columns ) {
					var column = columns[ i ];

					object[ column ] = resultSet.getString( columns[ i ] );
				}

				results.push( object );

				if ( resultIndex !== resultAmount ) {
					resultSet.next();
				}
			}
		}
	} catch ( error ) {
		throw new Error( 'Error in MySQL.query( \'' + database + '\', query ): ' + error );

	} finally {

		if ( resultSet ) {

			try {
				resultSet.close();
			} catch ( error ) {
				// Do Nothing
			}
		}

		if ( statement ) {

			try {
				statement.close();
			} catch ( error ) {
				// Do Nothing
			}
		}
	}

	return results;
};

module.exports = new MySQL();
<|endoftext|>


<commit_before>'use strict';

const spawnSync = require('child_process').spawnSync;
const fs = require('fs');
const path = require('path');

const conf = {};
const confFile = './conf.yml';
const confUiFile = './patternlab-config.json';
const enc = 'utf8';

let extendDir;
let sourceDir;

if (fs.existsSync(confFile)) {
  const confStr = fs.readFileSync(confFile, enc);
  const confLines = confStr.split('\n');

  for (let confLine of confLines) {
    const keyVal = confLine.split(':');

    if (keyVal[0].trim() === 'extend_dir' && keyVal[1]) {
      extendDir = keyVal[1].trim();
    }
  }
}
// confFile may not exists at this point of installation. Hard-code in that case.
else {
  extendDir = 'extend';
}

if (fs.existsSync(confUiFile)) {
  const confUiStr = fs.readFileSync(confUiFile, enc);

  try {
    conf.ui = JSON.parse(confUiStr);
  }
  catch (err) {
    throw err;
  }

  if (conf.ui) {
    sourceDir = conf.ui.paths.source.root;
  }
}
// confUiFile may not exists at this point of installation. Hard-code in that case.
else {
  sourceDir = 'source';
}

// Create empty extend and source dirs so the postinstall script doesn't write the main profile there.
if (!fs.existsSync(extendDir)) {
  fs.mkdirSync(extendDir);
}

if (!fs.existsSync(sourceDir)) {
  fs.mkdirSync(sourceDir);
  fs.mkdirSync(`${sourceDir}/_data`);
  fs.mkdirSync(`${sourceDir}/_patterns`);
  fs.mkdirSync(`${sourceDir}/_styles`);
  fs.writeFileSync(`${sourceDir}/_data/data.json`, '{}');
  fs.writeFileSync(`${sourceDir}/_data/listitems.json`, '{}');
}

// Output to install.log.
const installLog = 'install.log';
let spawnedObj;

fs.writeFileSync(installLog, '');

// Only run npm install if not already installed.
if (!fs.existsSync('node_modules')) {
  let binNpm = 'npm';

  // Spawn npm.cmd if Windows and not BASH.
  if (process.env.ComSpec && process.env.ComSpec.toLowerCase() === 'c:\\windows\\system32\\cmd.exe') {
    binNpm = 'npm.cmd';
  }

  spawnedObj = spawnSync(binNpm, ['install', '--ignore-scripts'], {stdio: 'inherit'});
}

if (spawnedObj && spawnedObj.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj.stderr}\n`);
}

// Check if patterns dir is already populated.
const patternsDirContent = fs.readdirSync(`${sourceDir}/_patterns`);

// Return if already populated.
if (patternsDirContent.length) {
  const warning = `The ${sourceDir} directory already has content! Aborting base install!`;

  // eslint-disable-next-line no-console
  console.warn(warning);
  fs.appendFileSync(installLog, `${warning}\n`);

  return;
}

// Delete the source and extend dirs so new ones can be copied over.
fs.unlinkSync(`${sourceDir}/_data/listitems.json`);
fs.unlinkSync(`${sourceDir}/_data/data.json`);
fs.rmdirSync(`${sourceDir}/_styles`);
fs.rmdirSync(`${sourceDir}/_patterns`);
fs.rmdirSync(`${sourceDir}/_data`);
fs.rmdirSync(sourceDir);
fs.rmdirSync(extendDir);

const binPath = path.resolve('node_modules', '.bin');
const fepperPath = path.resolve('node_modules', 'fepper');
const winGulp = path.resolve(binPath, 'gulp.cmd');

let binGulp = path.resolve(binPath, 'gulp');

// Spawn gulp.cmd if Windows and not BASH.
if (process.env.ComSpec && process.env.ComSpec.toLowerCase() === 'c:\\windows\\system32\\cmd.exe') {
  binGulp = winGulp;
}

// Copy over the base profile source dir.
const spawnedObj1 =
  spawnSync(binGulp, ['--gulpfile', path.resolve(fepperPath, 'tasker.js'), 'install:copy-base'], {stdio: 'inherit'});

if (spawnedObj1.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj1.stderr}\n`);
}

// Complete installation.
const spawnedObj2 = spawnSync('node', [path.resolve(fepperPath, 'run', 'install.js')], {stdio: 'inherit'});

if (spawnedObj2.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj2.stderr}\n`);
}

fs.appendFileSync(installLog, `Process exited with status ${spawnedObj2.status}.\n`);
<commit_msg>fixing install-base script<commit_after>'use strict';

const spawnSync = require('child_process').spawnSync;
const fs = require('fs');
const path = require('path');

const conf = {};
const confFile = './conf.yml';
const confUiFile = './patternlab-config.json';
const enc = 'utf8';
const fepperPath = path.resolve('node_modules', 'fepper');
const prefFile = './pref.yml';

let extendDir;
let sourceDir;

if (fs.existsSync(confFile)) {
  const confStr = fs.readFileSync(confFile, enc);
  const confLines = confStr.split('\n');

  for (let confLine of confLines) {
    const keyVal = confLine.split(':');

    if (keyVal[0].trim() === 'extend_dir' && keyVal[1]) {
      extendDir = keyVal[1].trim();
    }
  }
}
// confFile may not exists at this point of installation. Hard-code in that case.
else {
  extendDir = 'extend';
}

if (fs.existsSync(confUiFile)) {
  const confUiStr = fs.readFileSync(confUiFile, enc);

  try {
    conf.ui = JSON.parse(confUiStr);
  }
  catch (err) {
    throw err;
  }

  if (conf.ui) {
    sourceDir = conf.ui.paths.source.root;
  }
}
// confUiFile may not exists at this point of installation. Hard-code in that case.
else {
  sourceDir = 'source';
}

// Create empty extend and source dirs so the postinstall script doesn't write the main profile there.
if (!fs.existsSync(extendDir)) {
  fs.mkdirSync(extendDir);
}

if (!fs.existsSync(sourceDir)) {
  fs.mkdirSync(sourceDir);
  fs.mkdirSync(`${sourceDir}/_data`);
  fs.mkdirSync(`${sourceDir}/_patterns`);
  fs.mkdirSync(`${sourceDir}/_styles`);
  fs.writeFileSync(`${sourceDir}/_data/data.json`, '{}');
  fs.writeFileSync(`${sourceDir}/_data/listitems.json`, '{}');
}

// Output to install.log.
const installLog = 'install.log';
let spawnedObj;

fs.writeFileSync(installLog, '');

// Only run npm install if not already installed.
if (!fs.existsSync('node_modules')) {
  let binNpm = 'npm';

  // Spawn npm.cmd if Windows and not BASH.
  if (process.env.ComSpec && process.env.ComSpec.toLowerCase() === 'c:\\windows\\system32\\cmd.exe') {
    binNpm = 'npm.cmd';
  }

  spawnedObj = spawnSync(binNpm, ['install', '--ignore-scripts'], {stdio: 'inherit'});
}

if (spawnedObj && spawnedObj.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj.stderr}\n`);
}

if (!fs.existsSync(confFile)) {
  fs.copyFileSync(path.resolve(fepperPath, 'excludes', 'conf.yml'), confFile);
}

if (!fs.existsSync(confUiFile)) {
  fs.copyFileSync(path.resolve(fepperPath, 'excludes', 'patternlab-config.json'), confUiFile);
}

if (!fs.existsSync(prefFile)) {
  fs.copyFileSync(path.resolve(fepperPath, 'excludes', 'pref.yml'), prefFile);
}

// Delete the source and extend dirs so new ones can be copied over.
// fs.rmdirSync will throw an error if directory is already populated.
fs.unlinkSync(`${sourceDir}/_data/listitems.json`);
fs.unlinkSync(`${sourceDir}/_data/data.json`);
fs.rmdirSync(`${sourceDir}/_styles`);
fs.rmdirSync(`${sourceDir}/_patterns`);
fs.rmdirSync(`${sourceDir}/_data`);
fs.rmdirSync(sourceDir);
fs.rmdirSync(extendDir);

const binPath = path.resolve('node_modules', '.bin');
const winGulp = path.resolve(binPath, 'gulp.cmd');

let binGulp = path.resolve(binPath, 'gulp');

// Spawn gulp.cmd if Windows and not BASH.
if (process.env.ComSpec && process.env.ComSpec.toLowerCase() === 'c:\\windows\\system32\\cmd.exe') {
  binGulp = winGulp;
}

// Copy over the base profile source dir.
const spawnedObj1 =
  spawnSync(binGulp, ['--gulpfile', path.resolve(fepperPath, 'tasker.js'), 'install:copy-base'], {stdio: 'inherit'});

if (spawnedObj1.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj1.stderr}\n`);
}

// Complete installation.
const spawnedObj2 = spawnSync('node', [path.resolve('run', 'install.js')], {stdio: 'inherit'});

if (spawnedObj2.stderr) {
  fs.appendFileSync(installLog, `${spawnedObj2.stderr}\n`);
}

fs.appendFileSync(installLog, `Process exited with status ${spawnedObj2.status}.\n`);
<|endoftext|>


<commit_before>// SearchFormView
define(function (require) {
  var _ = require('underscore'),
    $ = require('jquery'),
    Backbone = require('backbone'),
    Handlebars = require('handlebars'),
    search_form_tmpl = require('text!./tmpl/search_form.html'),
    filter_to_matching_stems = require('./filter_to_matching_stems'),
    SuggestionsView = require('./suggestions');

  var SearchFormView = Backbone.View.extend({

    tagName: 'form',

    className: 'navbar-form navbar-left',

    template: Handlebars.compile(search_form_tmpl),

    events: {
      'change input': 'set_query',
      'keyup input': 'set_query',
      'input input': 'set_query',
      'keydown input': 'domain_match'
    },

    initialize: function(options) {
      var t = this;
      t.query_model = options.query_model;
      t.domain_list_model = options.domain_list_model;
      _.bindAll(t, 'set_query');
      t.listenTo(t.query_model, 'change:domain', t.render);

      t.suggestions_model = new Backbone.Model();
      t.suggestions_view = new SuggestionsView({
        suggestions_model: t.suggestions_model
      });
    },

    render: function() {
      var t = this;
      t.$el.html(t.template(t.query_model.toJSON()));

      t.$el.append(t.suggestions_view.render().el);

      // Determine size of domain bubble and adjust input width
      var bubble = t.$('.domain-bubble');
      if (bubble.length > 0) {
        var bubble_width = bubble.outerWidth();
        t.$('input').css('padding-left', bubble_width + 6);
      }

      return t;
    },

    domain_match: function(e) {
       // If tab is pressed, check for a domain match.
       var t = this;

       var search_val = t.$('input').val();

       // If we don't already have a domain filter, try to complete one.
       if (!t.query_model.get('domain')) {

         // Step 1: Filter to domains with stems matching the search string.
         var domains_matching_stem = filter_to_matching_stems({
           search: search_val,
           array: t.domain_list_model.get('domains')
          });

         if (e.keyCode == '9') {
           e.preventDefault();

           // Step 2: Set domain on query model if exact match
           // and if this is the second time the user hits tab after
           // a completion.
           if (t.in_completion) {
             if (domains_matching_stem.length === 1) {
               t.query_model.set('domain', search_val);
               t.$('input').val('');
               t.suggestions_model.unset('suggestions');
               return;
             } else {
               // Render a list of suggestions if multiple matches
               t.suggestions_model.set('suggestions', domains_matching_stem);
             }
           }

           // Keep track of when we are in the middle of a completion.
           if (domains_matching_stem.length > 0) {
             t.in_completion = true;

             // Step 3: Find longest stem matching all filtered domains.
             var initial_stem_length = search_val.length + 1;
             var domain_match = domains_matching_stem[0];
             var max_stem_length = domain_match.length;
             var longest_matching_stem = search_val;
             console.log(domains_matching_stem);
             for (var i = initial_stem_length; i < max_stem_length; i++) {
               var new_stem = domain_match.slice(0, i);
               var all_matching = _.all(domains_matching_stem, function(domain) {
                 return new_stem === domain.slice(0, i);
               });
               if (!all_matching) {
                 break;
               } else {
                 longest_matching_stem = new_stem;
               }
             }
             console.log(longest_matching_stem);
             t.$('input').val(longest_matching_stem);
           }

         } else {
           // If tab is not pressed, remove suggestions.
           t.suggestions_model.unset('suggestions');
           // If we are in the middle of a completion, and space
           // is pressed...
           if (t.in_completion && e.keyCode == '32') {
             console.log('in completion, space pressed');
             // And the matches contain an exact match, finish the completion
             // with the search value.
             if (_.contains(domains_matching_stem, search_val)) {
               e.preventDefault();
               t.query_model.set('domain', search_val.trim());
               t.$('input').val('');
               return;
             }
           }
           t.in_completion = false;
         }
       }
    },

    set_query: function() {
       var t = this;
       var search_val = t.$('input').val();

       if (search_val.length > 2 && !t.in_completion) {
         t.query_model.set('search', search_val);
       } else {
         // Unset the search if there are fewer than 3 characters
         // or if we are in the middle of a completion.
         t.query_model.set('search', undefined);
      }
    }

  });

  return SearchFormView;

});

<commit_msg>Exit completion mode when a completion is made<commit_after>// SearchFormView
define(function (require) {
  var _ = require('underscore'),
    $ = require('jquery'),
    Backbone = require('backbone'),
    Handlebars = require('handlebars'),
    search_form_tmpl = require('text!./tmpl/search_form.html'),
    filter_to_matching_stems = require('./filter_to_matching_stems'),
    SuggestionsView = require('./suggestions');

  var SearchFormView = Backbone.View.extend({

    tagName: 'form',

    className: 'navbar-form navbar-left',

    template: Handlebars.compile(search_form_tmpl),

    events: {
      'change input': 'set_query',
      'keyup input': 'set_query',
      'input input': 'set_query',
      'keydown input': 'domain_match'
    },

    initialize: function(options) {
      var t = this;
      t.query_model = options.query_model;
      t.domain_list_model = options.domain_list_model;
      _.bindAll(t, 'set_query');
      t.listenTo(t.query_model, 'change:domain', t.render);

      t.suggestions_model = new Backbone.Model();
      t.suggestions_view = new SuggestionsView({
        suggestions_model: t.suggestions_model
      });
    },

    render: function() {
      var t = this;
      t.$el.html(t.template(t.query_model.toJSON()));

      t.$el.append(t.suggestions_view.render().el);

      // Determine size of domain bubble and adjust input width
      var bubble = t.$('.domain-bubble');
      if (bubble.length > 0) {
        var bubble_width = bubble.outerWidth();
        t.$('input').css('padding-left', bubble_width + 6);
      }

      return t;
    },

    domain_match: function(e) {
       // If tab is pressed, check for a domain match.
       var t = this;

       var search_val = t.$('input').val();

       // If we don't already have a domain filter, try to complete one.
       if (!t.query_model.get('domain')) {

         // Step 1: Filter to domains with stems matching the search string.
         var domains_matching_stem = filter_to_matching_stems({
           search: search_val,
           array: t.domain_list_model.get('domains')
          });

         if (e.keyCode == '9') {
           e.preventDefault();

           // Step 2: Set domain on query model if exact match
           // and if this is the second time the user hits tab after
           // a completion.
           if (t.in_completion) {
             if (domains_matching_stem.length === 1) {
               t.query_model.set('domain', search_val);
               t.$('input').val('');
               t.suggestions_model.unset('suggestions');
               t.in_completion = false;
               return;
             } else {
               // Render a list of suggestions if multiple matches
               t.suggestions_model.set('suggestions', domains_matching_stem);
             }
           }

           // Keep track of when we are in the middle of a completion.
           if (domains_matching_stem.length > 0) {
             t.in_completion = true;

             // Step 3: Find longest stem matching all filtered domains.
             var initial_stem_length = search_val.length + 1;
             var domain_match = domains_matching_stem[0];
             var max_stem_length = domain_match.length;
             var longest_matching_stem = search_val;
             console.log(domains_matching_stem);
             for (var i = initial_stem_length; i < max_stem_length; i++) {
               var new_stem = domain_match.slice(0, i);
               var all_matching = _.all(domains_matching_stem, function(domain) {
                 return new_stem === domain.slice(0, i);
               });
               if (!all_matching) {
                 break;
               } else {
                 longest_matching_stem = new_stem;
               }
             }
             console.log(longest_matching_stem);
             t.$('input').val(longest_matching_stem);
           }

         } else {
           // If tab is not pressed, remove suggestions.
           t.suggestions_model.unset('suggestions');
           // If we are in the middle of a completion, and space
           // is pressed...
           if (t.in_completion && e.keyCode == '32') {
             console.log('in completion, space pressed');
             // And the matches contain an exact match, finish the completion
             // with the search value.
             if (_.contains(domains_matching_stem, search_val)) {
               e.preventDefault();
               t.query_model.set('domain', search_val.trim());
               t.$('input').val('');
             }
           }
           t.in_completion = false;
         }
       }
    },

    set_query: function() {
       var t = this;
       var search_val = t.$('input').val();

       if (search_val.length > 2 && !t.in_completion) {
         t.query_model.set('search', search_val);
       } else {
         // Unset the search if there are fewer than 3 characters
         // or if we are in the middle of a completion.
         t.query_model.set('search', undefined);
      }
    }

  });

  return SearchFormView;

});

<|endoftext|>


<commit_before>var http = require('http');
var utils = require('util');
var path = require('path');
var fs = require('fs');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:');
var json;

var table_name = "user_info";
var pets;
//console.log(pets);
var pet;
var id;
var name;
var url;

fs.readFile('./MockData.json', 'utf8', function (err, data) {
  if (err) {
      console.log("ERROR: JSON load - " + err);
      throw err;
  } else {
      try {
          json = JSON.parse(data);
          console.log("JSON loaded successfully");
          //console.log(json.data);

          var mockdata = json.mockdata;
          //console.log(mockdata);
          pets = mockdata.pets
          // for (i = 0; i < pets.length; i++)
          // {
          //   pet = pets[i];
          //   id = pet.id;
          //   name = pet.name;
          //   url = pet.url;
          //   console.log(i + ": id: " + id + ", name: " + ", url: " + url);
          // }

          //var pet = data["mockdata"]["pets"][0];
          //console.log(pet);
      }
      catch (ex) {
          console.log("ERROR: JSON parse - " + err);
      }
  }
});

db.serialize(function() {
  console.log("Database Serialization Initializing...");

  db.run("CREATE TABLE if not exists " + table_name + " (id INTEGER PRIMARY KEY, name TEXT, imageUrl TEXT)");
  var stmt = db.prepare("INSERT INTO " + table_name + "(id,name,imageUrl) VALUES (?,?,?)");
  for (var i = 0; i < 10; i++) {
      pet = pets[i];
      id = pet.id;
      name = pet.name;
      url = pet.url;
      console.log(i + ": id: " + id + ", name: " + ", url: " + url);
      stmt.run(id, name, url);
      console.log("Row inserted");
  }
  stmt.finalize();

  db.each("SELECT rowid AS id, info FROM " + table_name, function(err, row) {
      console.log(row.id + ": " + row.info);
  });

  console.log("Table " + table_name + " initialized");

});

db.close();
<commit_msg>--console logs<commit_after>var http = require('http');
var utils = require('util');
var path = require('path');
var fs = require('fs');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:');
var json;

var table_name = "user_info";
var pets;
//console.log(pets);
var pet;
var id;
var name;
var url;

fs.readFile('./MockData.json', 'utf8', function (err, data) {
  console.log("JSON Initializing...");
  if (err) {
      console.log("ERROR: JSON load - " + err);
      throw err;
  } else {
      try {
          json = JSON.parse(data);
          console.log("JSON loaded successfully");
          //console.log(json.data);

          var mockdata = json.mockdata;
          //console.log(mockdata);
          pets = mockdata.pets
          // for (i = 0; i < pets.length; i++)
          // {
          //   pet = pets[i];
          //   id = pet.id;
          //   name = pet.name;
          //   url = pet.url;
          //   console.log(i + ": id: " + id + ", name: " + ", url: " + url);
          // }

          //var pet = data["mockdata"]["pets"][0];
          //console.log(pet);
      }
      catch (ex) {
          console.log("ERROR: JSON parse - " + err);
      }
  }
  console.log("JSON initialized!");
});

db.serialize(function() {
  console.log("Database Serialization Initializing...");

  db.run("CREATE TABLE if not exists " + table_name + " (id INTEGER PRIMARY KEY, name TEXT, imageUrl TEXT)");
  var stmt = db.prepare("INSERT INTO " + table_name + "(id,name,imageUrl) VALUES (?,?,?)");
  for (var i = 0; i < 10; i++) {
      pet = pets[i];
      id = pet.id;
      name = pet.name;
      url = pet.url;
      console.log(i + ": id: " + id + ", name: " + ", url: " + url);
      stmt.run(id, name, url);
      console.log("Row inserted");
  }
  stmt.finalize();

  db.each("SELECT rowid AS id, info FROM " + table_name, function(err, row) {
      console.log(row.id + ": " + row.info);
  });

  console.log("Table " + table_name + " initialized!");

});

db.close();
<|endoftext|>


<commit_before>/*
 Copyright 2016 - 2017 by Jan Dockx

 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.
 */

(function(factory) {
  "use strict";

  var dependencies = ["../_util/describe", "../_util/it", "../_util/expect", "../_util/testUtil",
                      "𝕋合同/_private/util", "./AbstractContractCommon", "𝕋合同/III/Contract"];

  if (typeof define === "function" && define.amd) {
    define(dependencies, factory);
  }
  else if (typeof exports === "object") {
    module.exports =
      factory.apply(undefined, dependencies.map(function(d) {return require(d.replace("𝕋合同", "../../src"));}));
  }
}(function(describe, it, expect, testUtil, util, common, Contract) {
  "use strict";

  function expectInvariants(subject) {
    expect(subject).to.be.an.instanceOf(Contract);
    common.expectInvariants(subject);
    expect(subject.location).to.satisfy(function(location) {return util.isALocationOutsideLibrary(location);});
    // this strengthening implies the same for the location of subject.abstract, since the locations have to be the same
    expect(subject.abstract).to.satisfy(function(cf) {return Contract.isAContractFunction(cf);});
    expect(subject).to.have.property("implementation").that.is.a("function");
  }

  //noinspection FunctionNamingConventionJS
  function generatePrototypeMethodsDescriptions(oneSubjectGenerator, allSubjectGenerators) {
    common.generatePrototypeMethodsDescriptions(oneSubjectGenerator, allSubjectGenerators);
    var self = this; // jshint ignore:line

    //noinspection FunctionTooLongJS
    describe("#implementation", function() {
      function expectPost(contract, implFunction , result) {
        //noinspection BadExpressionStatementJS,JSHint
        expect(contract.isImplementedBy(result)).to.be.ok;
        expect(result).to.satisfy(Contract.isAContractFunction);
        expect(result).to.have.property("contract").that.equals(contract);
        expect(result).to.have.property("implementation").that.equals(implFunction);
        self.expectInvariants(contract);
      }

      it("returns an Contract function that is configured as expected", function() {
        var subject = oneSubjectGenerator();
        var impl = function() {};
        var result = subject.implementation(impl);
        expectPost(subject, impl, result);
      });

      it("returns a different Contract function when called with the same implementation", function() {
        var subject = oneSubjectGenerator();
        var impl = function() {};
        var result = subject.implementation(impl);
        //noinspection LocalVariableNamingConventionJS
        var result2 = subject.implementation(impl);
        expectPost(subject, impl, result2);
        expect(result2).to.not.equal(result);
      });

      it("returns a different Contract function with a different implementation", function() {
        var subject = oneSubjectGenerator();
        var impl = function() {};
        //noinspection LocalVariableNamingConventionJS
        var impl2 = function() {};
        var result = subject.implementation(impl);
        //noinspection LocalVariableNamingConventionJS
        var result2 = subject.implementation(impl2);
        expectPost(subject, impl2, result2);
        expect(result2).to.not.equal(result);
        expect(result2).to.have.property("implementation").that.not.equals(result.implementation);
      });

    });

  }

  var test = {
    expectInvariants: expectInvariants,
    generatePrototypeMethodsDescriptions: generatePrototypeMethodsDescriptions
  };
  Object.setPrototypeOf(test, common);
  return test;

}));
<commit_msg>IV/ContractCommon: remove AMD, standardify, es-ify, use arrow functions where appropriate, use must instead of chai<commit_after>/*
 Copyright 2016 - 2017 by Jan Dockx

 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.
 */

/* eslint-env mocha */

'use strict'

const util = require('../../src/_private/util')
const common = require('./AbstractContractCommon')
const Contract = require('../../src/IV/Contract')

function expectInvariants (subject) {
  subject.must.be.an.instanceof(Contract)
  common.expectInvariants(subject)
  util.isALocationOutsideLibrary(subject.location).must.be.true()
  // this strengthening implies the same for the location of subject.abstract, since the locations have to be the same
  // noinspection JSUnresolvedFunction, JSUnresolvedVariable
  Contract.isAContractFunction(subject.abstract)
  subject.implementation.must.be.a.function()
}

// noinspection FunctionNamingConventionJS
function generatePrototypeMethodsDescriptions (oneSubjectGenerator, allSubjectGenerators) {
  common.generatePrototypeMethodsDescriptions(oneSubjectGenerator, allSubjectGenerators)
  const self = this // jshint ignore:line

  describe('#implementation', function () {
    function expectPost (contract, implFunction, result) {
      contract.isImplementedBy(result).must.be.true()
      // noinspection JSUnresolvedFunction
      Contract.isAContractFunction(result).must.be.true()
      result.contract.must.equal(contract)
      result.implementation.must.equal(implFunction)
      self.expectInvariants(contract)
    }

    it('returns an Contract function that is configured as expected', function () {
      const subject = oneSubjectGenerator()
      const impl = function () {}
      const result = subject.implementation(impl)
      expectPost(subject, impl, result)
    })

    it('returns a different Contract function when called with the same implementation', function () {
      const subject = oneSubjectGenerator()
      const impl = function () {}
      const result = subject.implementation(impl)
      const result2 = subject.implementation(impl)
      expectPost(subject, impl, result2)
      result2.must.not.equal(result)
    })

    it('returns a different Contract function with a different implementation', function () {
      const subject = oneSubjectGenerator()
      const impl = function () {}
      const impl2 = function () {}
      const result = subject.implementation(impl)
      const result2 = subject.implementation(impl2)
      expectPost(subject, impl2, result2)
      result2.must.not.equal(result)
      result2.implementation.must.not.equal(result.implementation)
    })
  })
}

const test = {
  expectInvariants: expectInvariants,
  generatePrototypeMethodsDescriptions: generatePrototypeMethodsDescriptions
}
Object.setPrototypeOf(test, common)

module.exports = test
<|endoftext|>


<commit_before>app.Map = function(params) {

    var locationParams = params.location;
	var map = new L.Map(params.elmId, {
			center: [ locationParams.center.lat, locationParams.center.lng ],
			zoom: locationParams.zoom
		})
		.addLayer(new L.TileLayer('http://{s}.tile.cloudmade.com/' + params.key + '/998/256/{z}/{x}/{y}.png'))
		.on("viewreset", onViewReset);

	var svg = d3.select(map.getPanes().overlayPane).append("svg"),
		g = svg.append("g").attr("class", "leaflet-zoom-hide");

	var selectedFeature,
		transform,
		path,
		bordersSelection, clustersSelection, venuesSelection,
		layerPoints;

	var tooltip = Tooltip({
		elmId: "tooltip",
		width: 240
	});

	var colors = params.colors;
    var minCircle = 3,
        maxCircle = 30;

	function initPath() {

		transform = d3.geo.transform({ point: function projectPoint(x, y) {
			var point = map.latLngToLayerPoint(new L.LatLng(y, x));
			this.stream.point(point.x, point.y);
		}});

		path = d3.geo.path().projection(transform);
	}

	function getBounds(feature) {

		var allBounds = feature.features.map(function(subfeature) {
			return path.bounds(subfeature);
		});

		var topLeftX = allBounds.map(function(bounds) { return bounds[0][0]; });
		var topLeftY = allBounds.map(function(bounds) { return bounds[0][1]; });
		var bottomRightX = allBounds.map(function(bounds) { return bounds[1][0]; });
		var bottomRightY = allBounds.map(function(bounds) { return bounds[1][1]; });

		var topLeftTotal = [Math.min.apply(null, topLeftX), Math.min.apply(null, topLeftY)];
		var bottomRightTotal = [Math.max.apply(null, bottomRightX), Math.max.apply(null, bottomRightY)];
		var boundsTotal = [topLeftTotal, bottomRightTotal];

		return boundsTotal;
	}

	function getAllCoords(feature) {
		var groupedCoords = feature.features.map(function(subfeature) {
			return subfeature.geometry.geometries[1].coordinates[0];
		});
		return _.flatten(groupedCoords, true);
	}

    function updateBorders(locationParams) {
        var bounds = locationParams.bounds;
        var geometry = {
            type: 'Polygon',
            coordinates: [[
                // [ 9.15423312, 45.44013697 ]
                [bounds.west, bounds.north],
                [bounds.est, bounds.north],
                [bounds.est, bounds.sud],
                [bounds.west, bounds.sud],
                [bounds.west, bounds.north]
            ]]
        };

        bordersSelection = g.selectAll("path.border")
            .data([geometry]);

        bordersSelection.enter().append("path")
            .classed('border', true)

        bordersSelection.exit().remove();
    }

	function updateClustersSelection(selectedFeature, params) {
		// clustersSelection = svg polygon elements
		// representing clusters (hulls)

        var infoTemplate = _.template(d3.select('#cluster-tooltip').html());

		clustersSelection = g.selectAll("path.cluster")
			.data(selectedFeature.features, function(feature) {
				return feature.properties.clusterId;
			});

		clustersSelection.enter().append("path")
			.attr('data-href', function(feature) {
					var props = feature.properties,
							hash = [
								'#!' + params.location,
								// 'category', props.name,
								'clusters', props.clusterId
							].join('/');
				return hash;
			})
            .classed('cluster', true)
			.style('fill', function(feature) {
				return colors[feature.properties.name];
			})
			.style('stroke', function(feature) {
				return colors[feature.properties.name];
			})
            .on("mouseover", function(d) {
                var data = {
                    name: d.properties.name,
                    idCluster: d.properties.idCluster,
                    venuesLen: d.properties.venues.length
                }
                tooltip.showTooltip(infoTemplate({ data: data }), d3.event);
            })
            .on("mouseout", tooltip.hideTooltip);

		clustersSelection.exit().remove();
	}

	function updateVenuesSelection(selectedFeature) {

        var infoTemplate = _.template(d3.select('#venue-tooltip').html());

		var venues = [];
		if (selectedFeature.features.length === 1) {
			var venues = getVenues(selectedFeature);
		}

		// function groupVenues(venues) {
		// 	 return _(venues).groupBy(function(v) {
		// 		 return v.category;
		// 	 });
		// }

  //       var catNames = _(groupVenues(venues)).keys();

		// var fillColor = d3.scale.ordinal()
		// 	 .domain(catNames)
		// 		.range(catNames.map(function(catName) { return colors[catName]; }));

		var maxBeenHere = _(venues).pluck('beenHere')[0];

		var radiusScale = d3.scale.pow()
			.exponent(0.5)
			.domain([0, maxBeenHere])
			.range([minCircle, maxCircle]);

		// venuesSelection svg circle elements
		// representing venues
		venuesSelection = g.selectAll('circle')
			.data(venues, function(venue) {
				return venue.id;
			});

		venuesSelection.enter().append('circle')
			.attr('r', function(d) {
				return radiusScale(d.beenHere) || 1;
			})
            // .style('fill', function(d) {
            //     return fillColor(d.category);
            // })
			.on("mouseover", function(d) {
				d.date = moment(d.timestamp).fromNow();
				tooltip.showTooltip(infoTemplate({ data: d }), d3.event);
			})
			.on("mouseout", tooltip.hideTooltip)
			.on('click', function(d) {
				window.open(
					'https://foursquare.com/v/' + d.id,
					'_blank'
				);
			});

		venuesSelection.exit().remove();
	}

	function update(feature, params) {

		selectedFeature = feature;

		updateClustersSelection(selectedFeature, params);
		updateVenuesSelection(selectedFeature);

        // if (selectedFeature.features.length === 1) {
		if (params.category || params.clusters) {
            bordersSelection && bordersSelection.remove();
        }
        else {
            updateBorders(this.locationParams);
        }

		onViewReset();

		// debugger;
		map.fitBounds(getAllCoords(selectedFeature).map(app.utils.inv));
	}

	function onViewReset() {

		initPath();

		var bounds = getBounds(selectedFeature),
			// var bounds = path.bounds(selectedFeature),
			topLeft = bounds[0],
			bottomRight = bounds[1],
            // padding = 2 * maxCircle;
            padding = Math.pow(maxCircle, map.getZoom() / 10);

		svg .attr("width", bottomRight[0] - topLeft[0] + (2 * padding))
				.attr("height", bottomRight[1] - topLeft[1] + (2 * padding))
				.style("left", (topLeft[0] - padding) + "px")
				.style("top", (topLeft[1] - padding) + "px");

		g	 .attr("transform", "translate(" + (-topLeft[0] + padding) + "," + (-topLeft[1] + padding) + ")");

		clustersSelection.attr("d", function(feature) {
				var geo = feature.geometry.geometries[1];
				var coords = geo.coordinates[0];
				coords.push(coords[0]);
				geo.coordinates = [coords];

				return path(geo);
		}.bind(this));

		venuesSelection.each(function(venue) {
			var point = map.latLngToLayerPoint(new L.LatLng(venue.venueLatitude, venue.venueLongitude));
			d3.select(this)
				.attr('cx', point.x)
				.attr('cy', point.y);
		});

        if (bordersSelection) {
            bordersSelection.attr("d", function(geometry) {
                  return path(geometry);
              }.bind(this));
        }

		// removePoints();
		// removeVenues();

		// show only if one cluster
		if (selectedFeature.features.length === 1) {

			// addPoints();
			// addVenues();
		}
	}

	function addPoints(limit, everyNth) {

		var limit = limit || 1000;
		var everyNth = everyNth || 2;

		var markers = _(selectedFeature.features.map(function(feature) {
			var coordinates = feature.geometry.geometries[0].coordinates;
			return coordinates.map(app.utils.inv)
				.filter(function(coords, i) { return i % everyNth === 0; })
				.slice(0, limit)
				.map(function(coords) {
					return L.marker(coords, { icon: L.divIcon({ className: 'grid-dot' }) });
				});
		})).flatten();

		layerPoints = L.layerGroup(markers).addTo(map);
	}

	function removePoints(argument) {
		if (layerPoints) { map.removeLayer(layerPoints); }
	}

	function getVenues(selectedFeature, limit) {

		limit = limit || 300;

		var coords, marker,
				markers = [];

		var feature = selectedFeature.features[0];
		var categoriesToShow = categoriesFromFeature(feature.properties.name);
		var venues = selectedFeature.features[0].properties.venues;

		var venuesInCategory = venues.filter(function(venue) {
			return (categoriesToShow.indexOf(venue.category) >= 0);
		});

		// if there are no venues that share the same categories as the cluster
		// show all the venues
		if (venuesInCategory.length > 0) {
			venues = venuesInCategory;
		}

		return venues.sort(sortVenue)
			.slice(0, limit);

		function sortVenue(v1, v2) {
			// beenHere is sometimes undefined!
			// this caused sort to fail, that led to huge circle bug
			return (v2.beenHere || 0) - (v1.beenHere || 0);
		}

		function categoriesFromFeature(categoryName) {

			var regex = /c\((.*?)\)/;
			var matched = regex.exec(categoryName);

			if (matched) {
				return matched[1].split(',');
			}
			return null;
		}
	}

	// function createMarkers(coords, icon) {
	//	 var options = {};
	//	 if (icon) { options.icon = icon; }
	//	 return coords.map(function(marker) {
	//		 return L.marker(marker, options);
	//			// .bindPopup(renderPopup()); // .addTo(map);
	//	 })
	//	 .filter(function(d, i) {
	//		 return i % 10 === 0;
	//	 });
	// }

	return {
        locationParams: locationParams,
		update: update,
		get: function() {
			return map;
		}
	}
};<commit_msg>[ui] Fixed the bug that caused the border rectangle to look like a line in some cases<commit_after>app.Map = function(params) {

    var locationParams = params.location;
	var map = new L.Map(params.elmId, {
			center: [ locationParams.center.lat, locationParams.center.lng ],
			zoom: locationParams.zoom
		})
		.addLayer(new L.TileLayer('http://{s}.tile.cloudmade.com/' + params.key + '/998/256/{z}/{x}/{y}.png'))
		.on("viewreset", onViewReset);

	var
		svg,
		g,

		selectedFeature,
		transform,
		path,
		clustersSelection,
		venuesSelection,
		layerPoints,

		colors = params.colors,
 		minCircle = 3,
    maxCircle = 30,

    tooltip;

	drawBorder(locationParams.bounds, map);
	svg = d3.select(map.getPanes().overlayPane).append("svg");
	g = svg.append("g").attr("class", "leaflet-zoom-hide");

	tooltip = Tooltip({
		elmId: "tooltip",
		width: 240
	});

	function drawBorder(bounds, map) {
		var pointSW = [bounds.sud, bounds.west];
		var pointNE = [bounds.north, bounds.est];
		var border = [pointSW, pointNE];
		var styles = { stroke: true, color: '#000', weight: 5, fillOpacity: 0 };
		L.rectangle(border, {className: 'border'}).addTo(map);
	}

	function initPath() {

		transform = d3.geo.transform({ point: function projectPoint(x, y) {
			var point = map.latLngToLayerPoint(new L.LatLng(y, x));
			this.stream.point(point.x, point.y);
		}});

		path = d3.geo.path().projection(transform);
	}

	function getBounds(feature) {

		var allBounds = feature.features.map(function(subfeature) {
			return path.bounds(subfeature);
		});

		var topLeftX = allBounds.map(function(bounds) { return bounds[0][0]; });
		var topLeftY = allBounds.map(function(bounds) { return bounds[0][1]; });
		var bottomRightX = allBounds.map(function(bounds) { return bounds[1][0]; });
		var bottomRightY = allBounds.map(function(bounds) { return bounds[1][1]; });

		var topLeftTotal = [Math.min.apply(null, topLeftX), Math.min.apply(null, topLeftY)];
		var bottomRightTotal = [Math.max.apply(null, bottomRightX), Math.max.apply(null, bottomRightY)];
		var boundsTotal = [topLeftTotal, bottomRightTotal];

		return boundsTotal;
	}

	function getAllCoords(feature) {
		var groupedCoords = feature.features.map(function(subfeature) {
			return subfeature.geometry.geometries[1].coordinates[0];
		});
		return _.flatten(groupedCoords, true);
	}

	function updateClustersSelection(selectedFeature, params) {
		// clustersSelection = svg polygon elements
		// representing clusters (hulls)

        var infoTemplate = _.template(d3.select('#cluster-tooltip').html());

		clustersSelection = g.selectAll("path.cluster")
			.data(selectedFeature.features, function(feature) {
				return feature.properties.clusterId;
			});

		clustersSelection.enter().append("path")
			.attr('data-href', function(feature) {
					var props = feature.properties,
							hash = [
								'#!' + params.location,
								// 'category', props.name,
								'clusters', props.clusterId
							].join('/');
				return hash;
			})
            .classed('cluster', true)
			.style('fill', function(feature) {
				return colors[feature.properties.name];
			})
			.style('stroke', function(feature) {
				return colors[feature.properties.name];
			})
            .on("mouseover", function(d) {
                var data = {
                    name: d.properties.name,
                    idCluster: d.properties.idCluster,
                    venuesLen: d.properties.venues.length
                }
                tooltip.showTooltip(infoTemplate({ data: data }), d3.event);
            })
            .on("mouseout", tooltip.hideTooltip);

		clustersSelection.exit().remove();
	}

	function updateVenuesSelection(selectedFeature) {

        var infoTemplate = _.template(d3.select('#venue-tooltip').html());

		var venues = [];
		if (selectedFeature.features.length === 1) {
			var venues = getVenues(selectedFeature);
		}

		// function groupVenues(venues) {
		// 	 return _(venues).groupBy(function(v) {
		// 		 return v.category;
		// 	 });
		// }

  //       var catNames = _(groupVenues(venues)).keys();

		// var fillColor = d3.scale.ordinal()
		// 	 .domain(catNames)
		// 		.range(catNames.map(function(catName) { return colors[catName]; }));

		var maxBeenHere = _(venues).pluck('beenHere')[0];

		var radiusScale = d3.scale.pow()
			.exponent(0.5)
			.domain([0, maxBeenHere])
			.range([minCircle, maxCircle]);

		// venuesSelection svg circle elements
		// representing venues
		venuesSelection = g.selectAll('circle')
			.data(venues, function(venue) {
				return venue.id;
			});

		venuesSelection.enter().append('circle')
			.attr('r', function(d) {
				return radiusScale(d.beenHere) || 1;
			})
            // .style('fill', function(d) {
            //     return fillColor(d.category);
            // })
			.on("mouseover", function(d) {
				d.date = moment(d.timestamp).fromNow();
				tooltip.showTooltip(infoTemplate({ data: d }), d3.event);
			})
			.on("mouseout", tooltip.hideTooltip)
			.on('click', function(d) {
				window.open(
					'https://foursquare.com/v/' + d.id,
					'_blank'
				);
			});

		venuesSelection.exit().remove();
	}

	function update(feature, params) {

		selectedFeature = feature;

		updateClustersSelection(selectedFeature, params);
		updateVenuesSelection(selectedFeature);

		onViewReset();

		// debugger;
		map.fitBounds(getAllCoords(selectedFeature).map(app.utils.inv));
	}

	function onViewReset() {

		initPath();

		var bounds = getBounds(selectedFeature),
			// var bounds = path.bounds(selectedFeature),
			topLeft = bounds[0],
			bottomRight = bounds[1],
            // padding = 2 * maxCircle;
            padding = Math.pow(maxCircle, map.getZoom() / 10);

		svg .attr("width", bottomRight[0] - topLeft[0] + (2 * padding))
				.attr("height", bottomRight[1] - topLeft[1] + (2 * padding))
				.style("left", (topLeft[0] - padding) + "px")
				.style("top", (topLeft[1] - padding) + "px");

		g	 .attr("transform", "translate(" + (-topLeft[0] + padding) + "," + (-topLeft[1] + padding) + ")");

		clustersSelection.attr("d", function(feature) {
				var geo = feature.geometry.geometries[1];
				var coords = geo.coordinates[0];
				coords.push(coords[0]);
				geo.coordinates = [coords];

				return path(geo);
		}.bind(this));

		venuesSelection.each(function(venue) {
			var point = map.latLngToLayerPoint(new L.LatLng(venue.venueLatitude, venue.venueLongitude));
			d3.select(this)
				.attr('cx', point.x)
				.attr('cy', point.y);
		});

		// removePoints();
		// removeVenues();

		// show only if one cluster
		if (selectedFeature.features.length === 1) {

			// addPoints();
			// addVenues();
		}
	}

	function addPoints(limit, everyNth) {

		var limit = limit || 1000;
		var everyNth = everyNth || 2;

		var markers = _(selectedFeature.features.map(function(feature) {
			var coordinates = feature.geometry.geometries[0].coordinates;
			return coordinates.map(app.utils.inv)
				.filter(function(coords, i) { return i % everyNth === 0; })
				.slice(0, limit)
				.map(function(coords) {
					return L.marker(coords, { icon: L.divIcon({ className: 'grid-dot' }) });
				});
		})).flatten();

		layerPoints = L.layerGroup(markers).addTo(map);
	}

	function removePoints(argument) {
		if (layerPoints) { map.removeLayer(layerPoints); }
	}

	function getVenues(selectedFeature, limit) {

		limit = limit || 300;

		var coords, marker,
				markers = [];

		var feature = selectedFeature.features[0];
		var categoriesToShow = categoriesFromFeature(feature.properties.name);
		var venues = selectedFeature.features[0].properties.venues;

		var venuesInCategory = venues.filter(function(venue) {
			return (categoriesToShow.indexOf(venue.category) >= 0);
		});

		// if there are no venues that share the same categories as the cluster
		// show all the venues
		if (venuesInCategory.length > 0) {
			venues = venuesInCategory;
		}

		return venues.sort(sortVenue)
			.slice(0, limit);

		function sortVenue(v1, v2) {
			// beenHere is sometimes undefined!
			// this caused sort to fail, that led to huge circle bug
			return (v2.beenHere || 0) - (v1.beenHere || 0);
		}

		function categoriesFromFeature(categoryName) {

			var regex = /c\((.*?)\)/;
			var matched = regex.exec(categoryName);

			if (matched) {
				return matched[1].split(',');
			}
			return null;
		}
	}

	// function createMarkers(coords, icon) {
	//	 var options = {};
	//	 if (icon) { options.icon = icon; }
	//	 return coords.map(function(marker) {
	//		 return L.marker(marker, options);
	//			// .bindPopup(renderPopup()); // .addTo(map);
	//	 })
	//	 .filter(function(d, i) {
	//		 return i % 10 === 0;
	//	 });
	// }

	return {
        locationParams: locationParams,
		update: update,
		get: function() {
			return map;
		}
	}
};<|endoftext|>


<commit_before>/**
 * @file TimePicker component
 * @author sunday(sunday.wei@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import classNames from 'classnames';

import TextField from '../TextField';
import TimeList from '../_TimeList';
import Popup from '../Popup';

import Position from '../_statics/Position';

import Util from '../_vendors/Util';

class TimePicker extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.validValue = true;

        this.state = {
            textFieldValue: props.value,
            popupVisible: false,
            hour: moment().format('HH'),
            minute: moment().format('mm'),
            second: moment().format('ss'),
            triggerEl: null
        };

        this.textFieldChangeHandle = ::this.textFieldChangeHandle;
        this.togglePopup = ::this.togglePopup;
        this.closePopup = ::this.closePopup;
        this.timePickerChangeHandle = ::this.timePickerChangeHandle;
    }

    rangeData(range) {
        let arr = [];
        for (let i = 0; i < range; i++) {
            if (i < 10) {
                i = '0' + i;
            }
            arr.push({text: i, value: true});
        }
        return arr;
    }

    textFieldChangeHandle(text) {
        if (text && text.length) {
            let validDate = '1970-01-01 ' + text;
            let validFormat = 'YYYY-MM-DD ' + this.props.dateFormat;
            const flag = moment(validDate, validFormat, true).isValid();
            if (flag) {
                const hour = moment(validDate).format('HH'),
                    minute = moment(validDate).format('mm'),
                    second = moment(validDate).format('ss');
                this.setState({
                    textFieldValue: text,
                    hour: hour,
                    minute: minute,
                    second: second
                });
            }
        } else {
            this.setState({
                textFieldValue: text
            });
        }
    }

    timePickerChangeHandle(obj) {
        let timer = obj.hour + ':' + obj.minute + ':' + obj.second;
        let validDate = '1970-01-01 ' + timer;
        timer = moment(validDate).format(this.props.dateFormat);
        this.setState({
            hour: obj.hour,
            minute: obj.minute,
            second: obj.second,
            textFieldValue: timer
        });
    }

    togglePopup(e) {
        if (this.validValue) {
            this.setState({
                popupVisible: !this.state.popupVisible,
                triggerEl: e.target
            });
        }
    }

    closePopup() {
        const {textFieldValue} = this.state;
        !this.props.disabled && this.setState({
            popupVisible: false
        }, () => {
            this.props.onChange && this.props.onChange(textFieldValue);
        });
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.props.value || nextProps.dateFormat !== this.props.dateFormat) {
            const value = Util.value2Moment(nextProps.value, nextProps.dateFormat);
            this.setState({
                value,
                textFieldValue: value.format(nextProps.dateFormat)
            });
        }
    }

    componentDidMount() {
        const {value} = this.props;
        let dateFormatValue = '2000-02-01 ' + value;
        if (value) {
            if (moment(dateFormatValue, 'YYYY-MM-DD HH:mm:ss').isValid()) {
                this.setState({
                    textFieldValue: value,
                    hour: moment(dateFormatValue).format('HH'),
                    minute: moment(dateFormatValue).format('mm'),
                    second: moment(dateFormatValue).format('ss')
                });
            } else {
                this.validValue = false;
                console.error('Invalid date');
            }
        }
    }

    render() {

        const {className, style, name, placeholder, maxValue, minValue, dateFormat, position} = this.props,
            {popupVisible, textFieldValue, hour, minute, second, triggerEl} = this.state,

            pickerClassName = classNames('time-picker', {
                [className]: className
            }),

            popupTextField = moment(moment().format('YYYY-MM-DD') + ' ' + hour + ':' + minute + ':' + second)
            .format(dateFormat);

        return (

                    <TextField ref="trigger"
                               className="time-picker-field"
                               name={name}
                               placeholder={placeholder}
                               value={textFieldValue}
                               clearButtonVisible={false}
                               isFocusedSelectAll={false}
                               readOnly={true}
                               onClick={e => {
                                   this.togglePopup(e);
                               }}/>

                    <Popup className="time-picker-popup"
                           visible={popupVisible}
                           triggerEl={triggerEl}
                           position={position}
                           hasTriangle={false}
                           onRequestClose={() => {
                               this.closePopup();
                           }}>
                        <TextField className="popup-text-field"
                                   placeholder={placeholder}
                                   value={textFieldValue ? popupTextField : textFieldValue}
                                   clearButtonVisible={false}
                                   onChange={this.textFieldChangeHandle}/>
                        <TimeList hour={hour}
                                  minute={minute}
                                  second={second}
                                  maxValue={maxValue}
                                  minValue={minValue}
                                  isRequired={true}
                                  dateFormat={dateFormat}
                                  popupVisible={popupVisible}
                                  onChange={this.timePickerChangeHandle}/>
                    </Popup>

        );
    }
}

TimePicker.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Time picker input name.
     */
    name: PropTypes.string,

    /**
     * This is the initial date value of the component.
     */
    value: PropTypes.string,

    /**
     * The ending of a range of valid dates. The range includes the endDate.
     */
    maxValue: PropTypes.string,

    /**
     * The beginning of a range of valid dates. The range includes the startDate.
     */
    minValue: PropTypes.string,

    /**
     * TimePicker textField element placeholder.
     */
    placeholder: PropTypes.string,

    /**
     * Time format.
     */
    dateFormat: PropTypes.string

};

TimePicker.defaultProps = {
    name: '',
    value: moment().format('HH:mm:ss'),
    placeholder: 'Time',
    dateFormat: 'HH:mm:ss',
    position: Position.BOTTOM_LEFT
};

export default TimePicker;<commit_msg>update TimePicker<commit_after>/**
 * @file TimePicker component
 * @author sunday(sunday.wei@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import classNames from 'classnames';

import TextField from '../TextField';
import TimeList from '../_TimeList';
import Popup from '../Popup';

import Position from '../_statics/Position';

import Util from '../_vendors/Util';

class TimePicker extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.validValue = true;

        this.state = {
            textFieldValue: props.value,
            popupVisible: false,
            hour: moment().format('HH'),
            minute: moment().format('mm'),
            second: moment().format('ss'),
            triggerEl: null
        };

    }

    rangeData = range => {
        let arr = [];
        for (let i = 0; i < range; i++) {
            if (i < 10) {
                i = '0' + i;
            }
            arr.push({text: i, value: true});
        }
        return arr;
    };

    textFieldChangeHandle = text => {
        if (text && text.length) {
            let validDate = '1970-01-01 ' + text;
            let validFormat = 'YYYY-MM-DD ' + this.props.dateFormat;
            const flag = moment(validDate, validFormat, true).isValid();
            if (flag) {
                const hour = moment(validDate).format('HH'),
                    minute = moment(validDate).format('mm'),
                    second = moment(validDate).format('ss');
                this.setState({
                    textFieldValue: text,
                    hour: hour,
                    minute: minute,
                    second: second
                });
            }
        } else {
            this.setState({
                textFieldValue: text
            });
        }
    };

    timePickerChangeHandle = obj => {
        let timer = obj.hour + ':' + obj.minute + ':' + obj.second;
        let validDate = '1970-01-01 ' + timer;
        timer = moment(validDate).format(this.props.dateFormat);
        this.setState({
            hour: obj.hour,
            minute: obj.minute,
            second: obj.second,
            textFieldValue: timer
        });
    };

    togglePopup = e => {
        if (this.validValue) {
            this.setState({
                popupVisible: !this.state.popupVisible,
                triggerEl: e.target
            });
        }
    };

    closePopup = () => {
        const {textFieldValue} = this.state;
        !this.props.disabled && this.setState({
            popupVisible: false
        }, () => {
            this.props.onChange && this.props.onChange(textFieldValue);
        });
    };

    componentDidMount() {
        const {value} = this.props;
        let dateFormatValue = '2000-02-01 ' + value;
        if (value) {
            if (moment(dateFormatValue, 'YYYY-MM-DD HH:mm:ss').isValid()) {
                this.setState({
                    textFieldValue: value,
                    hour: moment(dateFormatValue).format('HH'),
                    minute: moment(dateFormatValue).format('mm'),
                    second: moment(dateFormatValue).format('ss')
                });
            } else {
                this.validValue = false;
                console.error('Invalid date');
            }
        }
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.props.value || nextProps.dateFormat !== this.props.dateFormat) {
            const value = Util.value2Moment(nextProps.value, nextProps.dateFormat);
            this.setState({
                value,
                textFieldValue: value.format(nextProps.dateFormat)
            });
        }
    }

    render() {

        const {className, style, name, placeholder, maxValue, minValue, dateFormat, position} = this.props,
            {popupVisible, textFieldValue, hour, minute, second, triggerEl} = this.state,

            pickerClassName = classNames('time-picker', {
                [className]: className
            }),

            popupTextField = moment(moment().format('YYYY-MM-DD') + ' ' + hour + ':' + minute + ':' + second)
            .format(dateFormat);

        return (

                    <TextField ref="trigger"
                               className="time-picker-field"
                               name={name}
                               placeholder={placeholder}
                               value={textFieldValue}
                               clearButtonVisible={false}
                               isFocusedSelectAll={false}
                               readOnly={true}
                               onClick={e => {
                                   this.togglePopup(e);
                               }}/>

                    <Popup className="time-picker-popup"
                           visible={popupVisible}
                           triggerEl={triggerEl}
                           position={position}
                           hasTriangle={false}
                           onRequestClose={() => {
                               this.closePopup();
                           }}>
                        <TextField className="popup-text-field"
                                   placeholder={placeholder}
                                   value={textFieldValue ? popupTextField : textFieldValue}
                                   clearButtonVisible={false}
                                   onChange={this.textFieldChangeHandle}/>
                        <TimeList hour={hour}
                                  minute={minute}
                                  second={second}
                                  maxValue={maxValue}
                                  minValue={minValue}
                                  isRequired={true}
                                  dateFormat={dateFormat}
                                  popupVisible={popupVisible}
                                  onChange={this.timePickerChangeHandle}/>
                    </Popup>

        );
    }
}

TimePicker.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Time picker input name.
     */
    name: PropTypes.string,

    /**
     * This is the initial date value of the component.
     */
    value: PropTypes.string,

    /**
     * The ending of a range of valid dates. The range includes the endDate.
     */
    maxValue: PropTypes.string,

    /**
     * The beginning of a range of valid dates. The range includes the startDate.
     */
    minValue: PropTypes.string,

    /**
     * TimePicker textField element placeholder.
     */
    placeholder: PropTypes.string,

    /**
     * Time format.
     */
    dateFormat: PropTypes.string

};

TimePicker.defaultProps = {
    name: '',
    value: moment().format('HH:mm:ss'),
    placeholder: 'Time',
    dateFormat: 'HH:mm:ss',
    position: Position.BOTTOM_LEFT
};

export default TimePicker;<|endoftext|>