<commit_before>"use strict";

angular.module('arethusa.constituents').directive('constituent', [

  function() {
    var parts = ['class', 'role'];

    return {
      restrict: 'A',
      scope: {
        constituent: '='
      },
      link: function(scope, element, attrs) {
        function buildLabel() {
          scope.label = arethusaUtil.inject([], parts, function(memo, part) {
            var p = scope.constituent[part];
            if (p) memo.push(p);
          }).join(' - ');
        }

        for (var i = parts.length - 1; i >= 0; i--) {
          var part = parts[i];
          scope.$watch('constituent.' + part, buildLabel);
        }
      },
      template: '{{ label }}'
    };
  }
]);
<commit_msg>Fix constituent template<commit_after>"use strict";

angular.module('arethusa.constituents').directive('constituent', [

  function() {
    var parts = ['class', 'role'];

    return {
      restrict: 'A',
      scope: {
        constituent: '='
      },
      link: function(scope, element, attrs) {
        function buildLabel() {
          scope.label = arethusaUtil.inject([], parts, function(memo, part) {
            var p = scope.constituent[part];
            if (p) memo.push(p);
          }).join(' - ');
        }

        for (var i = parts.length - 1; i >= 0; i--) {
          var part = parts[i];
          scope.$watch('constituent.' + part, buildLabel);
        }
      },
      template: '
{{ label }}
'
    };
  }
]);
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2014 University Of Southern California
 *
 *  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.
 */

/**
 * Created by dcbriggs on 7/14/14.
 */
