<commit_before>'use strict';

/**
 * ngTable: Table + Angular JS
 *
 * @author Vitalii Savchuk <esvit666@gmail.com>
 * @copyright 2013 Vitalii Savchuk <esvit666@gmail.com>
 * @version 0.2.0
 * @url https://github.com/esvit/ng-table/
 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
 */
angular.module('ngTable', [])
    // name of table header template
    .constant('ngTableHeaderTemplate', "ng-table/header")

    // name of pager template
    .constant('ngTablePaginationTemplate', "ng-table/pager")

    // save predefined templates to cache
    .run(      ['$templateCache', 'ngTableHeaderTemplate', 'ngTablePaginationTemplate',
        function($templateCache,   ngTableHeaderTemplate,   ngTablePaginationTemplate) {
        $templateCache.put(ngTableHeaderTemplate,
            '
 \

{[column.title]}
	 \

 \

 \
                 \

\
                        <input type="text" ng-model="params.filter[name]" class="input-filter" ng-show="filter == \'text\'" /> \
                        <select class="filter filter-select" ng-options="data.id as data.title for data in column.data" ng-model="params.filter[name]" ng-show="filter == \'select\'"></select> \
                        <input type="text" date-range ng-model="params.filter[name]" ng-show="filter == \'date\'" /> \
                        <button class="btn btn-primary btn-block" ng-click="doFilter()" ng-show="filter == \'button\'">Filter</button> \

\
                	 \

');

        $templateCache.put(ngTablePaginationTemplate,
            '
\

 \

 \
                    « \
                    {[page.number]} \
                    {[page.number]} \
                    … \
                    {[page.number]} \
                    » \

 \

 \

 \
                    <button type="button" ng-class="{\'active\':params.count == 10}" ng-click="changeCount(10)" class="btn btn-mini">10</button> \
                    <button type="button" ng-class="{\'active\':params.count == 25}" ng-click="changeCount(25)" class="btn btn-mini">25</button> \
                    <button type="button" ng-class="{\'active\':params.count == 50}" ng-click="changeCount(50)" class="btn btn-mini">50</button> \
                    <button type="button" ng-class="{\'active\':params.count == 100}" ng-click="changeCount(100)" class="btn btn-mini">100</button> \

\

');
    }])
    .directive('ngTable', ['$compile', '$parse', '$http', 'ngTableHeaderTemplate', 'ngTablePaginationTemplate', 'ngTableParams',
                   function($compile,   $parse,   $http,   ngTableHeaderTemplate,   ngTablePaginationTemplate,   ngTableParams) {
        return {
            restrict: 'A',
            priority: 1001,
            scope: true,
            controller: function($scope, $timeout) {
                $scope.params = $scope.params || { page: 1, count: 10 };
                $scope.params.filter = $scope.params.filter || {};

                var updateParams = function(newParams) {
                    newParams = angular.extend($scope.params, newParams);

                    // assign params in both scopes
                    $scope.paramsModel.assign($scope.$parent, new ngTableParams(newParams));
                    $scope.paramsModel.assign($scope, angular.copy(newParams));
                };

                // goto page
                $scope.goToPage = function(page) {
                    if (page > 0 && $scope.params.page != page && $scope.pages.length + 1 >= page) {
                        updateParams({ 'page': page });
                    }
                }
                // change items per page
                $scope.changeCount = function(count) {
                    updateParams({ 'page': 1, 'count': count });
                }
                $scope.doFilter = function() {
                    updateParams({ 'page': 1 });
                }
                $scope.sortBy = function(column) {
                    if (!column.sortable) {
                        return;
                    }
                    var sorting = $scope.params.sorting && $scope.params.sorting[column.sortable] && ($scope.params.sorting[column.sortable] == 'desc');
                    var sortingParams = {};
                    sortingParams[column.sortable] = sorting ? 'asc' : 'desc';

                    updateParams({ 'sorting': sortingParams });
                }
            },
            compile: function(element, attrs) {
                var i = 0, columns = [];
                // get columns from table
                angular.forEach(element.find('td'), function(item) {
                    var el = $(item);
                    columns.push({
                        id: i++,
                        title: el.attr('title') || el.text(),
                        sortable: el.attr('sortable') ? el.attr('sortable') : false,
                        filter: el.attr('filter') ? $parse(el.attr('filter'))() : false,
                        filterData: el.attr('filter-data') ? el.attr('filter-data') : null
                    });
                });
                return function(scope, element, attrs) {
                    scope.columns = columns;

                    // generate array of pages
                    var generatePages = function(currentPage, totalItems, pageSize) {
                        var maxBlocks = 11;  // specify the max
 elements you want rendered
                        var pages = [],
                            numPages = Math.ceil(totalItems / pageSize);

                        if (numPages > 1) {
                            pages.push({ type: 'prev', number: Math.max(1, currentPage - 1), active: currentPage > 1 });
                            pages.push({ type: 'first', number: 1, active: currentPage > 1 });

                            var maxPivotPages = Math.round((maxBlocks - 5) / 2),
                                minPage = Math.max(2, currentPage - maxPivotPages),
                                maxPage = Math.min(numPages - 1, currentPage + maxPivotPages * 2 - (currentPage - minPage));

                            minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));

                            for (var i = minPage; i <= maxPage; i++) {
                                if ((i == minPage && i != 2) || (i == maxPage && i != numPages - 1)) {
                                    pages.push({ type: 'more' });
                                } else {
                                    pages.push({ type: 'page', number: i, active: currentPage != i });
                                }
                            }
                            pages.push({ type: 'last', number: numPages, active: currentPage != numPages });
                            pages.push({ type: 'next', number: Math.min(numPages, currentPage + 1), active: currentPage < numPages });
                        }
                        return pages;
                    };

                    // update pagination where parameters changes
                    scope.$parent.$watch(attrs.ngTable, function(params) {
                        if (angular.isUndefined(params)) {
                            return;
                        }
                        scope.paramsModel = $parse(attrs.ngTable);
                        scope.pages = generatePages(params.page, params.total, params.count);
                        scope.params = angular.copy(params);
                    });

                    // show/hide filter row
                    if (attrs.showFilter) {
                        scope.$parent.$watch(attrs.showFilter, function(value) {
                            scope.show_filter = value;
                        });
                    }

                    // get data from columns
                    angular.forEach(columns, function(column) {
                        if (!column.filterData) {
                            return;
                        }
                        var promise = scope[column.filterData];
                        if (!promise) {
                            throw new Error('Function ' + column.filterData + ' not found in scope');
                        }
                        delete column['filterData'];
                        promise(column).then(function(data) {
                            if (!angular.isArray(data)) {
                                data = [];
                            }
                            data.unshift({ title: '-' });
                            column.data = data;
                        });
                    });

                    // create table
                    if (!element.hasClass('ng-table')) {
                        scope.templates = {
                            'header': attrs.templateHeader ? attrs.templateHeader : ngTableHeaderTemplate,
                            'pagination': attrs.templatePagination ? attrs.templatePagination : ngTablePaginationTemplate
                        };

                        var headerTemplate = $compile('

')(scope),
                            paginationTemplate = $compile('

')(scope);

                        element.filter('thead').remove();
                        element.prepend(headerTemplate).addClass('ng-table');
                        element.after(paginationTemplate);
                    }
                };
            }
        };
    }])
    .factory('ngTableParams', function() {
        function isNumber(n) {
            return !isNaN(parseFloat(n)) && isFinite(n);
        }
        var ngTableParams = function (data) {
            var ignoreFields = ['total'];

            // parse url params
            for (var key in data) {
                if (key.indexOf('[') >= 0) {
                    var params = key.split(/\[(.*)\]/), value = data[key], lastKey = '';

                    angular.forEach(params.reverse(), function(name) {
                        if (name != '') {
                            var v = value;
                            value = {};
                            value[lastKey = name] = isNumber(v) ? parseFloat(v) : v;
                        }
                    });
                    this[lastKey] = angular.extend(this[lastKey] || {}, value[lastKey]);
                } else {
                    this[key] = isNumber(data[key]) ? parseFloat(data[key]) : data[key];
                }
            }
            this.url = function(asString) {
                asString = asString || false;
                var pairs = asString ? [] : {};
                for (var key in this) {
                    if (this.hasOwnProperty(key)) {
                        if (ignoreFields.indexOf(key) >= 0) {
                            continue;
                        }
                        var item = this[key],
                            name = encodeURIComponent(key);
                        if (typeof item == 'object') {
                            for (var subkey in item) {
                                if (!angular.isUndefined(item[subkey]) && item[subkey] != '') {
                                    var pname = name + '[' + encodeURIComponent(subkey) + ']';
                                    if (asString) {
                                        pairs.push(pname + '=' + encodeURIComponent(item[subkey]));
                                    } else {
                                        pairs[pname] = encodeURIComponent(item[subkey]);
                                    }
                                }
                            }
                        } else if (!angular.isFunction(item) && !angular.isUndefined(item) && item != '') {
                            if (asString) {
                                pairs.push(name + '=' + encodeURIComponent(item));
                            } else {
                                pairs[name] = encodeURIComponent(item);
                            }
                        }
                    }
                }
                return pairs;
            };
        };
        return ngTableParams;
    });<commit_msg>add orderBy function<commit_after>'use strict';

/**
 * ngTable: Table + Angular JS
 *
 * @author Vitalii Savchuk <esvit666@gmail.com>
 * @copyright 2013 Vitalii Savchuk <esvit666@gmail.com>
 * @version 0.2.0
 * @url https://github.com/esvit/ng-table/
 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
 */
angular.module('ngTable', [])
    // name of table header template
    .constant('ngTableHeaderTemplate', "ng-table/header")

    // name of pager template
    .constant('ngTablePaginationTemplate', "ng-table/pager")

    // save predefined templates to cache
    .run(      ['$templateCache', 'ngTableHeaderTemplate', 'ngTablePaginationTemplate',
        function($templateCache,   ngTableHeaderTemplate,   ngTablePaginationTemplate) {
        $templateCache.put(ngTableHeaderTemplate,
            '
 \

{[column.title]}
	 \

 \

 \
                 \

\
                        <input type="text" ng-model="params.filter[name]" class="input-filter" ng-show="filter == \'text\'" /> \
                        <select class="filter filter-select" ng-options="data.id as data.title for data in column.data" ng-model="params.filter[name]" ng-show="filter == \'select\'"></select> \
                        <input type="text" date-range ng-model="params.filter[name]" ng-show="filter == \'date\'" /> \
                        <button class="btn btn-primary btn-block" ng-click="doFilter()" ng-show="filter == \'button\'">Filter</button> \

\
                	 \

');

        $templateCache.put(ngTablePaginationTemplate,
            '
\

 \

 \
                    « \
                    {[page.number]} \
                    {[page.number]} \
                    … \
                    {[page.number]} \
                    » \

 \

 \

 \
                    <button type="button" ng-class="{\'active\':params.count == 10}" ng-click="changeCount(10)" class="btn btn-mini">10</button> \
                    <button type="button" ng-class="{\'active\':params.count == 25}" ng-click="changeCount(25)" class="btn btn-mini">25</button> \
                    <button type="button" ng-class="{\'active\':params.count == 50}" ng-click="changeCount(50)" class="btn btn-mini">50</button> \
                    <button type="button" ng-class="{\'active\':params.count == 100}" ng-click="changeCount(100)" class="btn btn-mini">100</button> \

\

');
    }])
    .directive('ngTable', ['$compile', '$parse', '$http', 'ngTableHeaderTemplate', 'ngTablePaginationTemplate', 'ngTableParams',
                   function($compile,   $parse,   $http,   ngTableHeaderTemplate,   ngTablePaginationTemplate,   ngTableParams) {
        return {
            restrict: 'A',
            priority: 1001,
            scope: true,
            controller: function($scope, $timeout) {
                $scope.params = $scope.params || { page: 1, count: 10 };
                $scope.params.filter = $scope.params.filter || {};

                var updateParams = function(newParams) {
                    newParams = angular.extend($scope.params, newParams);

                    // assign params in both scopes
                    $scope.paramsModel.assign($scope.$parent, new ngTableParams(newParams));
                    $scope.paramsModel.assign($scope, angular.copy(newParams));
                };

                // goto page
                $scope.goToPage = function(page) {
                    if (page > 0 && $scope.params.page != page && $scope.pages.length + 1 >= page) {
                        updateParams({ 'page': page });
                    }
                }
                // change items per page
                $scope.changeCount = function(count) {
                    updateParams({ 'page': 1, 'count': count });
                }
                $scope.doFilter = function() {
                    updateParams({ 'page': 1 });
                }
                $scope.sortBy = function(column) {
                    if (!column.sortable) {
                        return;
                    }
                    var sorting = $scope.params.sorting && $scope.params.sorting[column.sortable] && ($scope.params.sorting[column.sortable] == 'desc');
                    var sortingParams = {};
                    sortingParams[column.sortable] = sorting ? 'asc' : 'desc';

                    updateParams({ 'sorting': sortingParams });
                }
            },
            compile: function(element, attrs) {
                var i = 0, columns = [];
                // get columns from table
                angular.forEach(element.find('td'), function(item) {
                    var el = $(item);
                    columns.push({
                        id: i++,
                        title: el.attr('title') || el.text(),
                        sortable: el.attr('sortable') ? el.attr('sortable') : false,
                        filter: el.attr('filter') ? $parse(el.attr('filter'))() : false,
                        filterData: el.attr('filter-data') ? el.attr('filter-data') : null
                    });
                });
                return function(scope, element, attrs) {
                    scope.columns = columns;

                    // generate array of pages
                    var generatePages = function(currentPage, totalItems, pageSize) {
                        var maxBlocks = 11;  // specify the max
 elements you want rendered
                        var pages = [],
                            numPages = Math.ceil(totalItems / pageSize);

                        if (numPages > 1) {
                            pages.push({ type: 'prev', number: Math.max(1, currentPage - 1), active: currentPage > 1 });
                            pages.push({ type: 'first', number: 1, active: currentPage > 1 });

                            var maxPivotPages = Math.round((maxBlocks - 5) / 2),
                                minPage = Math.max(2, currentPage - maxPivotPages),
                                maxPage = Math.min(numPages - 1, currentPage + maxPivotPages * 2 - (currentPage - minPage));

                            minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));

                            for (var i = minPage; i <= maxPage; i++) {
                                if ((i == minPage && i != 2) || (i == maxPage && i != numPages - 1)) {
                                    pages.push({ type: 'more' });
                                } else {
                                    pages.push({ type: 'page', number: i, active: currentPage != i });
                                }
                            }
                            pages.push({ type: 'last', number: numPages, active: currentPage != numPages });
                            pages.push({ type: 'next', number: Math.min(numPages, currentPage + 1), active: currentPage < numPages });
                        }
                        return pages;
                    };

                    // update pagination where parameters changes
                    scope.$parent.$watch(attrs.ngTable, function(params) {
                        if (angular.isUndefined(params)) {
                            return;
                        }
                        scope.paramsModel = $parse(attrs.ngTable);
                        scope.pages = generatePages(params.page, params.total, params.count);
                        scope.params = angular.copy(params);
                    }, true);

                    // show/hide filter row
                    if (attrs.showFilter) {
                        scope.$parent.$watch(attrs.showFilter, function(value) {
                            scope.show_filter = value;
                        });
                    }

                    // get data from columns
                    angular.forEach(columns, function(column) {
                        if (!column.filterData) {
                            return;
                        }
                        var promise = scope[column.filterData];
                        if (!promise) {
                            throw new Error('Function ' + column.filterData + ' not found in scope');
                        }
                        delete column['filterData'];
                        promise(column).then(function(data) {
                            if (!angular.isArray(data)) {
                                data = [];
                            }
                            data.unshift({ title: '-' });
                            column.data = data;
                        });
                    });

                    // create table
                    if (!element.hasClass('ng-table')) {
                        scope.templates = {
                            'header': ngTableHeaderTemplate,
                            'pagination': attrs.templatePagination ? attrs.templatePagination : ngTablePaginationTemplate
                        };

                        var headerTemplate = $compile('

')(scope),
                            paginationTemplate = $compile('

')(scope);

                        element.filter('thead').remove();
                        element.prepend(headerTemplate).addClass('ng-table');
                        element.after(paginationTemplate);
                    }
                };
            }
        };
    }])
    .factory('ngTableParams', function() {
        function isNumber(n) {
            return !isNaN(parseFloat(n)) && isFinite(n);
        }
        var ngTableParams = function (data) {
            var ignoreFields = ['total'];

            // parse url params
            for (var key in data) {
                if (key.indexOf('[') >= 0) {
                    var params = key.split(/\[(.*)\]/), value = data[key], lastKey = '';

                    angular.forEach(params.reverse(), function(name) {
                        if (name != '') {
                            var v = value;
                            value = {};
                            value[lastKey = name] = isNumber(v) ? parseFloat(v) : v;
                        }
                    });
                    this[lastKey] = angular.extend(this[lastKey] || {}, value[lastKey]);
                } else {
                    this[key] = isNumber(data[key]) ? parseFloat(data[key]) : data[key];
                }
            }
            this.orderBy = function() {
                var sorting = [];
                angular.forEach(this.sorting, function(direction, column) {
                    sorting.push( (direction == 'asc' ? '+' : '-') + column );
                });
                return sorting;
            };
            this.url = function(asString) {
                asString = asString || false;
                var pairs = asString ? [] : {};
                for (var key in this) {
                    if (this.hasOwnProperty(key)) {
                        if (ignoreFields.indexOf(key) >= 0) {
                            continue;
                        }
                        var item = this[key],
                            name = encodeURIComponent(key);
                        if (typeof item == 'object') {
                            for (var subkey in item) {
                                if (!angular.isUndefined(item[subkey]) && item[subkey] != '') {
                                    var pname = name + '[' + encodeURIComponent(subkey) + ']';
                                    if (asString) {
                                        pairs.push(pname + '=' + encodeURIComponent(item[subkey]));
                                    } else {
                                        pairs[pname] = encodeURIComponent(item[subkey]);
                                    }
                                }
                            }
                        } else if (!angular.isFunction(item) && !angular.isUndefined(item) && item != '') {
                            if (asString) {
                                pairs.push(name + '=' + encodeURIComponent(item));
                            } else {
                                pairs[name] = encodeURIComponent(item);
                            }
                        }
                    }
                }
                return pairs;
            };
        };
        return ngTableParams;
    });<|endoftext|>


<commit_before>exports.merge = function(a, b){
  if (a && b) {
    for (var key in b) {
      a[key] = b[key];
    }
  }
  return a;
};
<commit_msg>Document utils.merge().<commit_after>/**
 * Merge object b with object a.
 *
 *     var a = { foo: 'bar' }
 *       , b = { bar: 'baz' };
 *
 *     utils.merge(a, b);
 *     // => { foo: 'bar', bar: 'baz' }
 *
 * @param {Object} a
 * @param {Object} b
 * @return {Object}
 * @api private
 */
exports.merge = function(a, b){
  if (a && b) {
    for (var key in b) {
      a[key] = b[key];
    }
  }
  return a;
};
<|endoftext|>


<commit_before>var Network = require('./network.js');
var lift = require('./lift.js');

module.exports = {
	Network: Network,
	lift: lift
};

// Include everything from composition
var composition = require('./composition.js');
for (var prop in composition) {
	module.exports[prop] = composition[prop];
}

// Networks
var lifted = require('./networks/lifted.js');
var linear = require('./networks/linear.js');
var convolution = require('./networks/convolution.js');
var pooling = require('./networks/pooling.js');
var activation = require('./networks/activation.js');
var perceptron = require('./networks/perceptron.js');
var misc = require('./networks/misc.js');
var modules = [
	lifted, linear, convolution, pooling, activation, perceptron, misc
];
for (var i = 0; i < modules.length; i++) {
	var m = modules[i];
	for (var prop in m) {
		module.exports[prop] = m[prop];
	}
}<commit_msg>make deserializeJSON a top-level module function.<commit_after>var Network = require('./network.js');
var lift = require('./lift.js');

module.exports = {
	Network: Network,
	lift: lift,
	deserializeJSON: Network.deserializeJSON
};

// Include everything from composition
var composition = require('./composition.js');
for (var prop in composition) {
	module.exports[prop] = composition[prop];
}

// Networks
var lifted = require('./networks/lifted.js');
var linear = require('./networks/linear.js');
var convolution = require('./networks/convolution.js');
var pooling = require('./networks/pooling.js');
var activation = require('./networks/activation.js');
var perceptron = require('./networks/perceptron.js');
var misc = require('./networks/misc.js');
var modules = [
	lifted, linear, convolution, pooling, activation, perceptron, misc
];
for (var i = 0; i < modules.length; i++) {
	var m = modules[i];
	for (var prop in m) {
		module.exports[prop] = m[prop];
	}
}<|endoftext|>


<commit_before>describe('Helpers', function() {
	it('should translate to kebab case', function() {
		expect(kebabCase('rdSomeCoolDirectiveHere')).toEqual(
			'rd-some-cool-directive-here'
		);
	});

	it('should check the deep equality between two values', function() {
		expect(isEqual('A great value here', 'A great value here')).toBeTruthy();
		expect(isEqual('A great value here', 'A_great value here')).not.toBeTruthy();

		expect(isEqual(1, [1,2,3,4])).not.toBeTruthy();
		expect(isEqual('1', [1,2,3,4])).not.toBeTruthy();
		expect(isEqual('1', 1)).not.toBeTruthy();
		expect(isEqual(1, 2)).not.toBeTruthy();

		expect(isEqual({ a: 1 }, { a: 1	})).toBeTruthy();
		expect(isEqual({ a: 1 }, { b: 1	})).not.toBeTruthy();

		expect(isEqual({
			someDeepObject: {
				anotherDeepObject: {
					goOn: {
						ohYeah: {
							weAreDone: 1
						}
					}
				}
			}
		}, {
			someDeepObject: {
				anotherDeepObject: {
					goOn: {
						ohYeah: {
							weAreDone: 1
						}
					}
				}
			}
		})).toBeTruthy();
		expect(isEqual({ a: 1 }, { b: 1	})).not.toBeTruthy();
	});

  it('should create custom error message', function() {
    expect(createError('message {0} message {1}!!!', 1, 2)).toEqual(
      new Error('message 1 message 2!!!')
    );
  });
});
<commit_msg>chore(test/helpers.js): reliable tests for `clone()` function<commit_after>describe('Helpers', function() {
	it('should translate to kebab case', function() {
		expect(kebabCase('rdSomeCoolDirectiveHere')).toEqual(
			'rd-some-cool-directive-here'
		);
	});

	it('should check the deep equality between two values', function() {
		expect(isEqual('A great value here', 'A great value here')).toBeTruthy();
		expect(isEqual('A great value here', 'A_great value here')).not.toBeTruthy();

		expect(isEqual(1, [1,2,3,4])).not.toBeTruthy();
		expect(isEqual('1', [1,2,3,4])).not.toBeTruthy();
		expect(isEqual('1', 1)).not.toBeTruthy();
		expect(isEqual(1, 2)).not.toBeTruthy();

		expect(isEqual({ a: 1 }, { a: 1	})).toBeTruthy();
		expect(isEqual({ a: 1 }, { b: 1	})).not.toBeTruthy();

		expect(isEqual({
			someDeepObject: {
				anotherDeepObject: {
					goOn: {
						ohYeah: {
							weAreDone: 1
						}
					}
				}
			}
		}, {
			someDeepObject: {
				anotherDeepObject: {
					goOn: {
						ohYeah: {
							weAreDone: 1
						}
					}
				}
			}
		})).toBeTruthy();
		expect(isEqual({ a: 1 }, { b: 1	})).not.toBeTruthy();
	});

  it('should clone a deep array', function() {
    expect(clone([[[[]]]])).toEqual([[[[]]]]);
  });

  it('should clone an object', function() {
    var object = {
      huge: {
        object: {
          lots: {
            of: {
              recursive: {
                keys: [1,2,3,4]
              }
            }
          }
        }
      }
    };

    expect(object).toBe(object);
    expect(clone(object)).toEqual(object);
    expect(clone(object)).not.toBe(object);
  });

  it('should create custom error message', function() {
    expect(createError('message {0} message {1}!!!', 1, 2)).toEqual(
      new Error('message 1 message 2!!!')
    );
  });
});
<|endoftext|>


<commit_before>"use strict";

const test       = require('tape');

const tests      = require("./tests.js");
const toByteCode = tests.toByteCode;

const lua     = require('../src/lua.js');
const lauxlib = require('../src/lauxlib.js');
const lualib  = require('../src/lualib.js');

const inttable2array = function(t) {
    let a = [];

    t.strong.forEach(function (v, k) {
        if (typeof k === 'number')
            a[k - 1] = v.value;
    });

    return a.map(e => e.value);
};

test('table.concat', function (t) {
    let luaCode = `
        return table.concat({1, 2, 3, 4, 5, 6, 7}, ",", 3, 5)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.concat"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.strictEqual(
        lua.lua_tojsstring(L, -1),
        "3,4,5",
        "Correct element(s) on the stack"
    );
});

test('table.pack', function (t) {
    let luaCode = `
        return table.pack(1, 2, 3)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.pack"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => typeof e[0] === 'number') // Filter out the 'n' field
            .map(e => e[1].value.value).reverse(),
        [1, 2, 3],
        "Correct element(s) on the stack"
    );
});

test('table.unpack', function (t) {
    let luaCode = `
        return table.unpack({1, 2, 3, 4, 5}, 2, 4)
    `, L;

    t.plan(4);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.unpack"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.strictEqual(
        lua.lua_tointeger(L, -3),
        2,
        "Correct element(s) on the stack"
    );

    t.strictEqual(
        lua.lua_tointeger(L, -2),
        3,
        "Correct element(s) on the stack"
    );

    t.strictEqual(
        lua.lua_tointeger(L, -1),
        4,
        "Correct element(s) on the stack"
    );
});

test('table.insert', function (t) {
    let luaCode = `
        local t = {1, 3, 4}
        table.insert(t, 5)
        table.insert(t, 2, 2)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.insert"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => typeof e[0] === 'number')
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4, 5],
        "Correct element(s) on the stack"
    );
});

test('table.remove', function (t) {
    let luaCode = `
        local t = {1, 2, 3, 3, 4, 4}
        table.remove(t)
        table.remove(t, 3)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.remove"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => typeof e[0] === 'number')
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4],
        "Correct element(s) on the stack"
    );
});