define(["moment"],
    function (moment) {
        "use strict"
        var runsController = function ($scope, $window, $http, $state) {

            // Adjust this to change the number of pages you have to request from the server
            var resultsPerPage = 100;

            $scope.alerts = [];
            $scope.getAlertIcon = function (status) {
                return (status == 'success') ? "text-success fa fa-check-circle" : "text-danger fa fa-exclamation-triangle";
            };

            $scope.closeAlert = function (index) {
                $scope.alerts.splice(index, 1);
            };

            function getRuns() {
                $http.get($window.apiLinks.runs, {
                    params: {
                        results_per_page: resultsPerPage
                    }
                }).success(function (data) {
                    $scope.runs = data.objects;
                    // Get all the results after the first page
                    for (var currentPage = 2; currentPage <= data.total_pages; currentPage++) {
                        $http.get($window.apiLinks.runs, {
                            params: {
                                results_per_page: resultsPerPage,
                                page: currentPage
                            }
                        }).success(function (data) {
                            $scope.runs = $scope.runs.concat(data.objects);
                        }).error(function (data) {
                            $scope.alerts.push({
                                "type": "danger",
                                "message": "Unable to get runs, please contact the Pegasus team if this issue persists"
                            });
                        })
                    }
                }).error(function (data) {
                    console.error(data);
                });
            }

            getRuns();

            $scope.refresh = getRuns;

            // We have to define this with the CSS hardcoded in here because the system does not seem
            // to like inlining the -'s that bootstrap classes use
            $scope.getbgColor = function (exitCode) {
                return (exitCode == 0) ? "bg-success" : (exitCode == -1) ? "bg-info" : "bg-danger";
            };

            $scope.getExitCodeIcon = function (status) {
                switch (status) {
                    case -1:
                        return "text-primary fa fa-check-circle";
                    case 0:
                        return "text-success fa fa-check-circle";
                    case 256:
                        return "text-warning fa fa-warning";
                    default:
                        return "text-danger fa fa-exclamation-triangle";
                }
            };

            $scope.createRun = function () {
                $state.go('createRun');
            };

            $scope.deleteSelected = function () {

                var selected = $scope.runsGrid.selectedItems;
                var deleteTotal = $scope.runsGrid.selectedItems.length;
                var runName = selected[0].name;
                if (deleteTotal > 1) {
                    runName = "these " + deleteTotal + " runs"
                }
                var doubleCheck = confirm("Are you sure you want to delete " + runName + "?  This will delete all output files as well.");
                if (!doubleCheck) {
                    return;
                }

                var deleteCount = 0;
                for (var i = 0; i < deleteTotal; i++) {
                    $http.delete($window.apiLinks.runs + "/" + selected[i].name)
                        .success(function () {
                            // No specifications aside from the then clause
                        }).error(function () {
                            // TODO: display an error popup
                            deleteCount++;

                        })
                        .then(function () {
                            deleteCount++;
                            if (deleteCount == deleteTotal) {
                                $scope.runsGrid.selectedItems.length = 0;
                                getRuns();
                            }
                        })
                }
            };

            $scope.getFormattedDate = function (dateString) {
                var createdOn = moment.utc(dateString).local();
                var s = createdOn.format('ddd MMM DD, YYYY hh:mm:ss A');
                s += ' (' + createdOn.fromNow() + ')';
                return s;
            };

            $scope.runsGrid = {
                data: "runs",
                enablePaging: true,
                showGroupPanel: true,
                showSelectionCheckbox: true,
                selectWithCheckboxOnly: true,
                showFilter: true,
                columnDefs: [
                    {field: "name", displayName: "Name", cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "status", displayName: "Status", width: 60, cellTemplate: "" },
                    {field: "readLength", displayName: "Read Length", width: '10%', cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "mismatches", displayName: "Mismatches", width: '10%', cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "filename", displayName: "File", cellTemplate: " {{row.getProperty(col.field)}}" },
                    {field: "created", displayName: "Started On", width: '30%', cellTemplate: "
{{getFormattedDate(row.getProperty(col.field))}}
" }
                ],
                sortInfo: {fields: ['created'], directions: ['desc']},
                selectedItems: []
            };

            $scope.getDownloadLink = function (id, filename) {
                return $window.apiLinks.runs + "/" + id + "/input/" + filename;
            };

        };

        function getFullConstructor() {
            return ["$scope", "$window", "$http", "$state", runsController];
        }

        // For testing so we can mock the injected variables
        function getMinimalConstructor() {
            return runsController;
        }

        return {
            getFullConstructor: getFullConstructor,
            getMinimalConstructor: getMinimalConstructor
        };

    });
<commit_msg>Rows have fixed height. So large files names were shown as multiple lines where bottom half of the text was not visible. Use ngCellText class which hides overflowing text.<commit_after>/*
 * Copyright 2007-2014 University Of Southern California
 *
 *  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.
 */

/**
 * Created by dcbriggs on 7/14/14.
 */
define(["moment"],
    function (moment) {
        "use strict"
        var runsController = function ($scope, $window, $http, $state) {

            // Adjust this to change the number of pages you have to request from the server
            var resultsPerPage = 100;

            $scope.alerts = [];
            $scope.getAlertIcon = function (status) {
                return (status == 'success') ? "text-success fa fa-check-circle" : "text-danger fa fa-exclamation-triangle";
            };

            $scope.closeAlert = function (index) {
                $scope.alerts.splice(index, 1);
            };

            function getRuns() {
                $http.get($window.apiLinks.runs, {
                    params: {
                        results_per_page: resultsPerPage
                    }
                }).success(function (data) {
                    $scope.runs = data.objects;
                    // Get all the results after the first page
                    for (var currentPage = 2; currentPage <= data.total_pages; currentPage++) {
                        $http.get($window.apiLinks.runs, {
                            params: {
                                results_per_page: resultsPerPage,
                                page: currentPage
                            }
                        }).success(function (data) {
                            $scope.runs = $scope.runs.concat(data.objects);
                        }).error(function (data) {
                            $scope.alerts.push({
                                "type": "danger",
                                "message": "Unable to get runs, please contact the Pegasus team if this issue persists"
                            });
                        })
                    }
                }).error(function (data) {
                    console.error(data);
                });
            }

            getRuns();

            $scope.refresh = getRuns;

            // We have to define this with the CSS hardcoded in here because the system does not seem
            // to like inlining the -'s that bootstrap classes use
            $scope.getbgColor = function (exitCode) {
                return (exitCode == 0) ? "bg-success" : (exitCode == -1) ? "bg-info" : "bg-danger";
            };

            $scope.getExitCodeIcon = function (status) {
                switch (status) {
                    case -1:
                        return "text-primary fa fa-check-circle";
                    case 0:
                        return "text-success fa fa-check-circle";
                    case 256:
                        return "text-warning fa fa-warning";
                    default:
                        return "text-danger fa fa-exclamation-triangle";
                }
            };

            $scope.createRun = function () {
                $state.go('createRun');
            };

            $scope.deleteSelected = function () {

                var selected = $scope.runsGrid.selectedItems;
                var deleteTotal = $scope.runsGrid.selectedItems.length;
                var runName = selected[0].name;
                if (deleteTotal > 1) {
                    runName = "these " + deleteTotal + " runs"
                }
                var doubleCheck = confirm("Are you sure you want to delete " + runName + "?  This will delete all output files as well.");
                if (!doubleCheck) {
                    return;
                }

                var deleteCount = 0;
                for (var i = 0; i < deleteTotal; i++) {
                    $http.delete($window.apiLinks.runs + "/" + selected[i].name)
                        .success(function () {
                            // No specifications aside from the then clause
                        }).error(function () {
                            // TODO: display an error popup
                            deleteCount++;

                        })
                        .then(function () {
                            deleteCount++;
                            if (deleteCount == deleteTotal) {
                                $scope.runsGrid.selectedItems.length = 0;
                                getRuns();
                            }
                        })
                }
            };

            $scope.getFormattedDate = function (dateString) {
                var createdOn = moment.utc(dateString).local();
                var s = createdOn.format('ddd MMM DD, YYYY hh:mm:ss A');
                s += ' (' + createdOn.fromNow() + ')';
                return s;
            };

            $scope.runsGrid = {
                data: "runs",
                enablePaging: true,
                showGroupPanel: true,
                showSelectionCheckbox: true,
                selectWithCheckboxOnly: true,
                showFilter: true,
                columnDefs: [
                    {field: "name", displayName: "Name", cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "status", displayName: "Status", width: 60, cellTemplate: "" },
                    {field: "readLength", displayName: "Read Length", width: '10%', cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "mismatches", displayName: "Mismatches", width: '10%', cellTemplate: "
{{row.getProperty(col.field)}}
" },
                    {field: "filename", displayName: "File", cellTemplate: "
 {{ row.getProperty(col.field) }}
" },
                    {field: "created", displayName: "Started On", width: '30%', cellTemplate: "
{{getFormattedDate(row.getProperty(col.field))}}
" }
                ],
                sortInfo: {fields: ['created'], directions: ['desc']},
                selectedItems: []
            };

            $scope.getDownloadLink = function (id, filename) {
                return $window.apiLinks.runs + "/" + id + "/input/" + filename;
            };

        };

        function getFullConstructor() {
            return ["$scope", "$window", "$http", "$state", runsController];
        }

        // For testing so we can mock the injected variables
        function getMinimalConstructor() {
            return runsController;
        }

        return {
            getFullConstructor: getFullConstructor,
            getMinimalConstructor: getMinimalConstructor
        };

    });
<|endoftext|>


<commit_before>/**
 * Copyright (c) Flyover Games, LLC.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to
 * whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall
 * be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var node_sdl2 = null;
try { node_sdl2 = node_sdl2 || require('./build/Release/node-sdl2.node'); } catch (err) {}
try { node_sdl2 = node_sdl2 || process._linkedBinding('node_sdl2'); } catch (err) {}
try { node_sdl2 = node_sdl2 || process.binding('node_sdl2'); } catch (err) {}
module.exports = node_sdl2;

node_sdl2.version = node_sdl2.version || node_sdl2.SDL_MAJOR_VERSION + "." + node_sdl2.SDL_MINOR_VERSION + "." + node_sdl2.SDL_PATCHLEVEL + " (" + node_sdl2.SDL_GetRevisionNumber() + ")";

node_sdl2.SDL_CheckError = node_sdl2.SDL_CheckError || function ()
{
	var error = node_sdl2.SDL_GetError(); node_sdl2.SDL_ClearError();
	if (error) { console.error("SDL", error); }
	return error;
};

/// var node_sdl2 = require('@flyover/node-sdl2');
/// var sdl = node_sdl2.SDL();
/// node_sdl2.SDL_* -> sdl.*
node_sdl2.SDL = function (out) {
	out = out || {};
	var re = /^(SDL_)(.*)/;
	for (var key in node_sdl2) {
		var match = key.match(re);
		if (match && match[2]) {
			console.log(key, match[2]);
			out[match[2]] = node_sdl2[key];
		} else {
			//console.log("!!!", key);
			out[key] = node_sdl2[key];
		}
	}
	return out;
}

//node_sdl2.SDL();
<commit_msg>revert node-sdl2.js from f6daffe9bb5430f75e46e4adfcd4f7d4b3576d72<commit_after>/**
 * Copyright (c) Flyover Games, LLC.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to
 * whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall
 * be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var sdl2 = null;
try { sdl2 = sdl2 || require('./build/Release/node-sdl2.node'); } catch (err) {}
try { sdl2 = sdl2 || process._linkedBinding('node_sdl2'); } catch (err) {}
try { sdl2 = sdl2 || process.binding('node_sdl2'); } catch (err) {}
module.exports = sdl2;

sdl2.version = sdl2.version || sdl2.SDL_MAJOR_VERSION + "." + sdl2.SDL_MINOR_VERSION + "." + sdl2.SDL_PATCHLEVEL + " (" + sdl2.SDL_GetRevisionNumber() + ")";
<|endoftext|>


<commit_before>(function(angular, vis) {

  'use strict';

  function OccupyViewController($scope, $state, $q, OccupyDataService) {

    var geoIP = require('geo-from-ip');
    var url = require('url');
    var dns = require('dns');

    this.state = $state.$current;
    this.baseState = this.state.parent.toString();
    this.tiles = {
      url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
    };
    this.center = {
      lat: 51.505,
      lng: -0.09,
      zoom: 2,
      autoDiscover: true
    };
    this.markers = {

    };

    this.initialize = function() {

      return OccupyDataService.initialize()
      .then(() => {
        OccupyDataService.readLine((err, line) => {

          var item = url.parse(line.uri);
          dns.lookup(item.hostname, { family: 4 }, (err, ip) => {
            console.log(item.hostname, ip);
            var loc = geoIP.allData(ip);
            $q.when(true).then(() => {
              var markerID = loc.city || loc.state;
              this.markers[markerID] = {
                lat: loc.location.latitude,
                lng: loc.location.longitude
              };
              //console.log(item.hostname, loc);
            });
          });
        });
      });
    };
  }

  module.exports = OccupyViewController;

})(global.angular, global.vis);
<commit_msg>line marker id update<commit_after>(function(angular, vis) {

  'use strict';

  function OccupyViewController($scope, $state, $q, OccupyDataService) {

    var geoIP = require('geo-from-ip');
    var url = require('url');
    var dns = require('dns');

    this.state = $state.$current;
    this.baseState = this.state.parent.toString();
    this.tiles = {
      url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
    };
    this.center = {
      lat: 51.505,
      lng: -0.09,
      zoom: 2,
      autoDiscover: true
    };
    this.markers = {

    };

    this.initialize = function() {

      return OccupyDataService.initialize()
      .then(() => {
        var lineNo = 1;
        OccupyDataService.readLine((err, line) => {
          var item = url.parse(line.uri);
          dns.lookup(item.hostname, { family: 4 }, (err, ip) => {
            console.log(item.hostname, ip);
            var loc = geoIP.allData(ip);
            $q.when(true).then(() => {
              var markerID = `marker${lineNo++}`;
              this.markers[markerID] = {
                lat: loc.location.latitude,
                lng: loc.location.longitude,
                message: line.uri
              };
              //console.log(item.hostname, loc);
            });
          });
        });
      });
    };
  }

  module.exports = OccupyViewController;

})(global.angular, global.vis);
<|endoftext|>


<commit_before>//Should move this out of Common at some point.
(function() {
    'use strict';

    angular.module('brewApp.services')
        .factory('Store', ['$resource', store]);

    function store($resource) {
        //Can get base URL from config.
        var Store = $resource('http://localhost:8008/api/v1/store/:id', { id: '@id' });

        function store(obj) {
            return Store.save(obj).$promise;
        }

        function getById(id) {
            return Store.$get({ id: id }).$promise;
        }

        return {
            store: store,
            getById: getById
        };
    }
})();
<commit_msg>Setting mongo url from location service<commit_after>//Should move this out of Common at some point.
(function() {
    'use strict';

    angular.module('brewApp.services')
        .factory('Store', ['$resource', '$location', store]);

    function store($resource, $location) {
        //Can get base URL from config.
        var host = $location.protocol() + '://' + $location.host() + ':' + $location.port();
        var Store = $resource(host + '/api/v1/store/:id', { id: '@id' });

        function store(obj) {
            return Store.save(obj).$promise;
        }

        function getById(id) {
            return Store.$get({ id: id }).$promise;
        }

        return {
            store: store,
            getById: getById
        };
    }
})();
<|endoftext|>


<commit_before>/*
TODO:
otestovat
royjet metodu valid
rozjet metodu validate
ukladat paramy do pameti uzlu??
pridat callbacky
checknout pravidla pro selecty a radia

custom classy
zmena DOMu
dogenerovani hlasek
error hlasky

definovani pravidel pro inputz pomoci trid
predani nastaveni inputu pomoci configu
*/

(function($) {

	$.bValidator = {

		defaults: {
		},

		validations: {},

		transformations: {},

		//settings: {},

		init: function(form, settings) {
			form.data('bValidator', settings);
			plugin = this;
			inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.each(function (){
				$(this).on('focusin.bValidator', function() {
					plugin.focus($(this));
				});

				$(this).on('focusout.bValidator', function() {
					plugin.validate($(this));
				});

				/*$(this).on('change.bValidator', function() {
					plugin.validate($(this));
				});*/

				plugin.initInput($(this));
			});

			//plugin.settings: $.extend({}, defaults, options);
			form.on('submit.bValidator', function(e) {
				var settings = $(this).data('bValidator');
				bValid = true;
				var inputs = $('input[data-bvString], input[data-bvStrict], textarea', $(this));

				inputs.each(function() {
					if(!plugin.validate($(this))) bValid = false;
				});

				if(!bValid) {
					settings.onSubmitFail.call( this, e );
					e.preventDefault();
				} else {
					inputs.each(function() {
						plugin.focus($(this));
					});
					//console.log(settings);
					settings.beforeSubmit.call( this, this, e );
				}
			});

		},

		getConfig: function(elem) {
			conf = {};
			// switch value - erase inputs with this value. Fill value of empty inputs on focus out
			conf['switchVal'] = (elem.attr('data-bvSwitch') == undefined ? '' : elem.attr('data-bvSwitch'));
			// prepended value
			conf['prepend'] = (elem.attr('data-bvPrepend') == undefined ? '' : elem.attr('data-bvPrepend'));
			// key string
			conf['string'] = (elem.attr('data-bvString') == undefined ? '.*' : elem.attr('data-bvString'));
			// appended value
			conf['append'] = (elem.attr('data-bvAppend') == undefined ? '' : elem.attr('data-bvAppend'));
			// string transformation
			conf['transform'] = (elem.attr('data-bvTransform') == undefined ? '' : elem.attr('data-bvTransform'));
			// pattern for regexp
			var pattern = '('+conf['prepend']+')?'+'('+conf['string']+')('+conf['append']+')?'+'';
			var re = new RegExp(pattern, 'i');
			// new string value
			conf['newString'] = elem.val().match(re)[2];
			// string which fill for empty inputs
			conf['empty'] = (elem.attr('data-bvEmpty') == undefined ? '' : elem.attr('data-bvEmpty'));
			// rules for real validation
			conf['strict'] = (elem.attr('data-bvStrict') == undefined ? '' : elem.attr('data-bvStrict'));

			return conf;
		},

		initInput: function(elem) {
			conf = this.getConfig(elem);

			conf['prepend'] = conf['prepend'].replace(/\\|\?/g,'');
			conf['append'] = conf['append'].replace(/\\|\?/g,'');
			if(!elem.val() || elem.val() == conf['empty'] || conf['newString'] == '') {
				if(conf['empty'] == '' && conf['switchVal'] == '') elem.val(conf['prepend']+conf['append']);
				else if(conf['switchVal'] == '') elem.val(conf['empty']);
				else elem.val(conf['switchVal']);
				//elem.addClass('grey');
			}
			else {
				if(conf['transform']) conf['newString'] = this.transform(conf['newString'], conf['transform']);
				elem.val(conf['prepend']+conf['newString']+conf['append']);
				//elem.removeClass('grey');
			}
			return conf;
		},

		focus: function(elem) {
			conf = this.getConfig(elem);

			if(elem.val() == conf['switchVal']) elem.val('');
			else elem.val($.trim(conf['newString']));
			//elem.removeClass('grey');
			//this.clean(elem);
		},

		isValid: function(value, rule) {

			var plugin = this;

			var result = false;

			var rulesOr = rule.split('|');

			//rulesAnd.each();

			$.each(rulesOr, function(indexOr, ruleOr) {

				var rulesAnd = ruleOr.split('&');

				var resultAnd = true;

				$.each(rulesAnd, function(indexAnd, ruleAnd) {

					var args = ruleAnd.split(':');

					if(!plugin.validations[args[0]].func(value, args)) {
						resultAnd = false;
						return;
					}

				});

				if(resultAnd == true) {
					result = true;
					return;
				}

				/*var args = ruleOr.split(':');

				if(plugin.validations[args[0]].func(value, args)) {
					result = true;
					return;
				}
				console.log(args);*/
				//console.log(val);

				//console.log(rulesAnd);

			});

			//console.log(rulesAnd);

			return result;

			if(rule.indexOf("\\|") != -1) {
				if(typeof this.validations[rule] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[rule].func(value);
			} else {
				var args = rule.split('|');
				if(typeof this.validations[args[0]] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[args[0]].func(value, args);
			}
		},

		validate: function(elem) {
			this.clean(elem);
			conf = this.initInput(elem);

			if(elem.is(':checkbox')) {
				if(elem.prop('checked')) return this.valid(elem);
				else return this.invalid(elem);
			}
			else if(this.isValid(conf['newString'], conf['strict'])) return this.valid(elem);
			else return this.invalid(elem);
		},

		validation: function() {
			this.validations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		transform: function(value, method) {
			return this.transformations[method].func(value);
		},

		transformation: function() {
			this.transformations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		clean: function(elem) {
			elem.removeClass('error').removeClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).removeClass('error').removeClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').removeClass('error').removeClass('valid');
			//elem.parents('.row').removeClass('error').removeClass('valid');
		},

		valid: function(elem) {
			elem.addClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('valid');

			//elem.parents('.row').addClass('valid');
			//elem.parents('.row').find('.error-message').addClass('hidden');
			return true;
		},

		invalid: function(elem) {
			elem.addClass('error');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('error');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('error');

			//elem.parents('.row').addClass('error');
			//elem.parents('.row').find('.error-message').removeClass('hidden');
			return false;
		}

	}

	$.fn.bValidator = function(options) {

		var settings = $.extend({
			beforeSubmit: function() {},
			onSubmitFail: function() {}
		}, options );

		return this.each(function() {
			if(typeof options == 'string') {
				switch(options) {
					case 'validate':
						return $.bValidator.validate(this);
						break;
					case 'isValid':
						return $.bValidator.isValid(this);
						break;
					}
			} else {
				$this = $(this);
				//if($this.is('form')) $.bValidator.init($this, settings);
				//else $.bValidator.init($this.find('form'), settings);

				if(!$this.is('form')) $this = $this.find('form');

				//console.log($this);

				return $this.each(function() {
					$.bValidator.init($(this), settings);
				});
			}
			//if (undefined == $(this).data('bValidator')) {
				//var plugin = new $.bValidator.init();
				//$(this).data('bValidator', plugin);
			//}
		});

	}

})(jQuery);

jQuery.bValidator
.validation('number', function(value, args) {
	valid = (value.match(/^[0-9]+$/) != null);
	if(!valid) return false;
	if(typeof args[1] != 'undefined') {
		intVal = parseInt(value);
		if(args[1] != '') {
			if(intVal < args[1]) return false;
		}
		if(typeof args[2] != 'undefined') {
			if(args[2] != '') {
				if(intVal > args[2]) return false;
			}
		}
	}
	return true;
})
.validation('same', function(value, args) {
	return (value == $('form [name="'+args[1]+'"]').val());
})
.validation('reg', function(value, args) {
	return (value.match(args[1]) != null);
})
.validation('string', function(value) {
	return (value.match(/^.+$/) != null);
})
.validation('email', function(value) {
	return (value.match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) != null && value.length != 0);
})
.validation('zip', function(value) {
	return (value.match(/^[0-9]{5}$/) != null);
})
.validation('city', function(value) {
	return (value.match(/^.{2,}$/) != null);
})
.validation('date-d.m.yy', function(value) {
	return (value.match(/^[0123]?[0-9]\.[01]?[0-9]\.[12][09][0-9][0-9]$/) != null);
})
.validation('nin', function(value) {
	return (value.match(/^[0-9]{6}\/[0-9]{3,4}$/) != null);
})
.validation('false', function(value) {
	return false;
})
.validation('true', function(value) {
	return true;
})
.validation('checkbox', function(value) {
	//console.log(value + 's');
	return true;
})
.validation('phone', function(value) {
	var same = 0;
	var inc = 0;
	var i;

	var pnumber = value;

	if(!pnumber.match(/^[0-9]{9}$/)) {
		return false;
	}

	for(i = 4;i < 9;i++) {
	if(i != 3 && pnumber.charAt(i) == pnumber.charAt(i - 1)) {
		same++;
	}
	if(parseInt(pnumber.charAt(i)) == (parseInt(pnumber.charAt(i - 1)) + 1) || (pnumber.charAt(i) == '0' && pnumber.charAt(i - 1) == '9')) {
		inc++;
	}
	}
	if(same >= 4 || inc >= 5) {
	return false;
	}
	return true;
})
.transformation('noSpaces', function(value) {
	return value.replace(/ /g,'');
});

//$('form.big').bValidator();<commit_msg>empty rule, destructor, isValid fix, rule escaping<commit_after>/*
TODO:
otestovat
royjet metodu valid
rozjet metodu validate
ukladat paramy do pameti uzlu??
pridat callbacky
checknout pravidla pro selecty a radia

custom classy
zmena DOMu
dogenerovani hlasek
error hlasky

definovani pravidel pro inputz pomoci trid
predani nastaveni inputu pomoci configu

destruktor
refresh
if:name:rule
if:name:value:rule
parser reg rename
*/

(function($) {

	$.bValidator = {

		defaults: {
		},

		validations: {},

		transformations: {},

		//settings: {},

		init: function(form, settings) {
			form.data('bValidator', settings);
			plugin = this;
			inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.each(function (){
				$(this).on('focusin.bValidator', function() {
					plugin.focus($(this));
				});

				$(this).on('focusout.bValidator', function() {
					plugin.validate($(this));
				});

				/*$(this).on('change.bValidator', function() {
					plugin.validate($(this));
				});*/

				plugin.initInput($(this));
			});

			//plugin.settings: $.extend({}, defaults, options);
			form.on('submit.bValidator', function(e) {
				var settings = $(this).data('bValidator');
				bValid = true;
				var inputs = $('input[data-bvString], input[data-bvStrict], textarea', $(this));

				inputs.each(function() {
					if(!plugin.validate($(this))) bValid = false;
				});

				if(!bValid) {
					settings.onSubmitFail.call( this, e );
					e.preventDefault();
				} else {
					inputs.each(function() {
						plugin.focus($(this));
					});
					//console.log(settings);
					settings.beforeSubmit.call( this, this, e );
				}
			});

		},

		getConfig: function(elem) {
			conf = {};
			// switch value - erase inputs with this value. Fill value of empty inputs on focus out
			conf['switchVal'] = (elem.attr('data-bvSwitch') == undefined ? '' : elem.attr('data-bvSwitch'));
			// prepended value
			conf['prepend'] = (elem.attr('data-bvPrepend') == undefined ? '' : elem.attr('data-bvPrepend'));
			// key string
			conf['string'] = (elem.attr('data-bvString') == undefined ? '.*' : elem.attr('data-bvString'));
			// appended value
			conf['append'] = (elem.attr('data-bvAppend') == undefined ? '' : elem.attr('data-bvAppend'));
			// string transformation
			conf['transform'] = (elem.attr('data-bvTransform') == undefined ? '' : elem.attr('data-bvTransform'));
			// pattern for regexp
			var pattern = '('+conf['prepend']+')?'+'('+conf['string']+')('+conf['append']+')?'+'';
			var re = new RegExp(pattern, 'i');
			// new string value
			conf['newString'] = elem.val().match(re)[2];
			// string which fill for empty inputs
			conf['empty'] = (elem.attr('data-bvEmpty') == undefined ? '' : elem.attr('data-bvEmpty'));
			// rules for real validation
			conf['strict'] = (elem.attr('data-bvStrict') == undefined ? '' : elem.attr('data-bvStrict'));

			return conf;
		},

		initInput: function(elem) {
			conf = this.getConfig(elem);

			conf['prepend'] = conf['prepend'].replace(/\\|\?/g,'');
			conf['append'] = conf['append'].replace(/\\|\?/g,'');
			if(!elem.val() || elem.val() == conf['empty'] || conf['newString'] == '') {
				if(conf['empty'] == '' && conf['switchVal'] == '') elem.val(conf['prepend']+conf['append']);
				else if(conf['switchVal'] == '') elem.val(conf['empty']);
				else elem.val(conf['switchVal']);
				//elem.addClass('grey');
			}
			else {
				if(conf['transform']) conf['newString'] = this.transform(conf['newString'], conf['transform']);
				elem.val(conf['prepend']+conf['newString']+conf['append']);
				//elem.removeClass('grey');
			}
			return conf;
		},

		focus: function(elem) {
			conf = this.getConfig(elem);

			if(elem.val() == conf['switchVal']) elem.val('');
			else elem.val($.trim(conf['newString']));
			//elem.removeClass('grey');
			//this.clean(elem);
		},

		isValid: function(value, rule) {

			if(typeof rule === 'undefined') {
				var elem = value;
				var conf = this.initInput(elem);
				var value = conf['newString'];
				var rule = conf['strict'];
			}

			var plugin = this;

			var result = false;

			var ruleEscaped = rule.replace(/({{((?!}}).)*}})/g, '{{NOPARSE}}');

			var ruleReplacements = rule.match(/({{((?!}}).)*}})/g);

			var rulesOr = ruleEscaped.split('|');

			//rulesAnd.each();

			$.each(rulesOr, function(indexOr, ruleOr) {

				var rulesAnd = ruleOr.split('&');

				var resultAnd = true;

				$.each(rulesAnd, function(indexAnd, ruleAnd) {

					var args = ruleAnd.split(':');

					for (var i = 0; i < args.length; i++) {
						if(args[i].match(/\{\{NOPARSE\}\}/) !== null) {
							var replacement = ruleReplacements.shift();
							args[i] = args[i].replace('{{NOPARSE}}', replacement.slice(2, -2));
						}
					};

					//console.log(args);

					/*if(typeof this.validations[rule] === 'undefined') {
						if(value.match(rule) == null) {
							resultAnd = false;
							return;
						}
					} else {*/
						//console.log(args);

						if(!plugin.validations[args[0]].func(value, args)) {
							resultAnd = false;
							return;
						}
					//}

				});

				if(resultAnd == true) {
					result = true;
					return;
				}

				/*var args = ruleOr.split(':');

				if(plugin.validations[args[0]].func(value, args)) {
					result = true;
					return;
				}
				console.log(args);*/
				//console.log(val);

				//console.log(rulesAnd);

			});

			//console.log(rulesAnd);

			return result;

			/*if(rule.indexOf("\\|") != -1) {
				if(typeof this.validations[rule] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[rule].func(value);
			} else {
				var args = rule.split('|');
				if(typeof this.validations[args[0]] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[args[0]].func(value, args);
			}*/
		},

		validate: function(elem) {
			this.clean(elem);
			conf = this.initInput(elem);

			if(elem.is(':checkbox')) {
				if(elem.prop('checked')) return this.valid(elem);
				else return this.invalid(elem);
			}
			else if(this.isValid(conf['newString'], conf['strict'])) return this.valid(elem);
			else return this.invalid(elem);
		},

		validation: function() {
			this.validations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		transform: function(value, method) {
			return this.transformations[method].func(value);
		},

		transformation: function() {
			this.transformations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		clean: function(elem) {
			elem.removeClass('error').removeClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).removeClass('error').removeClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').removeClass('error').removeClass('valid');
			//elem.parents('.row').removeClass('error').removeClass('valid');
		},

		valid: function(elem) {
			elem.addClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('valid');

			//elem.parents('.row').addClass('valid');
			//elem.parents('.row').find('.error-message').addClass('hidden');
			return true;
		},

		invalid: function(elem) {
			elem.addClass('error');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('error');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('error');

			//elem.parents('.row').addClass('error');
			//elem.parents('.row').find('.error-message').removeClass('hidden');
			return false;
		},

		destruct: function(form) {
			form.unbind('.bValidator');
		}

	}

	$.fn.bValidator = function(options) {

		if(typeof options == 'string' && options == 'isValid') {
			var valid = true;
			this.each(function() {
				if(!$.bValidator.isValid($(this))) {
					valid =  false;
					return;
				}
			});
			return valid;
		}

		var settings = $.extend({
			beforeSubmit: function() {},
			onSubmitFail: function() {}
		}, options );

		return this.each(function() {
			if(typeof options == 'string') {
				switch(options) {
					case 'validate':
						return $.bValidator.validate($(this));
						break;
					case 'destruct':
						return $.bValidator.destruct($(this));
						break;
					}
			} else {
				$this = $(this);
				//if($this.is('form')) $.bValidator.init($this, settings);
				//else $.bValidator.init($this.find('form'), settings);

				if(!$this.is('form')) $this = $this.find('form');

				return $this.each(function() {
					$.bValidator.init($(this), settings);
				});
			}
			//if (undefined == $(this).data('bValidator')) {
				//var plugin = new $.bValidator.init();
				//$(this).data('bValidator', plugin);
			//}
		});

	}

})(jQuery);

jQuery.bValidator
.validation('number', function(value, args) {
	valid = (value.match(/^[0-9]+$/) != null);
	if(!valid) return false;
	if(typeof args[1] != 'undefined') {
		intVal = parseInt(value);
		if(args[1] != '') {
			if(intVal < args[1]) return false;
		}
		if(typeof args[2] != 'undefined') {
			if(args[2] != '') {
				if(intVal > args[2]) return false;
			}
		}
	}
	return true;
})
.validation('empty', function(value) {
	return (value == '');
})
.validation('same', function(value, args) {
	return (value == $('form [name="'+args[1]+'"]').val());
})
.validation('reg', function(value, args) {
	return (value.match(args[1]) != null);
})
.validation('string', function(value) {
	return (value.match(/^.+$/) != null);
})
.validation('email', function(value) {
	return (value.match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) != null && value.length != 0);
})
.validation('zip', function(value) {
	return (value.match(/^[0-9]{5}$/) != null);
})
.validation('city', function(value) {
	return (value.match(/^.{2,}$/) != null);
})
.validation('date-d.m.yy', function(value) {
	return (value.match(/^[0123]?[0-9]\.[01]?[0-9]\.[12][09][0-9][0-9]$/) != null);
})
.validation('nin', function(value) {
	return (value.match(/^[0-9]{6}\/[0-9]{3,4}$/) != null);
})
.validation('false', function(value) {
	return false;
})
.validation('true', function(value) {
	return true;
})
.validation('checkbox', function(value) {
	return true;
})
.validation('phone', function(value) {
	var same = 0;
	var inc = 0;
	var i;

	var pnumber = value;

	if(!pnumber.match(/^[0-9]{9}$/)) {
		return false;
	}

	for(i = 4;i < 9;i++) {
	if(i != 3 && pnumber.charAt(i) == pnumber.charAt(i - 1)) {
		same++;
	}
	if(parseInt(pnumber.charAt(i)) == (parseInt(pnumber.charAt(i - 1)) + 1) || (pnumber.charAt(i) == '0' && pnumber.charAt(i - 1) == '9')) {
		inc++;
	}
	}
	if(same >= 4 || inc >= 5) {
	return false;
	}
	return true;
})
.transformation('noSpaces', function(value) {
	return value.replace(/ /g,'');
});<|endoftext|>


<commit_before>/**
 * node
 * nodejs,是一个可以让javascript运行在服务器端的平台。它可以让javascript脱离浏览器的束缚运行在一般的服务器环境下。
 */
/**
 * Node.js的优点
 * nodejs作为一个新兴的后台语言，有很多吸引人的地方：
 * RESTful API
 * 单线程
 * Node.js可以在不新增额外线程的情况下，依然可以对任务进行并行处理 —— Node.js是单线程的。它通过事件轮询（event loop）来实现并行操作，对此，我们应该要充分利用这一点 —— 尽可能的避免阻塞操作，取而代之，多使用非阻塞操作。
 * 非阻塞IO
 * V8虚拟机
 * 事件驱动
 */

/**
 * [node 第一个小程序]
 */
var http = require('http');
server = http.createServer(function (req, res) {
	res.writeHeader(200, {"Content-Type": "text/plain"});
	res.end("Hello World\n");
});
server.listen(8000);
console.log("httpd start @8000");

/**
 * CommonJS规范
 * commonjs是服务器模块的规范，node.js采用了这个规范
 * 根据CommonJS规范，一个单独的文件就是一个模块。加载模块使用require方法，该方法读取一个文件并执行，最后返回文件内部的exports对象。
 * js文件名前面需要加上路径，可以是相对路径（相对于使用require方法的文件），也可以是绝对路径。如果省略路径，node.js会认为，你要加载一个核心模块，或者已经安装在本地 node_modules 目录中的模块。如果加载的是一个目录，node.js会首先寻找该目录中的 package.json 文件，加载该文件 main 属性提到的模块，否则就寻找该目录下的 index.js 文件。
下面的例子是使用一行语句，定义一个最简单的模块。
 */
//addition.js
exports.do = function(a, b){
	return a + b;
}

var add = require('./addition');
add.do(1,2)  //3

/**
 * 同步与异步
 * 从调用方式上，可以把他们分为三类：同步调用、回调和异步调用。
 * 同步调用是一种阻塞式调用，调用方要等待对方执行完毕才返回，它是一种单向调用；回调是一种双向调用模式，也就是说，被调用方在接口被调用时也会调用对方的接口；
 * 异步调用是一种类似消息或事件的机制，不过它的调用方向刚好相反，接口的服务在收到某种讯息或发生某种事件时，会主动通知客户方（即调用客户方的接口）。
 */

 // readFileSync是同步方法，会阻塞直到得到结果后，才继续执行之后的语句。
var fs = require("fs");
var data = fs.readFileSync("new.txt");
console.log(data.toString());

//会发现 console.log(“first me run”) 先执行。 因为callback是回调函数，等到底层读取完数据后，会调用该函数
var fs = require("fs");
fs.readFile("new.txt", function callback(err, data){
	console.log(data.toString());
})
console.log("first me run");

//node中回调函数的规范是：
function callback(err, args0, args1 ...){}

//模拟一个异步函数，和回调函数，加深理解
function sumAsync(a,b,callback){
    setTimeout(function(){
        if(typeof a === "number" && typeof a === "number"){
            callback(null,a+b);
        }else{
            callback(new Error("must number"));
        }
    },200)
}

sumAsync(2,3,function callback(err,rs){
    console.log(rs);
})

console.log("first run !");
//我们定义一个 sumAsync 异步函数，运行后，会先执行 console.log("first run !");  ，根据这个实例，应对异步函数、回调概念已理解。在Node.js 的实际开发中，I/O操作都应该调用异步函数，这样才能发挥更好的性能，但回调函数的嵌套很丑，为了解决这个问题，之后的几节中，会介绍 Promises 的Q库 和 ES6 generator 及 co 库，通过这几个工具即能发挥Node.js高性能，又可让代码更好维护、更可控和更好的可读性。

/**
 * Promise 模式的Q库
 * Promise是一种让异步代码书写起来更舒服、更可控、优雅的模式，能够让异步操作代码像同步代码那样书写并且阅读。
 * Q库可运行中node.js环境下，它是Promise模式的实现，下面我们来介绍它。
 * 通过 npm i q 安装Q库
 */
//采用回调函数方式编写：
var fs = require("fs");
fs.readdir(".",function(err,rs){
    fs.readFile(rs[0],function(err,f1){
        console.log(f1);
        fs.readFile(rs[1],function(err,f2){
            console.log(f2);
            fs.readFile(rs[2],function(err,f3){
                console.log(f3);
            })
        })
    })
})
//这段代码的意思是，查看当前目录下有多少文件，然后逐个读取，把读取的数据打印到终端，可笑的是，你还必须要知道到底有几个文件，如果我知道有3个，就调用三次 readFile异步函数，如果1000个，那就要......

//通过Q库改善
// 导入q库
var Q = require("q"),fs = require("fs");

Q.nfcall(fs.readdir, ".").then(function(ns){

    var promises = [];

    ns.forEach(function(filename){
        promises.push(Q.nfcall(fs.readFile, filename,"utf8"));
    })

    Q.all(promises).then(function(results){
        console.log(results);
    })

})
//通过Q.nfcall 方法调用异步函数，返回一个 promise对象，promise对象具有一个方法 then ，可以得到运行结果。
//这里的 var promises = []; 变量用于储存promise数组，把这个参数加入Q.all 方法里，会得到一个promise对象，调用then方法会得到一个数组，这个数组就是所有promises的运行结果。
//一切都围绕promise对象，它有一个then方法用于返回回调函数结果，还有一个 fail  函数，用于返回异常对象，then 和 fail 不会同时被调用，就好比一个普通函数，如果抛出异常就不会有返回值一样。
//修改之前代码
var Q = require("q"),fs = require("fs");
Q.nfcall(fs.readdir, "no path")
.then(function(ns){
    var promises = [];
    ns.forEach(function(filename){
        promises.push(Q.nfcall(fs.readFile, filename,"utf8"));
    })
    Q.all(promises).then(function(results){
        console.log(results);
    })
})
.fail(function(err){
    console.log(err);
})
//说明调用的是 fail函数，而不是then，说明 then 代表无异常情况下的返回值，fail表示抛出的异常，如果过程中有任何异常，promise.then 的函数都不会被调用，而是会调用fail，表示抛出异常。

/**
 * generator
 * 运行generator代码需要Node.js version > 0.11.3，在运行时，使用 node --harmony xx.js  方式运行。*
 * 在 ES6 规范中，定义一个生成器函数，在 function 后跟上
 * 调用生成器函数会产生一个生成器（generator）对象。生成器拥有的最重要的方法是 next()，用来迭代：
 */
function* gf() { };
function *gf() { };
function * gf() { };

/**
 * go库用于优化异步函数调用方式，支持promise和thunks方式。
 * 安装 npm i co thunkify
 * thunkify 库是对异步函数的再次封装，符合co规范。
 *
 */

/**
 * 下面用co库实现任意文件数：
 */
var fs = require("fs");
var co = require("co");
var thunkify = require("thunkify");

// 包装异步函数，让其符合co规范。
var readdir = thunkify(fs.readdir);
var readFile = thunkify(fs.readFile);

co(function *(){

    // 得到当前目录下的文件名列表
    var fns = yield readdir(".");

    for(var i=0,len = fns.length;i<len;i++){
        var rs= yield readFile(fns[i]);
        console.log(rs);
    }

})();
//我们会发现，co使用很简单， 只要用thunkify转换普通的异步函数，之后和同步调用基本一致。
//下面我们自己编写一个，模拟异步的函数，并用co执行。
var co = require("co");
var thunkify = require("thunkify");

function fun(time,callback){
    setTimeout(function(){
        callback(null,"setTimeout time is - "+time);
    },time)
}

var func = thunkify(fun);

co(function* (){

    console.log(yield func(2000));
    console.log(yield func(1000));
    console.log(yield func(500));

})()

<commit_msg>node 流 简介<commit_after>/**
 * node
 * nodejs,是一个可以让javascript运行在服务器端的平台。它可以让javascript脱离浏览器的束缚运行在一般的服务器环境下。
 */
/**
 * Node.js的优点
 * nodejs作为一个新兴的后台语言，有很多吸引人的地方：
 * RESTful API
 * 单线程
 * Node.js可以在不新增额外线程的情况下，依然可以对任务进行并行处理 —— Node.js是单线程的。它通过事件轮询（event loop）来实现并行操作，对此，我们应该要充分利用这一点 —— 尽可能的避免阻塞操作，取而代之，多使用非阻塞操作。
 * 非阻塞IO
 * V8虚拟机
 * 事件驱动
 */

/**
 * [node 第一个小程序]
 */
var http = require('http');
server = http.createServer(function (req, res) {
	res.writeHeader(200, {"Content-Type": "text/plain"});
	res.end("Hello World\n");
});
server.listen(8000);
console.log("httpd start @8000");

/**
 * CommonJS规范
 * commonjs是服务器模块的规范，node.js采用了这个规范
 * 根据CommonJS规范，一个单独的文件就是一个模块。加载模块使用require方法，该方法读取一个文件并执行，最后返回文件内部的exports对象。
 * js文件名前面需要加上路径，可以是相对路径（相对于使用require方法的文件），也可以是绝对路径。如果省略路径，node.js会认为，你要加载一个核心模块，或者已经安装在本地 node_modules 目录中的模块。如果加载的是一个目录，node.js会首先寻找该目录中的 package.json 文件，加载该文件 main 属性提到的模块，否则就寻找该目录下的 index.js 文件。
下面的例子是使用一行语句，定义一个最简单的模块。
 */
//addition.js
exports.do = function(a, b){
	return a + b;
}

var add = require('./addition');
add.do(1,2)  //3

/**
 * 同步与异步
 * 从调用方式上，可以把他们分为三类：同步调用、回调和异步调用。
 * 同步调用是一种阻塞式调用，调用方要等待对方执行完毕才返回，它是一种单向调用；回调是一种双向调用模式，也就是说，被调用方在接口被调用时也会调用对方的接口；
 * 异步调用是一种类似消息或事件的机制，不过它的调用方向刚好相反，接口的服务在收到某种讯息或发生某种事件时，会主动通知客户方（即调用客户方的接口）。
 */

 // readFileSync是同步方法，会阻塞直到得到结果后，才继续执行之后的语句。
var fs = require("fs");
var data = fs.readFileSync("new.txt");
console.log(data.toString());

//会发现 console.log(“first me run”) 先执行。 因为callback是回调函数，等到底层读取完数据后，会调用该函数
var fs = require("fs");
fs.readFile("new.txt", function callback(err, data){
	console.log(data.toString());
})
console.log("first me run");

//node中回调函数的规范是：
function callback(err, args0, args1 ...){}

//模拟一个异步函数，和回调函数，加深理解
function sumAsync(a,b,callback){
    setTimeout(function(){
        if(typeof a === "number" && typeof a === "number"){
            callback(null,a+b);
        }else{
            callback(new Error("must number"));
        }
    },200)
}

sumAsync(2,3,function callback(err,rs){
    console.log(rs);
})

console.log("first run !");
//我们定义一个 sumAsync 异步函数，运行后，会先执行 console.log("first run !");  ，根据这个实例，应对异步函数、回调概念已理解。在Node.js 的实际开发中，I/O操作都应该调用异步函数，这样才能发挥更好的性能，但回调函数的嵌套很丑，为了解决这个问题，之后的几节中，会介绍 Promises 的Q库 和 ES6 generator 及 co 库，通过这几个工具即能发挥Node.js高性能，又可让代码更好维护、更可控和更好的可读性。

/**
 * Promise 模式的Q库
 * Promise是一种让异步代码书写起来更舒服、更可控、优雅的模式，能够让异步操作代码像同步代码那样书写并且阅读。
 * Q库可运行中node.js环境下，它是Promise模式的实现，下面我们来介绍它。
 * 通过 npm i q 安装Q库
 */
//采用回调函数方式编写：
var fs = require("fs");
fs.readdir(".",function(err,rs){
    fs.readFile(rs[0],function(err,f1){
        console.log(f1);
        fs.readFile(rs[1],function(err,f2){
            console.log(f2);
            fs.readFile(rs[2],function(err,f3){
                console.log(f3);
            })
        })
    })
})
//这段代码的意思是，查看当前目录下有多少文件，然后逐个读取，把读取的数据打印到终端，可笑的是，你还必须要知道到底有几个文件，如果我知道有3个，就调用三次 readFile异步函数，如果1000个，那就要......

//通过Q库改善
// 导入q库
var Q = require("q"),fs = require("fs");

Q.nfcall(fs.readdir, ".").then(function(ns){

    var promises = [];

    ns.forEach(function(filename){
        promises.push(Q.nfcall(fs.readFile, filename,"utf8"));
    })

    Q.all(promises).then(function(results){
        console.log(results);
    })

})
//通过Q.nfcall 方法调用异步函数，返回一个 promise对象，promise对象具有一个方法 then ，可以得到运行结果。
//这里的 var promises = []; 变量用于储存promise数组，把这个参数加入Q.all 方法里，会得到一个promise对象，调用then方法会得到一个数组，这个数组就是所有promises的运行结果。
//一切都围绕promise对象，它有一个then方法用于返回回调函数结果，还有一个 fail  函数，用于返回异常对象，then 和 fail 不会同时被调用，就好比一个普通函数，如果抛出异常就不会有返回值一样。
//修改之前代码
var Q = require("q"),fs = require("fs");
Q.nfcall(fs.readdir, "no path")
.then(function(ns){
    var promises = [];
    ns.forEach(function(filename){
        promises.push(Q.nfcall(fs.readFile, filename,"utf8"));
    })
    Q.all(promises).then(function(results){
        console.log(results);
    })
})
.fail(function(err){
    console.log(err);
})
//说明调用的是 fail函数，而不是then，说明 then 代表无异常情况下的返回值，fail表示抛出的异常，如果过程中有任何异常，promise.then 的函数都不会被调用，而是会调用fail，表示抛出异常。

/**
 * generator
 * 运行generator代码需要Node.js version > 0.11.3，在运行时，使用 node --harmony xx.js  方式运行。*
 * 在 ES6 规范中，定义一个生成器函数，在 function 后跟上
 * 调用生成器函数会产生一个生成器（generator）对象。生成器拥有的最重要的方法是 next()，用来迭代：
 */
function* gf() { };
function *gf() { };
function * gf() { };

/**
 * go库用于优化异步函数调用方式，支持promise和thunks方式。
 * 安装 npm i co thunkify
 * thunkify 库是对异步函数的再次封装，符合co规范。
 *
 */

/**
 * 下面用co库实现任意文件数：
 */
var fs = require("fs");
var co = require("co");
var thunkify = require("thunkify");

// 包装异步函数，让其符合co规范。
var readdir = thunkify(fs.readdir);
var readFile = thunkify(fs.readFile);

co(function *(){

    // 得到当前目录下的文件名列表
    var fns = yield readdir(".");

    for(var i=0,len = fns.length;i<len;i++){
        var rs= yield readFile(fns[i]);
        console.log(rs);
    }

})();
//我们会发现，co使用很简单， 只要用thunkify转换普通的异步函数，之后和同步调用基本一致。
//下面我们自己编写一个，模拟异步的函数，并用co执行。
var co = require("co");
var thunkify = require("thunkify");

function fun(time,callback){
    setTimeout(function(){
        callback(null,"setTimeout time is - "+time);
    },time)
}

var func = thunkify(fun);

co(function* (){

    console.log(yield func(2000));
    console.log(yield func(1000));
    console.log(yield func(500));

})()

/**
 * 流
 * 这部分的内容并不实用，这是真的，我们不太可能去自己实现流子类，而是去使用流的子类，比如 fs 、net、http等IO相关的模块就是流的子类，这部分内容又很重要。通过对流理解，在使用具体子类时才能得心应手。
 * 在Node.js中，通过.pipe() 方法连接上下游，把上游数据导入下游。
 * 什么时候应该使用流？
 * 	下面的例子，是当客户请求服务器资源，服务器会读取data.txt文件到内存，然后把数据再推倒客户端，如果文件很大，就会占用很多内存。更糟的是，如果高并发，性能会更差。
 * 	pipe方法，内部通过监听 stream 的data和end时间，把接收到的文件块第一时间到客户端，节省内存。
 * 	流的类别
 * 		在Node.js中，流分4种类别： readable可读流, writable可写流, transform转换流, duplex双工流。
 * 	pipe管道方法：
 * 		无论哪种流，都可通过pipe方法进行连接。pipe只是个函数，它接受一个可读的流作为输入源，和一个输出源的写入流。
 * 		src.pipe(target)
 * 		.pipe(target)返回target，所以可以多次调用pipe方法
 * 		如：a.pipe(b).pipe(c).pipe(d)
 *
 */
var http = require('http');
var fs = require('fs');

var server = http.createServer(function (req, res) {
    fs.readFile(__dirname + '/data.txt', function (err, data) {
        res.end(data);
    });
});
server.listen(3000);

/*
流可以解决这个问题，把文件流和响应流通过pipe连起来，这样上游的数据就会“缓缓的”流道客户端，不会出现大量内存被消耗的情况。在这里，用fs.createReadStream方法代替fs.readFile方法。
 */
var http = require('http');
var fs = require('fs');

var server = http.createServer(function (req, res) {
    var stream = fs.createReadStream(__dirname + '/data.txt');
    stream.pipe(res);
});
server.listen(3000);

<|endoftext|>


<commit_before>
'use strict';

const electron = require('electron');
const ipc = electron.ipcRenderer;

const state = document.querySelector('.pick-a-player');
const debug = require('../debug.js');

/**
 * init - Initialize the page handler, ataching the state manager and discovering any interactive elements
 *
 * @param  {object} stateManager the state-manager for this state to send instructions to
 */
function init(stateManager) {
  if (!stateManager) {
    throw new Error('no state-manager given');
  }

  module.exports.internal.stateManager = stateManager;

  module.exports.internal.playerAddButton = document.getElementById('button_pick-a-player_add');
  module.exports.internal.playerName = document.getElementById('input_pick-a-player');
  module.exports.internal.playerList = document.getElementById('pick-a-player_list');
  module.exports.internal.breadcrumb = document.getElementById('pick-a-player_breadcrumbs');

  module.exports.internal.playerAddButton.onclick = module.exports.internal.playerAddOnClick;
  module.exports.internal.playerName.oninput = module.exports.internal.playerNameOnInput;
}

/**
 * playerAddOnClick -A click handler for when the "add player" button is clicked.  This only
 * acts if the player name text value contains more than 0 characters.  The team data is saved
 * and the player list updated when this is clicked
 *
 * @private
 */
function playerAddOnClick() {
  if (module.exports.internal.playerName.value.length > 0) {
    let player = {
      id: module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].players.length + 1,
      name: module.exports.internal.playerName.value
    };
    module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].players.push(player);

    debug('adding player ' + JSON.stringify(player));
    ipc.send('save-team-data', module.exports.internal.filename, module.exports.internal.dataObj);
  }
}

/**
 * playerNameOnInput - An on-input handler for the player name text field.  This greys out the
 * "add" button when there is no text in the player name.
 *
 * @private
 */
function playerNameOnInput() {
  if (module.exports.internal.playerName.value.length === 0) {
    module.exports.internal.playerAddButton.className = 'button new-item-button-disabled';
  } else {
    module.exports.internal.playerAddButton.className = 'button new-item-button';
  }
}

/**
 * teamDataSavedListener - React to team data being saved, by reloading team data
 *
 * @private
 */
function teamDataSavedListener() {
  debug('team data saved, reloading team data');
  ipc.send('get-team-data');
}

/**
 * teamPlayerStoredListener - Reacts to the player selector being stored, then loads the player stats state.
 *
 * @private
 */
function teamPlayerStoredListener() {
  module.exports.internal.stateManager.showState('pick-a-player', 'player-stats');
}

/**
 * returnTeamDataListener - React to a request to get the known team data.  Populate the player list.
 * If the number of players is 6 or more then enable the done button.
 *
 * @param  {object} event    IPC Event
 * @param  {string} filename the filename that was loaded
 * @param  {object} dataObj  the team data
 * @param  {number} seasonId the currently selected season
 *
 * @private
 */

function returnTeamDataListener(event, filename, dataObj, seasonId) {
  debug('team data loaded - seasonId ' + seasonId);
  module.exports.internal.dataObj = dataObj;
  module.exports.internal.filename = filename;
  module.exports.internal.seasonId = seasonId;

  // Clean up the input text box
  module.exports.internal.playerName.value = '';
  playerNameOnInput();

  // generate the breadcrumb
  module.exports.internal.generateBreadcrumb();

  // Clean up the list div
  let clonePlayerList = module.exports.internal.playerList.cloneNode(false);
  module.exports.internal.playerList.parentNode.replaceChild(clonePlayerList, module.exports.internal.playerList);
  module.exports.internal.playerList = clonePlayerList;

  if (dataObj.seasons[seasonId].players) {
    dataObj.seasons[seasonId].players.forEach((player) => {
      let span = document.createElement('span');
      span.innerHTML = player.name;
      span.className = 'list-item';
      span.onclick = () => {ipc.send('store-team-player', player.id);};
      module.exports.internal.playerList.appendChild(span);
    });
  }

  // Scroll to the bottom of the list
  module.exports.internal.playerList.scrollTop = module.exports.internal.playerList.scrollHeight;
}