test('table.move', function (t) {
    let luaCode = `
        local t1 = {3, 4, 5}
        local t2 = {1, 2, nil, nil, nil, 6}
        return table.move(t1, 1, #t1, 3, t2)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.move"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => typeof e[0] === 'number')
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4, 5, 6],
        "Correct element(s) on the stack"
    );
});

test('table.sort (<)', function (t) {
    let luaCode = `
        local t = {3, 1, 5, ['just'] = 'tofuckitup', 2, 4}
        table.sort(t)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.sort"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        inttable2array(lua.lua_topointer(L, -1)),
        [1, 2, 3, 4, 5],
        "Correct element(s) on the stack"
    );
});

test('table.sort with cmp function', function (t) {
    let luaCode = `
        local t = {3, 1, 5, ['just'] = 'tofuckitup', 2, 4}
        table.sort(t, function (a, b)
            return a > b
        end)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.sort"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        inttable2array(lua.lua_topointer(L, -1)),
        [5, 4, 3, 2, 1],
        "Correct element(s) on the stack"
    );
});
<commit_msg>tests/ltablib.js: Use better filter for numeric keys<commit_after>"use strict";

const test       = require('tape');

const tests      = require("./tests.js");
const toByteCode = tests.toByteCode;

const lua     = require('../src/lua.js');
const lauxlib = require('../src/lauxlib.js');
const lualib  = require('../src/lualib.js');

const inttable2array = function(t) {
    let a = [];

    t.strong.forEach(function (v, k) {
        if (v.key.ttisnumber())
            a[k - 1] = v.value;
    });

    return a.map(e => e.value);
};

test('table.concat', function (t) {
    let luaCode = `
        return table.concat({1, 2, 3, 4, 5, 6, 7}, ",", 3, 5)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.concat"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.strictEqual(
        lua.lua_tojsstring(L, -1),
        "3,4,5",
        "Correct element(s) on the stack"
    );
});