/**
 * generateBreadcrumb - Generate the breadcrumb for this page:
 *  Home > $TeamName > $SeasonName
 *
 * Home links back to pick a team.
 * $TeamName links back to pick a season
 *
 * @private
 */
function generateBreadcrumb() {
  let cloneBreadcrumb = module.exports.internal.breadcrumb.cloneNode(false);
  module.exports.internal.breadcrumb.parentNode.replaceChild(cloneBreadcrumb, module.exports.internal.breadcrumb);
  module.exports.internal.breadcrumb = cloneBreadcrumb;

  let spanHome = document.createElement('span');
  spanHome.innerHTML = 'Home';
  spanHome.className = 'link';
  spanHome.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'pick-a-team');};
  module.exports.internal.breadcrumb.appendChild(spanHome);

  let spanSep1 = document.createElement('span');
  spanSep1.innerHTML = ' > ';
  module.exports.internal.breadcrumb.appendChild(spanSep1);

  let spanTeam = document.createElement('span');
  spanTeam.innerHTML = module.exports.internal.dataObj.name;
  spanTeam.className = 'link';
  spanTeam.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'pick-a-season');};
  module.exports.internal.breadcrumb.appendChild(spanTeam);

  let spanSep2 = document.createElement('span');
  spanSep2.innerHTML = ' > ';
  module.exports.internal.breadcrumb.appendChild(spanSep2);

  let spanSeason = document.createElement('span');
  spanSeason.innerHTML = module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].name;
  spanSeason.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'main-branch');};
  module.exports.internal.breadcrumb.appendChild(spanSeason);
}

/**
 * attach - Set up any event handlers
 */
function attach() {
  debug('attaching add-first-squad');
  ipc.on('team-data-saved', module.exports.internal.teamDataSavedListener);
  ipc.on('return-team-data', module.exports.internal.returnTeamDataListener);
  ipc.on('team-player-stored', module.exports.internal.teamPlayerStoredListener);
  ipc.send('get-team-data');
}

/**
 * detach - Clean up any event handlers
 */
function detach() {
  debug('detaching add-first-squad');
  ipc.removeListener('team-data-saved', module.exports.internal.teamDataSavedListener);
  ipc.removeListener('return-team-data', module.exports.internal.returnTeamDataListener);
  ipc.removeListener('team-player-stored', module.exports.internal.teamPlayerStoredListener);
}

module.exports = {
  name: 'pick-a-player',
  state: state,
  init: init,
  attach: attach,
  detach: detach,
  internal: {
    teamDataSavedListener: teamDataSavedListener,
    returnTeamDataListener: returnTeamDataListener,
    teamPlayerStoredListener: teamPlayerStoredListener,
    playerAddOnClick: playerAddOnClick,
    playerNameOnInput: playerNameOnInput,
    generateBreadcrumb: generateBreadcrumb,
    stateManager: undefined,
    playerAddButton: undefined,
    playerName: undefined,
    playerList: undefined,
    breadcrumb: undefined,
    filename: undefined,
    dataObj: undefined,
    seasonId: undefined
  }
};
<commit_msg>minor style fix<commit_after>
'use strict';