test('table.pack', function (t) {
    let luaCode = `
        return table.pack(1, 2, 3)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.pack"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => e[1].key.ttisnumber()) // Filter out the 'n' field
            .map(e => e[1].value.value).reverse(),
        [1, 2, 3],
        "Correct element(s) on the stack"
    );
});

test('table.unpack', function (t) {
    let luaCode = `
        return table.unpack({1, 2, 3, 4, 5}, 2, 4)
    `, L;

    t.plan(4);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.unpack"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.strictEqual(
        lua.lua_tointeger(L, -3),
        2,
        "Correct element(s) on the stack"
    );

    t.strictEqual(
        lua.lua_tointeger(L, -2),
        3,
        "Correct element(s) on the stack"
    );

    t.strictEqual(
        lua.lua_tointeger(L, -1),
        4,
        "Correct element(s) on the stack"
    );
});

test('table.insert', function (t) {
    let luaCode = `
        local t = {1, 3, 4}
        table.insert(t, 5)
        table.insert(t, 2, 2)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.insert"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => e[1].key.ttisnumber())
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4, 5],
        "Correct element(s) on the stack"
    );
});

test('table.remove', function (t) {
    let luaCode = `
        local t = {1, 2, 3, 3, 4, 4}
        table.remove(t)
        table.remove(t, 3)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.remove"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => e[1].key.ttisnumber())
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4],
        "Correct element(s) on the stack"
    );
});

test('table.move', function (t) {
    let luaCode = `
        local t1 = {3, 4, 5}
        local t2 = {1, 2, nil, nil, nil, 6}
        return table.move(t1, 1, #t1, 3, t2)
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.move"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        [...lua.lua_topointer(L, -1).strong.entries()]
            .filter(e => e[1].key.ttisnumber())
            .map(e => e[1].value.value).sort(),
        [1, 2, 3, 4, 5, 6],
        "Correct element(s) on the stack"
    );
});