const electron = require('electron');
const ipc = electron.ipcRenderer;

const state = document.querySelector('.pick-a-player');
const debug = require('../debug.js');

/**
 * init - Initialize the page handler, ataching the state manager and discovering any interactive elements
 *
 * @param  {object} stateManager the state-manager for this state to send instructions to
 */
function init(stateManager) {
  if (!stateManager) {
    throw new Error('no state-manager given');
  }

  module.exports.internal.stateManager = stateManager;

  module.exports.internal.playerAddButton = document.getElementById('button_pick-a-player_add');
  module.exports.internal.playerName = document.getElementById('input_pick-a-player');
  module.exports.internal.playerList = document.getElementById('pick-a-player_list');
  module.exports.internal.breadcrumb = document.getElementById('pick-a-player_breadcrumbs');

  module.exports.internal.playerAddButton.onclick = module.exports.internal.playerAddOnClick;
  module.exports.internal.playerName.oninput = module.exports.internal.playerNameOnInput;
}

/**
 * playerAddOnClick -A click handler for when the "add player" button is clicked.  This only
 * acts if the player name text value contains more than 0 characters.  The team data is saved
 * and the player list updated when this is clicked
 *
 * @private
 */
function playerAddOnClick() {
  if (module.exports.internal.playerName.value.length > 0) {
    let player = {
      id: module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].players.length + 1,
      name: module.exports.internal.playerName.value
    };
    module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].players.push(player);

    debug('adding player ' + JSON.stringify(player));
    ipc.send('save-team-data', module.exports.internal.filename, module.exports.internal.dataObj);
  }
}

/**
 * playerNameOnInput - An on-input handler for the player name text field.  This greys out the
 * "add" button when there is no text in the player name.
 *
 * @private
 */
function playerNameOnInput() {
  if (module.exports.internal.playerName.value.length === 0) {
    module.exports.internal.playerAddButton.className = 'button new-item-button-disabled';
  } else {
    module.exports.internal.playerAddButton.className = 'button new-item-button';
  }
}

/**
 * teamDataSavedListener - React to team data being saved, by reloading team data
 *
 * @private
 */
function teamDataSavedListener() {
  debug('team data saved, reloading team data');
  ipc.send('get-team-data');
}

/**
 * teamPlayerStoredListener - Reacts to the player selector being stored, then loads the player stats state.
 *
 * @private
 */
function teamPlayerStoredListener() {
  module.exports.internal.stateManager.showState('pick-a-player', 'player-stats');
}

/**
 * returnTeamDataListener - React to a request to get the known team data.  Populate the player list.
 * If the number of players is 6 or more then enable the done button.
 *
 * @param  {object} event    IPC Event
 * @param  {string} filename the filename that was loaded
 * @param  {object} dataObj  the team data
 * @param  {number} seasonId the currently selected season
 *
 * @private
 */

function returnTeamDataListener(event, filename, dataObj, seasonId) {
  debug('team data loaded - seasonId ' + seasonId);
  module.exports.internal.dataObj = dataObj;
  module.exports.internal.filename = filename;
  module.exports.internal.seasonId = seasonId;

  // Clean up the input text box
  module.exports.internal.playerName.value = '';
  playerNameOnInput();

  // generate the breadcrumb
  module.exports.internal.generateBreadcrumb();

  // Clean up the list div
  let clonePlayerList = module.exports.internal.playerList.cloneNode(false);
  module.exports.internal.playerList.parentNode.replaceChild(clonePlayerList, module.exports.internal.playerList);
  module.exports.internal.playerList = clonePlayerList;

  if (dataObj.seasons[seasonId].players) {
    dataObj.seasons[seasonId].players.forEach((player) => {
      let span = document.createElement('span');
      span.innerHTML = player.name;
      span.className = 'list-item';
      span.onclick = () => {ipc.send('store-team-player', player.id);};
      module.exports.internal.playerList.appendChild(span);
    });
  }

  // Scroll to the bottom of the list
  module.exports.internal.playerList.scrollTop = module.exports.internal.playerList.scrollHeight;
}

/**
 * generateBreadcrumb - Generate the breadcrumb for this page:
 *  Home > $TeamName > $SeasonName
 *
 * Home links back to pick a team.
 * $TeamName links back to pick a season
 *
 * @private
 */
function generateBreadcrumb() {
  let cloneBreadcrumb = module.exports.internal.breadcrumb.cloneNode(false);
  module.exports.internal.breadcrumb.parentNode.replaceChild(cloneBreadcrumb, module.exports.internal.breadcrumb);
  module.exports.internal.breadcrumb = cloneBreadcrumb;

  let spanHome = document.createElement('span');
  spanHome.innerHTML = 'Home';
  spanHome.className = 'link';
  spanHome.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'pick-a-team');};
  module.exports.internal.breadcrumb.appendChild(spanHome);

  let spanSep1 = document.createElement('span');
  spanSep1.innerHTML = ' > ';
  module.exports.internal.breadcrumb.appendChild(spanSep1);

  let spanTeam = document.createElement('span');
  spanTeam.innerHTML = module.exports.internal.dataObj.name;
  spanTeam.className = 'link';
  spanTeam.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'pick-a-season');};
  module.exports.internal.breadcrumb.appendChild(spanTeam);

  let spanSep2 = document.createElement('span');
  spanSep2.innerHTML = ' > ';
  module.exports.internal.breadcrumb.appendChild(spanSep2);

  let spanSeason = document.createElement('span');
  spanSeason.innerHTML = module.exports.internal.dataObj.seasons[module.exports.internal.seasonId].name;
  spanSeason.className = 'link';
  spanSeason.onclick = () => {module.exports.internal.stateManager.showState('pick-a-player', 'main-branch');};
  module.exports.internal.breadcrumb.appendChild(spanSeason);
}

/**
 * attach - Set up any event handlers
 */
function attach() {
  debug('attaching add-first-squad');
  ipc.on('team-data-saved', module.exports.internal.teamDataSavedListener);
  ipc.on('return-team-data', module.exports.internal.returnTeamDataListener);
  ipc.on('team-player-stored', module.exports.internal.teamPlayerStoredListener);
  ipc.send('get-team-data');
}

/**
 * detach - Clean up any event handlers
 */
function detach() {
  debug('detaching add-first-squad');
  ipc.removeListener('team-data-saved', module.exports.internal.teamDataSavedListener);
  ipc.removeListener('return-team-data', module.exports.internal.returnTeamDataListener);
  ipc.removeListener('team-player-stored', module.exports.internal.teamPlayerStoredListener);
}

module.exports = {
  name: 'pick-a-player',
  state: state,
  init: init,
  attach: attach,
  detach: detach,
  internal: {
    teamDataSavedListener: teamDataSavedListener,
    returnTeamDataListener: returnTeamDataListener,
    teamPlayerStoredListener: teamPlayerStoredListener,
    playerAddOnClick: playerAddOnClick,
    playerNameOnInput: playerNameOnInput,
    generateBreadcrumb: generateBreadcrumb,
    stateManager: undefined,
    playerAddButton: undefined,
    playerName: undefined,
    playerList: undefined,
    breadcrumb: undefined,
    filename: undefined,
    dataObj: undefined,
    seasonId: undefined
  }
};
<|endoftext|>


<commit_before>
var luajs = luajs || {};

// TODO: Remove this!
luajs.debug = {};

luajs.utils = {

	toObject: function (table) {
		var result = table[1] === undefined? {} : [],
			i;

		for (i in table) {
			if (table.hasOwnProperty (i) && !(i in luajs.Table.prototype) && i !== '__luajs') {
					result[i] = (table[i] instanceof luajs.Table)? luajs.utils.toObject (table[i]) : table[i];
			}
		}

		return result;
	},

	parseJSON: function (json) {

		var convertToTable = function (obj) {
			for (var i in obj) {

				if (typeof obj[i] === 'object') {
					obj[i] = convertToTable (obj[i]);

				} else if (obj[i] === null) {
					obj[i] = undefined;
				}
			}

			return new luajs.Table (obj);
		};

		return convertToTable (JSON.parse (json));
	},

	catchExecutionError: function (e) {
		if (e instanceof luajs.Error && console) throw new Error ('[luajs] ' + e.message + '\n    ' + (e.luaStack || []).join ('\n    '));
		throw e;
	}

};

<commit_msg>Bugfix for converting a luajs.Table to a JavaScript Object.<commit_after>
var luajs = luajs || {};

// TODO: Remove this!
luajs.debug = {};

luajs.utils = {

	toObject: function (table) {
		var isArr = luajs.lib.table.getn (table) > 0,
			result = isArr? [] : {},
			i;

		for (i in table) {
			if (table.hasOwnProperty (i) && !(i in luajs.Table.prototype) && i !== '__luajs') {
					result[isArr? i - 1 : i] = (table[i] instanceof luajs.Table)? luajs.utils.toObject (table[i]) : table[i];
			}
		}

		return result;
	},

	parseJSON: function (json) {

		var convertToTable = function (obj) {
			for (var i in obj) {

				if (typeof obj[i] === 'object') {
					obj[i] = convertToTable (obj[i]);

				} else if (obj[i] === null) {
					obj[i] = undefined;
				}
			}

			return new luajs.Table (obj);
		};

		return convertToTable (JSON.parse (json));
	},

	catchExecutionError: function (e) {
		if (e instanceof luajs.Error && console) throw new Error ('[luajs] ' + e.message + '\n    ' + (e.luaStack || []).join ('\n    '));
		throw e;
	}

};

<|endoftext|>


<commit_before>var zz = {
	Config : {
		Local : {
			DB : {
				name : "zz-mobile-frontend-titanium-db",
				schema : "/data/db/zz-mobile-frontend-titanium-db"
			}
		},
		Cloud : {
			/*
			baseURL : "http://172.30.113.10:10010/zz/api/v02",
			cdnURL : "http://172.30.113.10:10011/zz/api/v02/cdn",
			*/
			/*
			baseURL : "http://172.30.103.11:10010/zz/api/v02",
			cdnURL : "http://172.30.103.11:10011/zz/api/v02/cdn",
			*/
			baseURL : "https://beta.ziriziri.com/zz/api/v02",
			cdnURL : "https://beta.ziriziri.com/zz/api/v02/cdn",
			cached : true,
			maxPerPage : 10

		}
	}
};

exports.ZZ = zz;
exports.version = 0.2;<commit_msg>baase url nuovo<commit_after>var zz = {
	Config : {
		Local : {
			DB : {
				name : "zz-mobile-frontend-titanium-db",
				schema : "/data/db/zz-mobile-frontend-titanium-db"
			}
		},
		Cloud : {
			/*
			baseURL : "http://172.30.113.10:10010/zz/api/v02",
			cdnURL : "http://172.30.113.10:10011/zz/api/v02/cdn",
			*/
			/*
			baseURL : "http://172.30.103.11:10010/zz/api/v02",
			cdnURL : "http://172.30.103.11:10011/zz/api/v02/cdn",
			*/
			//baseURL : "https://beta.ziriziri.com/zz/api/v02",
			baseURL : "https://apis.ziriziri.com/v02",
			cdnURL : "https://apis.ziriziri.com/v02",
			cached : true,
			maxPerPage : 10

		}
	}
};

exports.ZZ = zz;
exports.version = 0.2;<|endoftext|>


<commit_before>"format cjs";

// HELPERS USED BY npm.js
function isRelative(path) {
	return  path.substr(0,1) === ".";
}

// Converts a parsed module name to a string
function createModuleName (descriptor, standard) {
	if(standard) {
		return descriptor.moduleName;
	} else {
		return descriptor.packageName
			+ (descriptor.version ? '@' + descriptor.version : '')
			+ (descriptor.modulePath ? '#' + descriptor.modulePath : '')
			+ (descriptor.plugin ? '!' + descriptor.plugin : '');
	}
};

// Breaks a string moduleName into parts.
// packageName@version!plugin#modulePath
// "./lib/bfs"
function parseModuleName (moduleName, currentPackageName) {
	var pluginParts = moduleName.split('!');
	var modulePathParts = pluginParts[0].split("#");
	var versionParts = modulePathParts[0].split("@");
	// it could be something like `@empty`
	if(!modulePathParts[1] && !versionParts[0]) {
		versionParts = ["@"+versionParts[0]];
	}
	var packageName,
		modulePath;

	// if relative, use currentPackageName
	if( currentPackageName && isRelative(moduleName) ) {
		packageName= currentPackageName;
		modulePath = versionParts[0];
	} else {

		if(modulePathParts[1]) { // foo@1.2#./path
			packageName = versionParts[0];
			modulePath = modulePathParts[1];
		} else {
			// test/abc
			var folderParts = versionParts[0].split("/");
			packageName = folderParts.shift();
			modulePath = folderParts.join("/");
		}

	}

	return {
		plugin: pluginParts[1],
		version: versionParts[1],
		modulePath: modulePath,
		packageName: packageName,
		moduleName: moduleName
	};
}

function childPackageAddress(parentPackageAddress, childName){
	var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/,"");
	return (packageFolderName ? packageFolderName+"/" : "")+"node_modules/" + childName + "/package.json";
}

function parentNodeModuleAddress(address) {
	var nodeModules = "/node_modules/",
		nodeModulesIndex = address.lastIndexOf(nodeModules),
		prevModulesIndex = address.lastIndexOf(nodeModules, nodeModulesIndex-1);
	if(prevModulesIndex >= 0) {
		return address.substr(0, prevModulesIndex+nodeModules.length - 1 );
	}
}

var extension = function(System){

	var oldNormalize = System.normalize;
	System.normalize = function(name, parentName, parentAddress){

		var refPkg = findPackageByAddress(this, parentName, parentAddress);

		// this isn't in a package, so ignore
		if(!refPkg) {
			return oldNormalize.call(this, name, parentName, parentAddress);
		}
		// TODO: joining ...
		var parsedModuleName = parsedModuleNameFromPackage(this, refPkg, name, parentName);

		var depPkg = findDepPackage(this, refPkg, parsedModuleName.packageName);

		// This really shouldn't happen, but lets find a package.
		if (!depPkg) {
			depPkg = findPackage(this, parsedModuleName.packageName);
		}
		// It could be something like `fs` so check in globals
		if(!depPkg) {
			var browserPackageName = this.globalBrowser[parsedModuleName.packageName];
			if(browserPackageName) {
				parsedModuleName.packageName = browserPackageName;
				depPkg = findPackage(this, parsedModuleName.packageName);
			}
		}

		if( depPkg ) {
			parsedModuleName.version = depPkg.version;
			// add the main path
			if(!parsedModuleName.modulePath) {
				parsedModuleName.modulePath = (typeof depPkg.browser === "string" && depPkg.browser) || depPkg.main || 'index';
			}
			return createModuleName(parsedModuleName);
		} else {
			// it could be a local module like components/foo
			parsedModuleName.version = refPkg.version;
			var modName = createModuleName({
				version: refPkg.version,
				packageName: refPkg.name,
				modulePath: name
			});
			return oldNormalize.call(this, modName, parentName, parentAddress);
		}

	};

	var oldLocate = System.locate;
	System.locate = function(load){
		console.log("locate",load.name);
		var parsedModuleName = parseModuleName(load.name),
			loader = this;

		// @ is not the first character
		if(parsedModuleName.version && this.npm) {
			var pkg = this.npm[parsedModuleName.packageName];
			if(pkg) {
				return oldLocate.call(this, load).then(function(address){
					var root = pkg === loader.npmPaths.__default ?
						removePackage( pkg.fileUrl ) :
						packageFolderAddress(pkg.fileUrl);

					if(parsedModuleName.modulePath) {
						return joinURL( root, addJS(parsedModuleName.modulePath));
					}

					return address;
				});
			}
		}
		return oldLocate.call(this, load);
	};

	var extend = function(d, s){
		for(var prop in s) {
			d[prop] = s[prop];
		}
		return d;
	};

	// PACKAGE HELPERS ========================
	// Help locate modules based on packages info
	function findPackageByAddress(loader, parentName, parentAddress) {
		if(loader.npm) {
			if(parentName) {
				var parsed = parseModuleName(parentName);
				if(parsed.version && parsed.packageName) {
					var name = parsed.packageName+"@"+parsed.version;
					if(name in loader.npm) {
						return loader.npm[name];
					}
				}
			}
			if(parentAddress) {
				var packageFolder = packageFolderAddress(parentAddress);
				return packageFolder ? loader.npmPaths[packageFolder] : loader.npmPaths.__default;
			} else {
				return loader.npmPaths.__default;
			}
		}

	}
	function findPackage(loader, name) {
		if(loader.npm && !startsWithDotSlash(name)) {
			return loader.npm[name];
		}
	}
	function findDepPackage(loader, refPackage, name) {
		if(loader.npm && refPackage && !startsWithDotSlash(name)) {
			// Todo .. first part of name
			var curPackage = childPackageAddress(refPackage.fileUrl, name).replace(/\/package\.json.*/,"");
			while(curPackage) {
				var pkg = loader.npmPaths[curPackage];
				if(pkg) {
					return pkg;
				}
				var parentAddress = parentNodeModuleAddress(curPackage);
				if(!parentAddress) {
					return;
				}
				curPackage = parentAddress+"/"+name;
			}
		}
	}

	function parsedModuleNameFromPackage(loader, refPkg, name, parentName) {
		var packageName = refPkg.name,
		    parsedModuleName = parseModuleName(name, packageName);

		if( isRelative( parsedModuleName.modulePath ) ) {
			var parentParsed = parseModuleName( parentName, packageName );
			if( parentParsed.packageName === parsedModuleName.packageName && parentParsed.modulePath ) {
				parsedModuleName.modulePath = joinURIs(parentParsed.modulePath, parsedModuleName.modulePath);
			}
		}
		var mapName = createModuleName(parsedModuleName),
		    mappedName;

		// The refPkg might have a browser [https://github.com/substack/node-browserify#browser-field] mapping.
		// Perform that mapping here.
		if(refPkg.browser && (mapName in refPkg.browser)) {
			mappedName = refPkg.browser[mapName] === false ? "@empty" : refPkg.browser[mapName];
		}
		// globalBrowser looks like: {moduleName: aliasName, pgk: aliasingPkg}
		var global = loader && loader.globalBrowser && loader.globalBrowser[mapName];
		if(global) {
			mappedName = global.moduleName === false ? "@empty" : global.moduleName;
		}

		if(mappedName) {
			return parseModuleName(mappedName, packageName);
		} else {
			return parsedModuleName;
		}
	}

	function addJS(path){
		if(/\.\w+$/.test(path)) {
			return path;
		} else {
			return path+".js";
		}
	}
	function removePackage(path){
		return path.replace(/\/package\.json.*/,"");
	}

	function packageFolderAddress(address){
		var nodeModules = "/node_modules/",
			nodeModulesIndex = address.lastIndexOf(nodeModules),
			nextSlash = address.indexOf("/", nodeModulesIndex+nodeModules.length);
		if(nodeModulesIndex >= 0) {
			return nextSlash>=0 ? address.substr(0, nextSlash) : address;
		}
	}
	function parseURI(url) {
		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
			// authority = '//' + user + ':' + pass '@' + hostname + ':' port
			return (m ? {
			href     : m[0] || '',
			protocol : m[1] || '',
			authority: m[2] || '',
			host     : m[3] || '',
			hostname : m[4] || '',
			port     : m[5] || '',
			pathname : m[6] || '',
			search   : m[7] || '',
			hash     : m[8] || ''
		} : null);
	}
	// TODO: merge with joinURL
	function joinURIs(base, href) {
		function removeDotSegments(input) {
			var output = [];
			input.replace(/^(\.\.?(\/|$))+/, '')
				.replace(/\/(\.(\/|$))+/g, '/')
				.replace(/\/\.\.$/, '/../')
				.replace(/\/?[^\/]*/g, function (p) {
					if (p === '/..') {
						output.pop();
					} else {
						output.push(p);
					}
				});
			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
		}

		href = parseURI(href || '');
		base = parseURI(base || '');

		return !href || !base ? null : (href.protocol || base.protocol) +
			(href.protocol || href.authority ? href.authority : base.authority) +
			removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
				(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
				href.hash;
	}
	function startsWithDotSlash( path ) {
		return path.substr(0,2) === "./";
	}
	function endsWithSlash(path){
		return path[path.length -1] === "/";
	}
	function removeTrailingSlash( path ) {
		if(endsWithSlash(path)) {
			return path.substr(0, path.length -1);
		} else {
			return path;
		}
	}
	function removeLeadingDotSlash( path ) {
		if(startsWithDotSlash(path)) {
			return path.substr(2);
		} else {
			return path;
		}
	}
	// TODO: merge joinURIs
	function joinURL(baseURL, url){
		baseURL = removeTrailingSlash(baseURL);
		url = removeLeadingDotSlash(url);
		return baseURL+"/"+url;
	}
};

exports.createModuleName = createModuleName;
exports.parseModuleName = parseModuleName;
exports.childPackageAddress = childPackageAddress;
exports.parentNodeModuleAddress= parentNodeModuleAddress;

exports.out = function(){
	return [createModuleName,parseModuleName,isRelative, childPackageAddress, parentNodeModuleAddress].join("\n")+"\n"+
		"("+extension.toString()+")(loader);\n";
};
<commit_msg>updating the npm extension<commit_after>"format cjs";

// HELPERS USED BY npm.js
function isRelative(path) {
	return  path.substr(0,1) === ".";
}

// Converts a parsed module name to a string
function createModuleName (descriptor, standard) {
	if(standard) {
		return descriptor.moduleName;
	} else {
		return descriptor.packageName
			+ (descriptor.version ? '@' + descriptor.version : '')
			+ (descriptor.modulePath ? '#' + descriptor.modulePath : '')
			+ (descriptor.plugin ? '!' + descriptor.plugin : '');
	}
};

// Breaks a string moduleName into parts.
// packageName@version!plugin#modulePath
// "./lib/bfs"
function parseModuleName (moduleName, currentPackageName) {
	var pluginParts = moduleName.split('!');
	var modulePathParts = pluginParts[0].split("#");
	var versionParts = modulePathParts[0].split("@");
	// it could be something like `@empty`
	if(!modulePathParts[1] && !versionParts[0]) {
		versionParts = ["@"+versionParts[0]];
	}
	var packageName,
		modulePath;

	// if relative, use currentPackageName
	if( currentPackageName && isRelative(moduleName) ) {
		packageName= currentPackageName;
		modulePath = versionParts[0];
	} else {

		if(modulePathParts[1]) { // foo@1.2#./path
			packageName = versionParts[0];
			modulePath = modulePathParts[1];
		} else {
			// test/abc
			var folderParts = versionParts[0].split("/");
			packageName = folderParts.shift();
			modulePath = folderParts.join("/");
		}

	}

	return {
		plugin: pluginParts[1],
		version: versionParts[1],
		modulePath: modulePath,
		packageName: packageName,
		moduleName: moduleName
	};
}

function childPackageAddress(parentPackageAddress, childName){
	var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/,"");
	return (packageFolderName ? packageFolderName+"/" : "")+"node_modules/" + childName + "/package.json";
}