test('table.sort (<)', function (t) {
    let luaCode = `
        local t = {3, 1, 5, ['just'] = 'tofuckitup', 2, 4}
        table.sort(t)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.sort"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        inttable2array(lua.lua_topointer(L, -1)),
        [1, 2, 3, 4, 5],
        "Correct element(s) on the stack"
    );
});

test('table.sort with cmp function', function (t) {
    let luaCode = `
        local t = {3, 1, 5, ['just'] = 'tofuckitup', 2, 4}
        table.sort(t, function (a, b)
            return a > b
        end)
        return t
    `, L;

    t.plan(2);

    t.doesNotThrow(function () {

        let bc = toByteCode(luaCode);

        L = lauxlib.luaL_newstate();

        lualib.luaL_openlibs(L);

        lua.lua_load(L, null, bc, lua.to_luastring("test-table.sort"), lua.to_luastring("binary"));

        lua.lua_call(L, 0, -1);

    }, "JS Lua program ran without error");

    t.deepEqual(
        inttable2array(lua.lua_topointer(L, -1)),
        [5, 4, 3, 2, 1],
        "Correct element(s) on the stack"
    );
});
<|endoftext|>


<commit_before>var util = require( 'util' )
var options = {
  depth: null,
  colors: true,
}

module.exports = function inspect( value ) {
  return util.inspect( value, options )
}
<commit_msg>test(inspect): Add inspect.log()<commit_after>var util = require( 'util' )
var options = { depth: null, colors: process.stdout.isTTY }

function inspect( value ) {
  return util.inspect( value, options )
}

inspect.log = function( value ) {
  process.stdout.write( inspect( value ) )
  process.stdout.write( '\n' )
}

module.exports = inspect
<|endoftext|>


<commit_before>"use strict";

module.exports = ema;

function ema(closes, period, ema0) {
    var hist,
        total = 0,
        ema1,
        emas = [];

    if (ema0) {
        return emaNext(closes, period, ema0);
    }

    hist = closes.slice(0, period);
    closes = closes.slice(period);

    hist.forEach(function (close) {
        total += close;
    });

    ema0 = total / period;
    emas.push(ema0);
    closes.forEach(function (close) {
        ema1 = emaNext(close, period, ema0);
        emas.push(ema1);
        ema0 = ema1;
    });

    return emas;
}

function emaNext(close, period, ema0) {
    var alpha = 2 / (period + 1);

    return close * alpha + ema0 * (1 - alpha);
}
<commit_msg>fix(ema): fix close value in ema<commit_after>"use strict";

module.exports = ema;

function ema(closes, period, ema0) {
    var hist,
        total = 0,
        ema1,
        emas = [];

    if (ema0) {
        return emaNext(closes, period, ema0);
    }

    hist = closes.slice(0, period);
    closes = closes.slice(period);

    hist.forEach(function (close) {
        total += parseFloat(close);
    });

    ema0 = total / period;
    emas.push(ema0);
    closes.forEach(function (close) {
        ema1 = emaNext(close, period, ema0);
        emas.push(ema1);
        ema0 = ema1;
    });

    return emas;
}

function emaNext(close, period, ema0) {
    var alpha = 2 / (period + 1);

    return close * alpha + ema0 * (1 - alpha);
}
<|endoftext|>


<commit_before>var https = require('https');
var http = require('http');
var net = require('net');
var url = require('url');
var extend = require('util')._extend;
var util = require('../util');
var WhistleTransform = util.WhistleTransform;
var rules = require('../rules');

function addRuleHeaders(headers, req, name) {
	name = 'x-' + name + '-';
	var rules = req.rules;
	for (var i in rules) {
		headers[name + i] = rules[i].matcher;
	}
	headers['x-remote-ip'] = req.hostIp || '127.0.0.1';
	return headers;
}

function handleRes(res, data) {
	if (data) {
		extend(res.headers, data.headers);
		res.addZipTransform(new WhistleTransform(data));
	}

}

module.exports = function(req, res, next) {
	var config = this.config;
	var self = this;
	var responsed, resData;

	req.request = function(options) {
		options = options || req.options;
		req.realUrl = res.realUrl = options.href;

		var now = Date.now();
		var proxyUrl;
		if (util.isProxyProtocol(options.protocol)) {
			proxyUrl = util.rule.getMatcher(req.rules.rule);
			options = url.parse(req.fullUrl);
		}

		rules.resolveHost(options.localDNS && net.isIP(options.host) ? options.host :
			(proxyUrl && util.replaceProtocol(proxyUrl, util.getProtocol(req.fullUrl)) || options.href),
				function(err, ip, customHost) {
			req.dnsTime = Date.now() - now;
			req.customHost = customHost;
			req.hostIp = ip;

			if (err) {
				util.drain(req, function() {
					  res.response(util.wrapGatewayError('DNS Lookup Failed\r\n' + util.getErrorStack(err)));
					});
				return;
			}

			var isHttps = options.protocol == 'https:';
			var headers = req.headers;
			if (proxyUrl) {
				var proxyOptions = url.parse(proxyUrl);
				proxyOptions.host = ip;
				var isSocks = proxyOptions.protocol == 'socks:';
				if (isSocks || isHttps) {
					util.connect({
						isSocks: isSocks,
						host: ip,
						port: proxyOptions.port,
						isHttps: isHttps,
						url: req.fullUrl,
						auth: proxyOptions.auth,
						headers: {
							host: headers.host,
							'proxy-connection': 'keep-alive',
							'user-agent': headers['user-agent']
						}
					}, function(err, socket) {
						if (err) {
							util.drain(req, function() {
								  res.response(util.wrapGatewayError('Failed to connect to the proxy server: '
										  + proxyUrl + '; IP: ' + ip
										  + ' \r\n' + util.getErrorStack(err)));
								});
							return;
						}
						options.agent = false;
						options.createConnection = function() {
							return socket;
						};
						request(options);
					});
					return;
				}

				options.port = proxyOptions.port || config.port; //http proxy
			}

			options.host = ip;//设置ip
			if ((options.port || 80) == config.port && util.isLocalAddress(options.host)) {
				util.drain(req, function() {
					res.response(util.wrapResponse({
						statusCode: 302,
						headers: {
							location: 'http://' + config.localUIHost + (options.path || '')
						}
					}));
				});
			} else {
				options.agent = isHttps ? config.httpsAgent : config.httpAgent;
				request(options);
			}

			function request(options) {
				options.headers = headers;
				options.method = req.method;
				options.rejectUnauthorized = false;
				if (!proxyUrl) {
					headers.host = options.hostname + (options.port ? ':' + options.port : '');
				}
				headers.Host = headers.host;//tencent的服务器不识别小写的host
				options.hostname = null; //防止自动dns
				var client = (isHttps ? https : http)
								.request(options, res.response)
									.on('error', function(err) {
										util.drain(req, function() {
											res.response(util.wrapGatewayError(util.getErrorStack(err)));
										});
									});
				req.pipe(client);
			}
		}, req.rules.filter && req.rules.filter.host);
	};

	res.response = function(_res) {
		if (responsed) {
			return;
		}
		responsed = true;
		if (_res.realUrl) {
			req.realUrl = res.realUrl = _res.realUrl;
		}
		var headers = res.headers = _res.headers;
		res.trailers = _res.trailers;
		res.statusCode = _res.statusCode = _res.statusCode || 0;
		handleRes(res, resData);
		addRuleHeaders(headers, req, config.name);
		if (headers.location) {
			//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
			headers.location = util.encodeNonAsciiChar(headers.location);
		}
		res.src(_res);
		res.writeHead(_res.statusCode, _res.headers);
		res.trailers && res.addTrailers(res.trailers);
	};

	util.parseRuleToJson(req.rules.res,
			function(err, data) {
		if (req.rules.head && req.rules.head.res) {
			data = extend(req.rules.head.res, data);
		}
		util.readInjectFiles(data, function(data) {
			if (resData = data) {
				data.headers = util.lowerCaseify(data.headers);
				if (data.statusCode) {
					req.hostIp = '127.0.0.1';
					util.drain(req, function() {
						res.response(util.wrapResponse(data));
					});
					return;
				}

				if (data.top || data.bottom || data.body) {
					util.removeUnsupportsHeaders(req.headers);
				}
			}

			next();
		});
	});
};<commit_msg>agent<commit_after>var https = require('https');
var http = require('http');
var net = require('net');
var url = require('url');
var extend = require('util')._extend;
var util = require('../util');
var WhistleTransform = util.WhistleTransform;
var rules = require('../rules');

function addRuleHeaders(headers, req, name) {
	name = 'x-' + name + '-';
	var rules = req.rules;
	for (var i in rules) {
		headers[name + i] = rules[i].matcher;
	}
	headers['x-remote-ip'] = req.hostIp || '127.0.0.1';
	return headers;
}

function handleRes(res, data) {
	if (data) {
		extend(res.headers, data.headers);
		res.addZipTransform(new WhistleTransform(data));
	}

}

module.exports = function(req, res, next) {
	var config = this.config;
	var self = this;
	var responsed, resData;

	req.request = function(options) {
		options = options || req.options;
		req.realUrl = res.realUrl = options.href;

		var now = Date.now();
		var proxyUrl;
		if (util.isProxyProtocol(options.protocol)) {
			proxyUrl = util.rule.getMatcher(req.rules.rule);
			options = url.parse(req.fullUrl);
		}

		rules.resolveHost(options.localDNS && net.isIP(options.host) ? options.host :
			(proxyUrl && util.replaceProtocol(proxyUrl, util.getProtocol(req.fullUrl)) || options.href),
				function(err, ip, customHost) {
			req.dnsTime = Date.now() - now;
			req.customHost = customHost;
			req.hostIp = ip;

			if (err) {
				util.drain(req, function() {
					  res.response(util.wrapGatewayError('DNS Lookup Failed\r\n' + util.getErrorStack(err)));
					});
				return;
			}

			var isHttps = options.protocol == 'https:';
			var headers = req.headers;
			if (proxyUrl) {
				var proxyOptions = url.parse(proxyUrl);
				proxyOptions.host = ip;
				var isSocks = proxyOptions.protocol == 'socks:';
				if (isSocks || isHttps) {
					util.connect({
						isSocks: isSocks,
						host: ip,
						port: proxyOptions.port,
						isHttps: isHttps,
						url: req.fullUrl,
						auth: proxyOptions.auth,
						headers: {
							host: headers.host,
							'proxy-connection': 'keep-alive',
							'user-agent': headers['user-agent']
						}
					}, function(err, socket) {
						if (err) {
							util.drain(req, function() {
								  res.response(util.wrapGatewayError('Failed to connect to the proxy server: '
										  + proxyUrl + '; IP: ' + ip
										  + ' \r\n' + util.getErrorStack(err)));
								});
							return;
						}
						options.agent = null;
						options.createConnection = function() {
							return socket;
						};
						request(options);
					});
					return;
				}

				options.port = proxyOptions.port || config.port; //http proxy
			}

			options.host = ip;//设置ip
			if ((options.port || 80) == config.port && util.isLocalAddress(options.host)) {
				util.drain(req, function() {
					res.response(util.wrapResponse({
						statusCode: 302,
						headers: {
							location: 'http://' + config.localUIHost + (options.path || '')
						}
					}));
				});
			} else {
				options.agent = isHttps ? config.httpsAgent : config.httpAgent;
				request(options);
			}

			function request(options) {
				options.headers = headers;
				options.method = req.method;
				options.rejectUnauthorized = false;
				if (!proxyUrl) {
					headers.host = options.hostname + (options.port ? ':' + options.port : '');
				}
				headers.Host = headers.host;//tencent的服务器不识别小写的host
				options.hostname = null; //防止自动dns
				var client = (isHttps ? https : http)
								.request(options, res.response)
									.on('error', function(err) {
										util.drain(req, function() {
											res.response(util.wrapGatewayError(util.getErrorStack(err)));
										});
									});
				req.pipe(client);
			}
		}, req.rules.filter && req.rules.filter.host);
	};

	res.response = function(_res) {
		if (responsed) {
			return;
		}
		responsed = true;
		if (_res.realUrl) {
			req.realUrl = res.realUrl = _res.realUrl;
		}
		var headers = res.headers = _res.headers;
		res.trailers = _res.trailers;
		res.statusCode = _res.statusCode = _res.statusCode || 0;
		handleRes(res, resData);
		addRuleHeaders(headers, req, config.name);
		if (headers.location) {
			//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
			headers.location = util.encodeNonAsciiChar(headers.location);
		}
		res.src(_res);
		res.writeHead(_res.statusCode, _res.headers);
		res.trailers && res.addTrailers(res.trailers);
	};

	util.parseRuleToJson(req.rules.res,
			function(err, data) {
		if (req.rules.head && req.rules.head.res) {
			data = extend(req.rules.head.res, data);
		}
		util.readInjectFiles(data, function(data) {
			if (resData = data) {
				data.headers = util.lowerCaseify(data.headers);
				if (data.statusCode) {
					req.hostIp = '127.0.0.1';
					util.drain(req, function() {
						res.response(util.wrapResponse(data));
					});
					return;
				}

				if (data.top || data.bottom || data.body) {
					util.removeUnsupportsHeaders(req.headers);
				}
			}

			next();
		});
	});
};<|endoftext|>


<commit_before>var https = require('https');
var http = require('http');
var net = require('net');
var extend = require('util')._extend;
var util = require('../../util');
var WhistleTransform = util.WhistleTransform;
var rules = require('../rules');

function addRuleHeaders(headers, req, name) {
	name = 'x-' + name + '-';
	var rules = req.rules;
	for (var i in rules) {
		headers[name + i] = rules[i].matcher;
	}
	headers['x-remote-ip'] = req.hostIp || '127.0.0.1';
	return headers;
}

function handleRes(res, data) {
	if (data) {
		extend(res.headers, data.headers);
		res.addZipTransform(new WhistleTransform(data));
	}

}

module.exports = function(req, res, next) {
	var config = this.config;
	var self = this;
	var responsed, resData;
	req.request = function(options) {
		var now = Date.now();
		rules.resolveHost(net.isIP(options.host) ? options.host : (options.proxyUrl || options.href),
				function(err, ip, customHost) {
			req.dnsTime = Date.now() - now;
			req.customHost = customHost;
			req.hostIp = ip;
			options.host = ip;

			if (err) {
				util.drain(req, function() {
					  res.response(util.wrapGatewayError('DNS Lookup Failed\r\n' + util.getErrorStack(err)));
					});
				return;
			}

			if (options.proxyUrl && req.isHttps) {
				options.headers[config.httpsProxyHost] = ip + ':' + options.port
				options.protocol = 'http:';
				options.host = '127.0.0.1';
				options.port = config.httpsproxyport;
			}
			req.realUrl = res.realUrl = options.href;

			if (util.isLocalAddress(options.host) && (options.port || 80) == config.port) {
				util.drain(req, function() {
					res.response(util.wrapResponse({
						statusCode: 302,
						headers: {
							location: 'http://' + config.localUIHost + (options.path || '')
						}
					}));
				});
				return;
			}

			var isHttps = options.protocol == 'https:';
			options.agent = isHttps ? config.httpsAgent : config.httpAgent;
			options.rejectUnauthorized = false;
			options.hostname = null;

			var client = (isHttps ? https : http).request(options, res.response);

			req.on('close', function() {
				!responsed && util.emitError(req, new Error('aborted'));
			});

			client.on('error', function(err) {
				util.drain(req, function() {
					res.response(util.wrapGatewayError(util.getErrorStack(err)));
				});
			});
			req.pipe(client);
		});
	};

	res.response = function(_res) {
		if (responsed) {
			return;
		}
		responsed = true;
		if (_res.realUrl) {
			req.realUrl = res.realUrl = _res.realUrl;
		}
		var headers = res.headers = _res.headers;
		res.trailers = _res.trailers;
		res.statusCode = _res.statusCode = _res.statusCode || 0;
		handleRes(res, resData);
		addRuleHeaders(headers, req, config.name);
		if (headers.location) {
			//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
			headers.location = util.encodeNonAsciiChar(headers.location);
		}
		res.src(_res);
		res.writeHead(_res.statusCode, _res.headers);
		res.trailers && res.addTrailers(res.trailers);
	};

	util.parseRuleToJson(req.rules.res,
			function(err, data) {
		if (req.rules.head && req.rules.head.res) {
			data = extend(req.rules.head.res, data);
		}

		if (resData = data) {
			data.headers = util.lowerCaseify(data.headers);
			if (data.statusCode) {
				req.hostIp = '127.0.0.1';
				util.drain(req, function() {
					res.response(util.wrapResponse(data));
				});
				return;
			}

			if (data.top || data.bottom || data.body) {
				util.removeUnsupportsHeaders(req.headers);
			}
		}

		next();
	});
};<commit_msg>hostip<commit_after>var https = require('https');
var http = require('http');
var net = require('net');
var extend = require('util')._extend;
var util = require('../../util');
var WhistleTransform = util.WhistleTransform;
var rules = require('../rules');

function addRuleHeaders(headers, req, name) {
	name = 'x-' + name + '-';
	var rules = req.rules;
	for (var i in rules) {
		headers[name + i] = rules[i].matcher;
	}
	headers['x-remote-ip'] = req.hostIp || '127.0.0.1';
	return headers;
}

function handleRes(res, data) {
	if (data) {
		extend(res.headers, data.headers);
		res.addZipTransform(new WhistleTransform(data));
	}

}

module.exports = function(req, res, next) {
	var config = this.config;
	var self = this;
	var responsed, resData;
	req.request = function(options) {
		var now = Date.now();
		rules.resolveHost(net.isIP(options.host) ? options.host : (options.proxyUrl || options.href),
				function(err, ip, customHost) {
			req.dnsTime = Date.now() - now;
			req.customHost = customHost;
			req.hostIp = ip;
			options.host = ip;
			req.realUrl = res.realUrl = options.href;

			if (err) {
				util.drain(req, function() {
					  res.response(util.wrapGatewayError('DNS Lookup Failed\r\n' + util.getErrorStack(err)));
					});
				return;
			}

			if (options.proxyUrl && req.isHttps) {
				options.headers[config.httpsProxyHost] = ip + ':' + options.port
				options.protocol = 'http:';
				options.host = '127.0.0.1';
				options.port = config.httpsproxyport;
			}

			if (util.isLocalAddress(options.host) && (options.port || 80) == config.port) {
				util.drain(req, function() {
					res.response(util.wrapResponse({
						statusCode: 302,
						headers: {
							location: 'http://' + config.localUIHost + (options.path || '')
						}
					}));
				});
				return;
			}

			var isHttps = options.protocol == 'https:';
			options.agent = isHttps ? config.httpsAgent : config.httpAgent;
			options.rejectUnauthorized = false;
			options.hostname = null;

			var client = (isHttps ? https : http).request(options, res.response);

			req.on('close', function() {
				!responsed && util.emitError(req, new Error('aborted'));
			});

			client.on('error', function(err) {
				util.drain(req, function() {
					res.response(util.wrapGatewayError(util.getErrorStack(err)));
				});
			});
			req.pipe(client);
		});
	};

	res.response = function(_res) {
		if (responsed) {
			return;
		}
		responsed = true;
		if (_res.realUrl) {
			req.realUrl = res.realUrl = _res.realUrl;
		}
		var headers = res.headers = _res.headers;
		res.trailers = _res.trailers;
		res.statusCode = _res.statusCode = _res.statusCode || 0;
		handleRes(res, resData);
		addRuleHeaders(headers, req, config.name);
		if (headers.location) {
			//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
			headers.location = util.encodeNonAsciiChar(headers.location);
		}
		res.src(_res);
		res.writeHead(_res.statusCode, _res.headers);
		res.trailers && res.addTrailers(res.trailers);
	};

	util.parseRuleToJson(req.rules.res,
			function(err, data) {
		if (req.rules.head && req.rules.head.res) {
			data = extend(req.rules.head.res, data);
		}

		if (resData = data) {
			data.headers = util.lowerCaseify(data.headers);
			if (data.statusCode) {
				req.hostIp = '127.0.0.1';
				util.drain(req, function() {
					res.response(util.wrapResponse(data));
				});
				return;
			}

			if (data.top || data.bottom || data.body) {
				util.removeUnsupportsHeaders(req.headers);
			}
		}

		next();
	});
};<|endoftext|>


<commit_before>class MovieNameLib {
    getMovieFilename(movieFilename, movie) {
        const ext = movieFilename.split(".").pop();

        const movieName = this._getMovieTitleAndYear(movie);

        return movieName + "." + ext;
    }

    getMovieTitleAndYear(movie) {
        const movieName = this._getCleanMovieName(movie);

        return movieName + "." + movie.year.toString();
    }

    _getCleanMovieName(movie) {
        // Replace current periods
        let newName = movie.title.replace(/\./g, "");

        // Replace spaces and dashes with periods
        newName = newName.replace(/(\s|\-)/g, ".");

        // Replace everything else with blank
        return newName.replace(/[^\.a-zA-Z0-9]/g, "");
    }
}

export default MovieNameLib;
<commit_msg>Renamed method call without the _<commit_after>class MovieNameLib {
    getMovieFilename(movieFilename, movie) {
        const ext = movieFilename.split(".").pop();

        const movieName = this.getMovieTitleAndYear(movie);

        return movieName + "." + ext;
    }

    getMovieTitleAndYear(movie) {
        const movieName = this._getCleanMovieName(movie);

        return movieName + "." + movie.year.toString();
    }

    _getCleanMovieName(movie) {
        // Replace current periods
        let newName = movie.title.replace(/\./g, "");

        // Replace spaces and dashes with periods
        newName = newName.replace(/(\s|\-)/g, ".");

        // Replace everything else with blank
        return newName.replace(/[^\.a-zA-Z0-9]/g, "");
    }
}

export default MovieNameLib;
<|endoftext|>


<commit_before>
/**
 * Provide some automatic handling of form controls, enable and disable elments based upon other values.
 *
 * Example:
 *   Cause the input text field named 'text' to be enbled when 'foo' is selected, when 'bar' is selected
 *     the input field will be disabled. The values to these two data- attributes are selectors. The more
 *     generic the selector, the greater possibility for there to be ambiguity in matching the originating
 *     event. It is up to the caller to make the value selector specific enough to remove ambiguity.
 *
 *   <select name="objectType">
 *   	<option value="foo">foo</option>
 *      <option value="bar">bar</option>
 *   </select>
 *
 *   <input name="text" type="text" data-enable-on-trigger="[name=objectType]" data-value="[value=foo]:selected" >
 */

$.fn.noscript = function() {

	// identify controllers by collecting the selectors from the listeners
	var container = this.is( "form" ) ? this : this.find( "form" ),
		controllers = {},
		triggerTypes = [ "[data-enable-on-trigger]", "[data-show-on-trigger]" ],
		toCamelCase = function(string) {
			// [data-some-name] --> someName
			return string.substring(6, string.length - 1).replace(/([ -]+)([a-zA-Z0-9])/g, function(a,b,c) {
				return c.toUpperCase();
			}).replace(/-/g, "");
		};

    $.each( triggerTypes, function( i, dataSelector ) {

		container.find( dataSelector ).each( function() {

			var enableOn = toCamelCase(dataSelector),
				onTrigger = $( this ).data( enableOn ).split( "," );

			$.each( onTrigger, function( index, selector ) {
				if ( !controllers[ selector ] ) {
					controllers[ selector ] = true;
				}
			});

		});
	});

    // bind change event on all select, checkbox and radio controls
	container.on( "change", "select, input[type=checkbox], input[type=radio]", function( event ) {

		var originator = $( event.currentTarget ),
			changedListeners = [];

		// handle enable/disable
		container.find( "[data-enable-on-trigger]" ).each( function() {

			$( this ).each( function() {

				var listener = $( this ),
					data = listener.data();

				// if listener is interested in this controller
				if ( originator.is( data.enableOnTrigger ) ) {

					// If the originator is disabled, the listener should be as well.
					var selector = data.value,
						disable = false;

					if ( !originator.prop( "disabled" ) ) {
						// When originator is select, match on the selected option.
						if ( originator.is( "select" ) ) {
							disable = !originator.find( "option:selected" ).is( selector );
						} else {
							disable = !originator.is( selector );
						}
					}

                    var addToChangedListeners = true;
                    if ( listener.is( "tr, td" ) ) {
                        listener.toggleClass( "vs-disabled", disable );
                    } else {
                        // Don't fire a change event for an unchecked radio button
                        addToChangedListeners = !listener.is( "[type=radio]" ) || listener.prop( "checked" );
                        listener.prop( "disabled", disable );
                    }

                    if ( addToChangedListeners ) {
                        // if this listener is also a controller, keep track so we can trigger a change event
                        $.each( controllers, function( selector ) {
                            if ( listener.is( selector )) {
                                changedListeners.push( listener );
                                return false; // break
                            }
                        });
                    }
                }
            });
        });

        // handle show/hide
        container.find( "[data-show-on-trigger]" ).each( function() {
            var listener = $( this );

            if ( originator.is( listener.data( "showOnTrigger" ) ) ) {

                var hideListener = false;
                // If the originator is disabled, the listener should be hidden regardless of the value
                 if ( originator.is( "select" ) ) {
                     // Match on the selected option: <select> --> <option selected>value</option>
                     hideListener = originator.prop( "disabled" ) || !originator.find( "option:selected" ).is( listener.data( "value" ) );
                 } else {
                     hideListener = originator.prop( "disabled" ) || !originator.is( listener.data( "value" ) );
                 }

                 // Don't check if already :visible or not, because these listeners may
                 // already be in the advanced options area which may be not visible.
                if ( hideListener ) {
                    listener.hide();
                } else {
                    listener.show();
                }
            }
        });

        // at the end of the event fire any controlling listeners
        $.each( changedListeners, function( index, listener ) {
            $( listener ).change();
        });

    });

    // Fire controllers on init to set initial state
    $.each( controllers, function( selector ) {
        // further iterate on these, a selector for a radio may have more than one match.
        container.find( selector ).each( function() {
            var t = $( this );
            if ( !t.prop( "disabled" ) ) {
                if ( t.is( "[type=radio]" ) ) {
                    if ( t.is( ":checked" ) ) {
                        t.change();
                    }
                } else {
                    t.change();
                }
            }
        });
    });
};

// User may initialize by calling $( "form" ).noscript()
// - or by using the 'noscript' attribute on the form element.
// Example: <form noscript>
$( document ).ready( function() {
	$( "body" ).find( "form[noscript]" ).noscript();
});

<commit_msg>wrap in no conflict<commit_after>
/**
 * Provide some automatic handling of form controls, enable and disable elments based upon other values.
 *
 * Example:
 *   Cause the input text field named 'text' to be enbled when 'foo' is selected, when 'bar' is selected
 *     the input field will be disabled. The values to these two data- attributes are selectors. The more
 *     generic the selector, the greater possibility for there to be ambiguity in matching the originating
 *     event. It is up to the caller to make the value selector specific enough to remove ambiguity.
 *
 *   <select name="objectType">
 *   	<option value="foo">foo</option>
 *      <option value="bar">bar</option>
 *   </select>
 *
 *   <input name="text" type="text" data-enable-on-trigger="[name=objectType]" data-value="[value=foo]:selected" >
 */
(function ( $ ) {

	$.fn.noscript = function() {

		// identify controllers by collecting the selectors from the listeners
		var container = this.is( "form" ) ? this : this.find( "form" ),
			controllers = {},
			triggerTypes = [ "[data-enable-on-trigger]", "[data-show-on-trigger]" ],
			toCamelCase = function(string) {
				// [data-some-name] --> someName
				return string.substring(6, string.length - 1).replace(/([ -]+)([a-zA-Z0-9])/g, function(a,b,c) {
					return c.toUpperCase();
				}).replace(/-/g, "");
			};

	    $.each( triggerTypes, function( i, dataSelector ) {

			container.find( dataSelector ).each( function() {

				var enableOn = toCamelCase(dataSelector),
					onTrigger = $( this ).data( enableOn ).split( "," );

				$.each( onTrigger, function( index, selector ) {
					if ( !controllers[ selector ] ) {
						controllers[ selector ] = true;
					}
				});

			});
		});

	    // bind change event on all select, checkbox and radio controls
		container.on( "change", "select, input[type=checkbox], input[type=radio]", function( event ) {

			var originator = $( event.currentTarget ),
				changedListeners = [];

			// handle enable/disable
			container.find( "[data-enable-on-trigger]" ).each( function() {

				$( this ).each( function() {

					var listener = $( this ),
						data = listener.data();

					// if listener is interested in this controller
					if ( originator.is( data.enableOnTrigger ) ) {

						// Default listener to disabled.
						var selector = data.value,
							disable = true;

						// If the originator is disabled, the listener should be as well.
						if ( !originator.prop( "disabled" ) ) {
							// When originator is select, match on the selected option.
							if ( originator.is( "select" ) ) {
								disable = !originator.find( "option:selected" ).is( selector );
							} else {
								disable = !originator.is( selector );
							}
						}

	                    var addToChangedListeners = true;
	                    if ( listener.is( "tr, td" ) ) {
	                        listener.toggleClass( "vs-disabled", disable );
	                    } else {
	                        // Don't fire a change event for an unchecked radio button
	                        addToChangedListeners = !listener.is( "[type=radio]" ) || listener.prop( "checked" );
	                        listener.prop( "disabled", disable );
	                    }

	                    if ( addToChangedListeners ) {
	                        // if this listener is also a controller, keep track so we can trigger a change event
	                        $.each( controllers, function( selector ) {
	                            if ( listener.is( selector )) {
	                                changedListeners.push( listener );
	                                return false; // break
	                            }
	                        });
	                    }
	                }
	            });
	        });

			// handle show/hide
			container.find( "[data-show-on-trigger]" ).each( function() {

				var listener = $( this ),
					data = listener.data();

				if ( originator.is( data.showOnTrigger ) ) {

					var selector = data.value,
						hide = true;

					// If the originator is disabled, the listener should be hidden regardless of the value
					if ( !originator.prop( "disabled" ) ) {
						if ( originator.is( "select" ) ) {
							// Match on the selected option: <select> --> <option selected>value</option>
							hide = !originator.find( "option:selected" ).is( selector );
						} else {
							hide = !originator.is( selector );
						}
					}

					if ( hide ) {
						listener.hide();
					} else {
						listener.show();
					}
				}
			});

			// at the end of the event fire any controlling listeners
			$.each( changedListeners, function( index, listener ) {
				$( listener ).change();
			});

		});

	    // Fire controllers on init to set initial state
	    $.each( controllers, function( selector ) {
	        // further iterate on these, a selector for a radio may have more than one match.
	        container.find( selector ).each( function() {
	            var t = $( this );
	            if ( !t.prop( "disabled" ) ) {
	                if ( t.is( "[type=radio]" ) ) {
	                    if ( t.is( ":checked" ) ) {
	                        t.change();
	                    }
	                } else {
	                    t.change();
	                }
	            }
	        });
	    });
	};

}( jQuery ));

// User may initialize by calling $( "form" ).noscript()
// - or by using the 'noscript' attribute on the form element.
// Example: <form noscript>
$( document ).ready( function() {
	$( "body" ).find( "form[noscript]" ).noscript();
});

<|endoftext|>


<commit_before>/**
 * @fileOverview Ensures that no imported module imports the linted module.
 * @author Ben Mosher
 */

import Exports from '../ExportMap'
import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor'
import docsUrl from '../docsUrl'

// todo: cache cycles / deep relationships for faster repeat evaluation
module.exports = {
  meta: {
    docs: { url: docsUrl('no-cycle') },
    schema: [makeOptionsSchema({
      maxDepth:{
        description: 'maximum dependency depth to traverse',
        type: 'integer',
        minimum: 1,
      },
    })],
  },

  create: function (context) {
    const myPath = context.getFilename()
    if (myPath === '<text>') return  // can't cycle-check a non-file

    const options = context.options[0] || {}
    const maxDepth = options.maxDepth || Infinity

    function checkSourceValue(sourceNode, importer) {
      const imported = Exports.get(sourceNode.value, context)

      if (imported == null) {
        return  // no-unresolved territory
      }

      if (imported.path === myPath) {
        return  // no-self-import territory
      }

      const untraversed = [{mget: () => imported, route:[]}]
      const traversed = new Set()
      function detectCycle({mget, route}) {
        const m = mget()
        if (m == null) return
        if (traversed.has(m.path)) return
        traversed.add(m.path)

        for (let [path, { getter, source }] of m.imports) {
          if (path === myPath) return true
          if (traversed.has(path)) continue
          if (route.length + 1 < maxDepth) {
            untraversed.push({
              mget: getter,
              route: route.concat(source),
            })
          }
        }
      }

      while (untraversed.length > 0) {
        const next = untraversed.shift() // bfs!
        if (detectCycle(next)) {
          const message = (next.route.length > 0
            ? `Dependency cycle via ${routeString(next.route)}`
            : 'Dependency cycle detected.')
          context.report(importer, message)
          return
        }
      }
    }

    return moduleVisitor(checkSourceValue, context.options[0])
  },
}

function routeString(route) {
  return route.map(s => `${s.value}:${s.loc.start.line}`).join('=>')
}
<commit_msg>[Fix] `no-cycle`: `create` must *always* return an object, even if there’s no listeners<commit_after>/**
 * @fileOverview Ensures that no imported module imports the linted module.
 * @author Ben Mosher
 */

import Exports from '../ExportMap'
import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor'
import docsUrl from '../docsUrl'

// todo: cache cycles / deep relationships for faster repeat evaluation
module.exports = {
  meta: {
    docs: { url: docsUrl('no-cycle') },
    schema: [makeOptionsSchema({
      maxDepth:{
        description: 'maximum dependency depth to traverse',
        type: 'integer',
        minimum: 1,
      },
    })],
  },

  create: function (context) {
    const myPath = context.getFilename()
    if (myPath === '<text>') return {} // can't cycle-check a non-file

    const options = context.options[0] || {}
    const maxDepth = options.maxDepth || Infinity

    function checkSourceValue(sourceNode, importer) {
      const imported = Exports.get(sourceNode.value, context)

      if (imported == null) {
        return  // no-unresolved territory
      }

      if (imported.path === myPath) {
        return  // no-self-import territory
      }

      const untraversed = [{mget: () => imported, route:[]}]
      const traversed = new Set()
      function detectCycle({mget, route}) {
        const m = mget()
        if (m == null) return
        if (traversed.has(m.path)) return
        traversed.add(m.path)

        for (let [path, { getter, source }] of m.imports) {
          if (path === myPath) return true
          if (traversed.has(path)) continue
          if (route.length + 1 < maxDepth) {
            untraversed.push({
              mget: getter,
              route: route.concat(source),
            })
          }
        }
      }

      while (untraversed.length > 0) {
        const next = untraversed.shift() // bfs!
        if (detectCycle(next)) {
          const message = (next.route.length > 0
            ? `Dependency cycle via ${routeString(next.route)}`
            : 'Dependency cycle detected.')
          context.report(importer, message)
          return
        }
      }
    }

    return moduleVisitor(checkSourceValue, context.options[0])
  },
}

function routeString(route) {
  return route.map(s => `${s.value}:${s.loc.start.line}`).join('=>')
}
<|endoftext|>


<commit_before>"use strict";

var assert = require("assert");
var trusted = require("../index.js");

describe("OPENSSL", function() {
    it("stop", function() {
        trusted.common.OpenSSL.stop();

        assert.equal(trusted.common.OpenSSL.printErrors(), "");
    });

    it("run", function() {
        trusted.common.OpenSSL.run();

        trusted.pki.Certificate.load("undefined");
        assert.equal(trusted.common.OpenSSL.printErrors().length > 0, true);
    });
});
<commit_msg>test: add try..catch<commit_after>"use strict";

var assert = require("assert");
var trusted = require("../index.js");

describe("OPENSSL", function() {
    it("stop", function() {
        trusted.common.OpenSSL.stop();

        assert.equal(trusted.common.OpenSSL.printErrors(), "");
    });

    it("run", function() {
        trusted.common.OpenSSL.run();

        try {
            trusted.pki.Certificate.load("undefined");
        } catch (err) {
            assert.equal(trusted.common.OpenSSL.printErrors().length > 0, true);
        }
    });
});
<|endoftext|>


<commit_before>var fs = require('fs');
var EasyZip = require('easy-zip').EasyZip;
var StringHelper = require('../helpers/stringhelper');
var Logger = require('./logger');

/*
** Zip the whole folder to a package.
** @params:
**     folderPath: The folder path.
**     zipPath: The path of target package.
**     callback: The callback function.
*/
exports.zipFolder = function(folderPath, zipPath, callback){
    var logger = Logger.getInstance();
    try{
        var easyZip = traverseFolder(folderPath);
        easyZip.writeToFile(zipPath);
        logger.logSuc('Finish to zip files');
        return callback();
    }
    catch(err){
        return callback(err);
    }
};

/*
** Traverse the target folder and its sub-folder, and set all the folders and files for EasyZip module.
** @params:
**     folderPath: The path of the folder which will be zipped.
**     easyZip: An instance of EasyZip. This parameter is only used in recursive invocations. Set it to null at first.
**     folder: An property of EasyZip instance. This parameter is only used in recursive invocations. Set it to null at first.
** @returns:
**     returns an EasyZip instance.
*/
function traverseFolder(folderPath, easyZip, folder){
    if(!easyZip){
        easyZip = new EasyZip();
    }
    var folderName = StringHelper.getLastSegment(folderPath);
    folder = folder ? folder.folder(folderName) : easyZip.folder(folderName);
    var files = fs.readdirSync(folderPath);
    if(null !== files && null !== files.length && files.length > 0){
        for(var i = 0; i < files.length; i++){
            var filePath = StringHelper.addSlash(folderPath) + files[i];
            var stats = fs.statSync(filePath);
            if(stats.isFile()){
                var content = fs.readFileSync(filePath);
                folder.file(files[i], content);
            }
            else if(stats.isDirectory()){
                easyZip = traverseFolder(filePath, easyZip, folder);
            }
        }
    }

    return easyZip;
}<commit_msg>fix bugs #74,#86,#87<commit_after>var fs = require('fs');
var EasyZip = require('easy-zip').EasyZip;
var StringHelper = require('../helpers/stringhelper');
var Logger = require('./logger');
var logger = Logger.getInstance();

/*
** Zip the whole folder to a package.
** @params:
**     folderPath: The folder path.
**     zipPath: The path of target package.
**     callback: The callback function.
*/
exports.zipFolder = function(folderPath, zipPath, callback){
    try{
        var easyZip = traverseFolder(folderPath);
        easyZip.writeToFile(zipPath);
        logger.logSuc('Finish to zip files');
        return callback();
    }
    catch(err){
        return callback(err);
    }
};

/*
** Traverse the target folder and its sub-folder, and set all the folders and files for EasyZip module.
** @params:
**     folderPath: The path of the folder which will be zipped.
**     easyZip: An instance of EasyZip. This parameter is only used in recursive invocations. Set it to null at first.
**     folder: An property of EasyZip instance. This parameter is only used in recursive invocations. Set it to null at first.
** @returns:
**     returns an EasyZip instance.
*/
function traverseFolder(folderPath, easyZip, folder){
    if(null === easyZip){
        easyZip = new EasyZip();
    }
    var folderName = StringHelper.getLastSegment(folderPath);
    folder = folder ? folder.folder(folderName) : easyZip.folder(folderName);
    var files = fs.readdirSync(folderPath);
    if(null !== files && null !== files.length && files.length > 0){
        for(var i = 0; i < files.length; i++){
            var filePath = StringHelper.addSlash(folderPath) + files[i];
            var stats = fs.statSync(filePath);
            if(stats.isFile()){
                var content = fs.readFileSync(filePath);
                folder.file(files[i], content);
            }
            else if(stats.isDirectory()){
                easyZip = traverseFolder(filePath, easyZip, folder);
            }
        }
    }

    return easyZip;
}<|endoftext|>


<commit_before>const placard = require('../src/index');
const should = require('should');
const assert = require('assert');
const util = require('util');

describe('Placard', function () {
  this.timeout(5000);

  describe('#fullSportsBook()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.fullSportsBook()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.fullSportsBook(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should have status property', function () {
      assert.equal(true, resData.hasOwnProperty('status'))
    })
  });

  describe('#nextEvents()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.nextEvents()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.nextEvents(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should have status property', function () {
      assert.equal(true, resData.hasOwnProperty('status'))
    })
  });

  describe('#info()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.info()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.info(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should be an array', function () {
      assert.equal(true, util.isArray(resData))
    })
  });

  describe('#faq()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.faq()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.faq(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should be an array', function () {
      assert.equal(true, util.isArray(resData))
    })
  })
});<commit_msg>fix tests<commit_after>const placard = require('../src/index');
const should = require('should');
const assert = require('assert');
const util = require('util');

describe('Placard', function () {
  this.timeout(5000);

  describe('#fullSportsBook()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.fullSportsBook()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.fullSportsBook(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should have status property', function () {
      assert.equal(true, resData.hasOwnProperty('status'))
    })
  });

  describe('#nextEvents()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.nextEvents()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.nextEvents(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should have status property', function () {
      assert.equal(true, resData.hasOwnProperty('status'))
    })
  });

  describe('#info()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.info()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.info(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should be an array if data !== undefined', function () {
      if (resData) assert.equal(true, util.isArray(resData))
    })
  });

  describe('#faq()', function () {
    var resData;

    it('should return a promise with fetched data', function (done) {
      placard.faq()
        .then(function () {
          done()
        })
        .catch(function (err) {
          throw err;
        })
    });

    it('should call a callback', function (done) {
      placard.faq(function (err, data) {
        if (err) throw err;

        resData = data;
        done()
      })
    });

    it('should be an array', function () {
      assert.equal(true, util.isArray(resData))
    })
  })
});<|endoftext|>