function parentNodeModuleAddress(address) {
	var nodeModules = "/node_modules/",
		nodeModulesIndex = address.lastIndexOf(nodeModules),
		prevModulesIndex = address.lastIndexOf(nodeModules, nodeModulesIndex-1);
	if(prevModulesIndex >= 0) {
		return address.substr(0, prevModulesIndex+nodeModules.length - 1 );
	}
}

var extension = function(System){

	var oldNormalize = System.normalize;
	System.normalize = function(name, parentName, parentAddress){
		if(name[0] === "$" || name[0] === "@") {

		}
		var refPkg = findPackageByAddress(this, parentName, parentAddress);

		// this isn't in a package, so ignore
		if(!refPkg) {
			return oldNormalize.call(this, name, parentName, parentAddress);
		}
		// TODO: joining ...
		var parsedModuleName = parsedModuleNameFromPackage(this, refPkg, name, parentName);

		var depPkg = findDepPackage(this, refPkg, parsedModuleName.packageName);

		// This really shouldn't happen, but lets find a package.
		if (!depPkg) {
			depPkg = findPackage(this, parsedModuleName.packageName);
		}
		// It could be something like `fs` so check in globals
		if(!depPkg) {
			var browserPackageName = this.globalBrowser[parsedModuleName.packageName];
			if(browserPackageName) {
				parsedModuleName.packageName = browserPackageName;
				depPkg = findPackage(this, parsedModuleName.packageName);
			}
		}

		if( depPkg ) {
			parsedModuleName.version = depPkg.version;
			// add the main path
			if(!parsedModuleName.modulePath) {
				parsedModuleName.modulePath = (typeof depPkg.browser === "string" && depPkg.browser) || depPkg.main || 'index';
			}
			return createModuleName(parsedModuleName);
		} else {
			// it could be a local module like components/foo
			parsedModuleName.version = refPkg.version;
			var modName = createModuleName({
				version: refPkg.version,
				packageName: refPkg.name,
				modulePath: name
			});
			if(name[0] === "$" || name[0] === "@") {
				modName = name;
			}
			return oldNormalize.call(this, modName, parentName, parentAddress);
		}

	};

	var oldLocate = System.locate;
	System.locate = function(load){
		console.log("locate",load.name);
		var parsedModuleName = parseModuleName(load.name),
			loader = this;

		// @ is not the first character
		if(parsedModuleName.version && this.npm) {
			var pkg = this.npm[parsedModuleName.packageName];
			if(pkg) {
				return oldLocate.call(this, load).then(function(address){
					var root = pkg === loader.npmPaths.__default ?
						removePackage( pkg.fileUrl ) :
						packageFolderAddress(pkg.fileUrl);

					if(parsedModuleName.modulePath) {
						return joinURL( root, addJS(parsedModuleName.modulePath));
					}

					return address;
				});
			}
		}
		return oldLocate.call(this, load);
	};

	var extend = function(d, s){
		for(var prop in s) {
			d[prop] = s[prop];
		}
		return d;
	};

	// PACKAGE HELPERS ========================
	// Help locate modules based on packages info
	function findPackageByAddress(loader, parentName, parentAddress) {
		if(loader.npm) {
			if(parentName) {
				var parsed = parseModuleName(parentName);
				if(parsed.version && parsed.packageName) {
					var name = parsed.packageName+"@"+parsed.version;
					if(name in loader.npm) {
						return loader.npm[name];
					}
				}
			}
			if(parentAddress) {
				var packageFolder = packageFolderAddress(parentAddress);
				return packageFolder ? loader.npmPaths[packageFolder] : loader.npmPaths.__default;
			} else {
				return loader.npmPaths.__default;
			}
		}

	}
	function findPackage(loader, name) {
		if(loader.npm && !startsWithDotSlash(name)) {
			return loader.npm[name];
		}
	}
	function findDepPackage(loader, refPackage, name) {
		if(loader.npm && refPackage && !startsWithDotSlash(name)) {
			// Todo .. first part of name
			var curPackage = childPackageAddress(refPackage.fileUrl, name).replace(/\/package\.json.*/,"");
			while(curPackage) {
				var pkg = loader.npmPaths[curPackage];
				if(pkg) {
					return pkg;
				}
				var parentAddress = parentNodeModuleAddress(curPackage);
				if(!parentAddress) {
					return;
				}
				curPackage = parentAddress+"/"+name;
			}
		}
	}

	function parsedModuleNameFromPackage(loader, refPkg, name, parentName) {
		var packageName = refPkg.name,
		    parsedModuleName = parseModuleName(name, packageName);

		if( isRelative( parsedModuleName.modulePath ) ) {
			var parentParsed = parseModuleName( parentName, packageName );
			if( parentParsed.packageName === parsedModuleName.packageName && parentParsed.modulePath ) {
				parsedModuleName.modulePath = joinURIs(parentParsed.modulePath, parsedModuleName.modulePath);
			}
		}
		var mapName = createModuleName(parsedModuleName),
		    mappedName;

		// The refPkg might have a browser [https://github.com/substack/node-browserify#browser-field] mapping.
		// Perform that mapping here.
		if(refPkg.browser && (mapName in refPkg.browser)) {
			mappedName = refPkg.browser[mapName] === false ? "@empty" : refPkg.browser[mapName];
		}
		// globalBrowser looks like: {moduleName: aliasName, pgk: aliasingPkg}
		var global = loader && loader.globalBrowser && loader.globalBrowser[mapName];
		if(global) {
			mappedName = global.moduleName === false ? "@empty" : global.moduleName;
		}

		if(mappedName) {
			return parseModuleName(mappedName, packageName);
		} else {
			return parsedModuleName;
		}
	}

	function addJS(path){
		if(/\.\w+$/.test(path)) {
			return path;
		} else {
			return path+".js";
		}
	}
	function removePackage(path){
		return path.replace(/\/package\.json.*/,"");
	}

	function packageFolderAddress(address){
		var nodeModules = "/node_modules/",
			nodeModulesIndex = address.lastIndexOf(nodeModules),
			nextSlash = address.indexOf("/", nodeModulesIndex+nodeModules.length);
		if(nodeModulesIndex >= 0) {
			return nextSlash>=0 ? address.substr(0, nextSlash) : address;
		}
	}
	function parseURI(url) {
		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
			// authority = '//' + user + ':' + pass '@' + hostname + ':' port
			return (m ? {
			href     : m[0] || '',
			protocol : m[1] || '',
			authority: m[2] || '',
			host     : m[3] || '',
			hostname : m[4] || '',
			port     : m[5] || '',
			pathname : m[6] || '',
			search   : m[7] || '',
			hash     : m[8] || ''
		} : null);
	}
	// TODO: merge with joinURL
	function joinURIs(base, href) {
		function removeDotSegments(input) {
			var output = [];
			input.replace(/^(\.\.?(\/|$))+/, '')
				.replace(/\/(\.(\/|$))+/g, '/')
				.replace(/\/\.\.$/, '/../')
				.replace(/\/?[^\/]*/g, function (p) {
					if (p === '/..') {
						output.pop();
					} else {
						output.push(p);
					}
				});
			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
		}

		href = parseURI(href || '');
		base = parseURI(base || '');

		return !href || !base ? null : (href.protocol || base.protocol) +
			(href.protocol || href.authority ? href.authority : base.authority) +
			removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
				(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
				href.hash;
	}
	function startsWithDotSlash( path ) {
		return path.substr(0,2) === "./";
	}
	function endsWithSlash(path){
		return path[path.length -1] === "/";
	}
	function removeTrailingSlash( path ) {
		if(endsWithSlash(path)) {
			return path.substr(0, path.length -1);
		} else {
			return path;
		}
	}
	function removeLeadingDotSlash( path ) {
		if(startsWithDotSlash(path)) {
			return path.substr(2);
		} else {
			return path;
		}
	}
	// TODO: merge joinURIs
	function joinURL(baseURL, url){
		baseURL = removeTrailingSlash(baseURL);
		url = removeLeadingDotSlash(url);
		return baseURL+"/"+url;
	}
};

exports.createModuleName = createModuleName;
exports.parseModuleName = parseModuleName;
exports.childPackageAddress = childPackageAddress;
exports.parentNodeModuleAddress= parentNodeModuleAddress;

exports.out = function(){
	return [createModuleName,parseModuleName,isRelative, childPackageAddress, parentNodeModuleAddress].join("\n")+"\n"+
		"("+extension.toString()+")(loader);\n";
};
<|endoftext|>