<commit_before>/*====+++++========+++++===*
* @Author: sovathana
* @Date:   2015-09-10 15:20:46
* @Last Modified by:   sovathana
* @Last Modified time: 2015-09-17 17:30:45
* @Email: sovathana.phat@gmail.com
* @Facebook && Twitter : Sophatvathana
* @Project: ngRolerr
* @FileName: ngRolerr.js
* @License: MIT
*==========================
*/

(function (window, factory) {
  if (typeof module !== 'undefined' && module.exports) {
    // CommonJS
    module.exports = factory(require('angular'));
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(['angular'], function (angular) {
      return (window.ngRolerr = factory(angular));
    });
  } else {
    // Global Variables
    window.ngRolerr  = factory(window.angular);
  }
}(this, function ngRolerr(angular) {

'use strict';
angular.module('ngRolerr', ['ng'])
 .constant('ngRolerrConfig', {
    rolesUrl: '',
    loginUrl: '',
    signupUrl: '',
    storageType: 'cookies',
    rolesSource: [],
    getUserUrl: '',
    getUrl: '',
    modeInterceptor: true,
    header: 'Authorization',
    tokenType: 'Bearer',
    keyTokenName: '__rolerr'
 })
 .provider('$rolerr',['ngRolerrConfig',function(config){
Object.defineProperties(this, {
       rolesUrl: {
          get: function() { return config.rolesUrl; },
          set: function(value) { config.rolesUrl = value; }
        },
       modeInterceptor: {
          get: function() { return config.modeInterceptor; },
          set: function(value) { config.modeInterceptor = value; }
       },
       getUserUrl: {
          get: function() { return config.getUserUrl; },
          set: function(value) { config.getUserUrl = value; }
       },
       getUrl: {
          get: function() { return config.getUrl; },
          set: function(value) { config.getUrl = value; }
        },
       rolesSource: {
          get: function() { return config.rolesSource; },
          set: function(value) { config.rolesSource = value; }
       },

       secret: {
          get: function() { return config.secret; },
          set: function(value) { config.secret = value; }
        },

       storageType: {
          get: function() { return config.storageType; },
          set: function(value) { config.storageType =  value; }
       },

       loginUrl: {
          get: function() { return config.loginUrl; },
          set: function(value) { config.loginUrl = value; }
       },

       signupUrl: {
          get: function() {return config.signupUrl; },
          set: function(value) { config.signupUrl = value; }
       },

       keyTokenName: {
          get: function() { return  config.keyTokenName; },
          set: function(value) { config.keyTokenName = value; }
       }

   });

   this.$get = ['service', 'rolerr', 'authorizer', function(service, rolerr, authorizer){
      var $rolerr = {};

      $rolerr.isTokenResolved = function() {
        return rolerr.isTokenResolved();
      };
      $rolerr.getToken = function() {
        return rolerr.getToken(config.keyTokenName);
      };

      $rolerr.isAuthenticated = function() {
        return rolerr.isAuthenticated();
      };

      $rolerr.isInRole = function(role) {
        return rolerr.isInRole(role);
      };

      $rolerr.isInAnyRole = function(roles) {
        return rolerr.isInAnyRole(roles);
      };

      $rolerr.authenticate = function(identity) {
        return rolerr.authenticate(identity);
      };

      $rolerr.identity = function(force) {
        return rolerr.identity(force);
      };

      $rolerr.authorize = function() {
        return authorizer.authorize();
      };

      $rolerr.getUser = function() {
        return service.getUser();
      };

      $rolerr.getRoles = function() {
        return service.getRoles();
      };

      $rolerr.signup = function(signupData){
        return service.signup(signupData);
      };

      $rolerr.login = function(loginData) {
        return service.login(loginData);
      };

      $rolerr.logout = function() {
         return service.logout();
      };

      $rolerr.get = function(url) {
        return service.get(url);
      };

      $rolerr.post = function(url,data) {
        return service.post(url,data);
      };

      return $rolerr;
   }];
 }])

 .factory('serviceStorage', ['ngRolerrConfig','$window','$rolerrCookies', function(config, $window, $rolerrCookies){
  var $storage ={}, isCookies = (config.storageType ==='cookies');
     var windowStorage = function(type) {
        var supported;
         try {
            supported = $window[type];
            if(supported!=null)
              if(!isCookies){
            var key = '__' + Math.round(Math.random() * 1e7);
                try {
                      $window[config.storageType].setItem(key, key);
                      $window[config.storageType].removeItem(key);
                    }catch (err) {
                }

              }
            }catch (err) {
            supported = false;
          }
      };
      if(!windowStorage)
        console.warn(config.storageType+ ' is not supported');

      $storage.setItem = function(key,value){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].setItem(key, value) : undefined;
        else
          return isCookies ? $rolerrCookies.put(key, value) : undefined;
      };

      $storage.getItem = function(key){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].getItem(key) : undefined;
        else
          return isCookies ? $rolerrCookies.get(key) : undefined;
      };
      $storage.removeItem = function(key){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].removeItem(key) : undefined;
        else
          return isCookies ? $rolerrCookies.remove(key) : undefined;
      };

    return $storage;

 }])
 .factory('service',['$rolerrCookies','rolerr', '$q',
  'ngRolerrConfig', '$http', function($rolerrCookies, rolerr, $q, config, $http){

    return {
       getRoles: function(){
          var deferred = $q.defer();
          $http.get(config.rolesUrl).success(function(data){
             deferred.resolve(data);
          }).error(function(err) { deferred.reject(err); });
        return deferred.promise;
       },

       getUser: function(){
      var deferred = $q.defer();
      $http.get(config.userRole).success(function(data){
        deferred.resolve(data);
      }).error(function(err) { deferred.reject(err); });
       },

       getData: function(){
          var deferred = $q.defer();
          $http.get(config.getUrl).success(function(data){
            deferred.resolve(data);
          }).error(function(err) { deferred.reject(err); });
       },

       login: function(loginData){
         var deferred = $q.defer();
         return $http.post(config.loginUrl,loginData).success(function(data){
            deferred.resolve(data);
          rolerr.authenticate(data.token);
         }).error(function(err){deferred.reject(err); });
       },

       signup: function(signupData){
         var deferred = $q.defer();
         return $http.post(config.signupUrl,signupData).success(function(data){
            deferred.resolve(data);
         }).error(function(err){deferred.reject(err); });
       },

       logout: function(){
          $rolerrCookies.remove(config.keyTokenName);
         return $q.when();
       },

       get: function(url){
         var deferred = $q.defer();
          return $http.get(url).success(function(res){
            deferred.resolve(res);
          }).error(function(err){deferred.reject(err); });
       },

       post: function(url, data){
         var deferred = $q.defer();
         return $http.post(url, data).success(function(res){
          deferred.resolve(res);
         }).error(function(err){deferred.reject(err);});
       }
    };

 }])
 .factory('rolerr',['ngRolerrConfig',
  '$q','$window',
  '$timeout','serviceStorage',
  function(config, $q, $window, $timeout, $storage) {
    var _token = undefined,
      _authenticated = false,
        dataRoles = {};

    return {
      isTokenResolved: function() {
        return angular.isDefined(_token);
      },
      getToken: function() {
        return $storage.getItem(config.storageName);
      },
      isAuthenticated: function() {
        if(config.storageType)
        var _token = $storage.getItem(config.keyTokenName);
          if (_token) {
            if (_token.split('.').length === 3) {
              var base64Url = _token.split('.')[1];
              var base64 = base64Url.replace('-', '+').replace('_', '/');
              var exp = JSON.parse($window.atob(base64)).exp;

              if (exp) {
                var isExpired = Math.round(new Date().getTime() / 1000) >= exp;

                if (isExpired) {
                  alert("This authentication is expire");
                  $storage.removeItem(config.keyTokenName);
                  return false;
                } else {
                  return true;
                }
              }
              return true;
            }
            return true;
          }
          return false;
      },

      authenticate: function(identity) {
        _token = identity;
        _authenticated = identity != null;
        var expireDate = new Date();
             expireDate.setDate(expireDate.getDate() + 1);
        if (identity)
           $storage.setItem(config.keyTokenName, identity,{'expires': expireDate});
        else $storage.removeItem(config.keyTokenName);
      },

      identity: function(force) {
        var deferred = $q.defer();

        if (force === true) _token = undefined;

        if (angular.isDefined(_token)) {
          deferred.resolve(_token);

          return deferred.promise;
        }

        var self = this;
         $timeout(function() {
          _token =  $storage.getItem(config.keyTokenName);
          self.authenticate(_token);
          deferred.resolve(_token);
         });

        return deferred.promise;
      }
    };
  }])
.factory('shareservice', [ 'ngRolerrConfig', '$q', 'rolerr', 'service', function( config, $q, rolerr, service){

   Array.prototype.equals = function (arr) {
      if (!arr) return false;
      if (this === null || arr === null) return false;
      if (this !== this && arr !== arr) return true;

    for(var i = 0, l=this.length; i < l; i++) {

        for(var j = 0, m=arr.length; j < m; j++){

            if (this[i] === arr[j]){
                return true;
            }
        }
    }
      return false;
};
  return  {

        checkRolesSource: function(getrr, roles) {
              var dataArr=[];
          if( !rolerr.isAuthenticated() || !rolerr.identity) return false;

           for(var i=0; i<getrr.roles.length;i++)
          dataArr.push(getrr.roles[i].name);
           return roles.equals(dataArr);
        }
  };
}])
.factory('authorizer', ['$location', 'service','shareservice','$rootScope', '$state', 'rolerr',
  function($location,service,shareservice, $rootScope, $state, rolerr) {
    return {
      authorize: function() {
         return  rolerr.identity()
            .then(function() {

          if (!rolerr.isAuthenticated()){
                $rootScope.returnToState = $rootScope.toState;
                $rootScope.returnToStateParams = $rootScope.toStateParams;
                if(!$rootScope.toState.data.failedTo)
                   $location.path($rootScope.toState.url);
                 else{
                  //alert("Logged in is expire!");
                 $state.go($rootScope.toState.data.failedTo);
               }
                 //console.log('Not Login ');
           }else{
            service.getRoles().then(function(data){
             if ($rootScope.toState.data.roles && $rootScope.toState.data.roles.length > 0 && !shareservice.checkRolesSource(data, $rootScope.toState.data.roles)) {
                 $state.go($rootScope.toState.data.deniedTo);
             }
           }, function(data) {
                    console.log('data retrieval failed.');
                });
     }
           });
      }
    };
  }
])
.factory('$rolerrCookies', ['$$cookieReader', '$$cookieWriter', function($$cookieReader,$$cookieWriter){
   var defaults = this.defaults = {};
    function calcOptions(options) {
      return options ? angular.extend({}, defaults, options) : defaults;
    }

  return {
    get : function(key) {
          return $$cookieReader()[key];
      },

    put : function(key, value, options) {
          $$cookieWriter(key, value, calcOptions(options));
      },

    remove : function(key, options) {
          $$cookieWriter(key, undefined, calcOptions(options));
      }
};
}]);
/* Spacial Thank to angular-cookies */

function $$CookieWriter($document, $log, $browser) {
  var cookiePath = $browser.baseHref();
  var rawDocument = $document[0];

  function buildCookieString(name, value, options) {
    var path, expires;
    options = options || {};
    expires = options.expires;
    path = angular.isDefined(options.path) ? options.path : cookiePath;
    if (value === undefined) {
      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
      value = '';
    }
    if (angular.isString(expires)) {
      expires = new Date(expires);
    }

    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    str += path ? ';path=' + path : '';
    str += options.domain ? ';domain=' + options.domain : '';
    str += expires ? ';expires=' + expires.toUTCString() : '';
    str += options.secure ? ';secure' : '';

    var cookieLength = str.length + 1;
    if (cookieLength > 4096) {
      $log.warn("Cookie '" + name +
        "' possibly not set or overflowed because it was too large (" +
        cookieLength + " > 4096 bytes)!");
    }

    return str;
  }

  return function(name, value, options) {
    rawDocument.cookie = buildCookieString(name, value, options);
  };
}

$$CookieWriter.$inject = ['$document', '$log', '$browser'];

angular.module('ngRolerr').provider('$$cookieWriter', function $$CookieWriterProvider() {
  this.$get = $$CookieWriter;
})

.config(['$httpProvider', function($httpProvider) {
      $httpProvider.interceptors.push(['$q','serviceStorage', 'ngRolerrConfig', 'rolerr',
  function($q, $storage, config, rolerr){
  return {
        request: function(request) {
         // if (request.skipAuthorization) {
           // return request;
          // }

          if (rolerr.isAuthenticated() && config.modeInterceptor) {
             var token =  $storage.getItem(config.keyTokenName);

                token =config.header && config.tokenType ? config.tokenType + ' ' + token:
                    $storage.getItem(config.keyTokenName);

              request.headers[config.header] = token;
               return request || $q.when(request);
            }

            return request;
          },
          responseError: function(response) {
            return $q.reject(response);
          }
        };
  }]);
}]);
}));
<commit_msg>Fixed expire angualr<commit_after>/*====+++++========+++++===*
* @Author: sovathana
* @Date:   2015-09-10 15:20:46
* @Last Modified by:   sovathana
* @Last Modified time: 2015-09-17 17:30:45
* @Email: sovathana.phat@gmail.com
* @Facebook && Twitter : Sophatvathana
* @Project: ngRolerr
* @FileName: ngRolerr.js
* @License: MIT
*==========================
*/

(function (window, factory) {
  if (typeof module !== 'undefined' && module.exports) {
    // CommonJS
    module.exports = factory(require('angular'));
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(['angular'], function (angular) {
      return (window.ngRolerr = factory(angular));
    });
  } else {
    // Global Variables
    window.ngRolerr  = factory(window.angular);
  }
}(this, function ngRolerr(angular) {

'use strict';
angular.module('ngRolerr', ['ng'])
 .constant('ngRolerrConfig', {
    rolesUrl: '',
    loginUrl: '',
    signupUrl: '',
    storageType: 'cookies',
    rolesSource: [],
    getUserUrl: '',
    getUrl: '',
    modeInterceptor: true,
    header: 'Authorization',
    tokenType: 'Bearer',
    keyTokenName: '__rolerr',
    expire: ''
 })
 .provider('$rolerr',['ngRolerrConfig',function(config){
Object.defineProperties(this, {
       rolesUrl: {
          get: function() { return config.rolesUrl; },
          set: function(value) { config.rolesUrl = value; }
        },
       modeInterceptor: {
          get: function() { return config.modeInterceptor; },
          set: function(value) { config.modeInterceptor = value; }
       },
       getUserUrl: {
          get: function() { return config.getUserUrl; },
          set: function(value) { config.getUserUrl = value; }
       },
       getUrl: {
          get: function() { return config.getUrl; },
          set: function(value) { config.getUrl = value; }
        },
       rolesSource: {
          get: function() { return config.rolesSource; },
          set: function(value) { config.rolesSource = value; }
       },

       secret: {
          get: function() { return config.secret; },
          set: function(value) { config.secret = value; }
        },

       storageType: {
          get: function() { return config.storageType; },
          set: function(value) { config.storageType =  value; }
       },

       loginUrl: {
          get: function() { return config.loginUrl; },
          set: function(value) { config.loginUrl = value; }
       },

       signupUrl: {
          get: function() {return config.signupUrl; },
          set: function(value) { config.signupUrl = value; }
       },

       keyTokenName: {
          get: function() { return  config.keyTokenName; },
          set: function(value) { config.keyTokenName = value; }
       },

       expire: {
          get: function() { return config.expire; },
          set: function(value) { config.expire = value; }
       }

   });

   this.$get = ['service', 'rolerr', 'authorizer', function(service, rolerr, authorizer){
      var $rolerr = {};

      $rolerr.isTokenResolved = function() {
        return rolerr.isTokenResolved();
      };
      $rolerr.getToken = function() {
        return rolerr.getToken(config.keyTokenName);
      };

      $rolerr.isAuthenticated = function() {
        return rolerr.isAuthenticated();
      };

      $rolerr.isInRole = function(role) {
        return rolerr.isInRole(role);
      };

      $rolerr.isInAnyRole = function(roles) {
        return rolerr.isInAnyRole(roles);
      };

      $rolerr.authenticate = function(identity) {
        return rolerr.authenticate(identity);
      };

      $rolerr.identity = function(force) {
        return rolerr.identity(force);
      };

      $rolerr.authorize = function() {
        return authorizer.authorize();
      };

      $rolerr.getUser = function() {
        return service.getUser();
      };

      $rolerr.getRoles = function() {
        return service.getRoles();
      };

      $rolerr.signup = function(signupData){
        return service.signup(signupData);
      };

      $rolerr.login = function(loginData) {
        return service.login(loginData);
      };

      $rolerr.logout = function() {
         return service.logout();
      };

      $rolerr.get = function(url) {
        return service.get(url);
      };

      $rolerr.post = function(url,data) {
        return service.post(url,data);
      };

      return $rolerr;
   }];
 }])

 .factory('serviceStorage', ['ngRolerrConfig','$window','$rolerrCookies', function(config, $window, $rolerrCookies){
  var $storage ={}, isCookies = (config.storageType ==='cookies');
     var windowStorage = function(type) {
        var supported;
         try {
            supported = $window[type];
            if(supported!=null)
              if(!isCookies){
            var key = '__' + Math.round(Math.random() * 1e7);
                try {
                      $window[config.storageType].setItem(key, key);
                      $window[config.storageType].removeItem(key);
                    }catch (err) {
                }

              }
            }catch (err) {
            supported = false;
          }
      };
      if(!windowStorage)
        console.warn(config.storageType+ ' is not supported');

      $storage.setItem = function(key,value,obj){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].setItem(key, value) : undefined;
        else
          return isCookies ? $rolerrCookies.put(key, value, obj) : undefined;
      };

      $storage.getItem = function(key){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].getItem(key) : undefined;
        else
          return isCookies ? $rolerrCookies.get(key) : undefined;
      };
      $storage.removeItem = function(key){
        if(!isCookies)
          return windowStorage ? $window[config.storageType].removeItem(key) : undefined;
        else
          return isCookies ? $rolerrCookies.remove(key) : undefined;
      };

    return $storage;

 }])
 .factory('service',['$rolerrCookies','rolerr', '$q',
  'ngRolerrConfig', '$http', function($rolerrCookies, rolerr, $q, config, $http){

    return {
       getRoles: function(){
          var deferred = $q.defer();
          $http.get(config.rolesUrl).success(function(data){
             deferred.resolve(data);
          }).error(function(err) { deferred.reject(err); });
        return deferred.promise;
       },

       getUser: function(){
      var deferred = $q.defer();
      $http.get(config.userRole).success(function(data){
        deferred.resolve(data);
      }).error(function(err) { deferred.reject(err); });
       },

       getData: function(){
          var deferred = $q.defer();
          $http.get(config.getUrl).success(function(data){
            deferred.resolve(data);
          }).error(function(err) { deferred.reject(err); });
       },

       login: function(loginData){
         var deferred = $q.defer();
         return $http.post(config.loginUrl,loginData).success(function(data){
            deferred.resolve(data);
          rolerr.authenticate(data.token);
         }).error(function(err){deferred.reject(err); });
       },

       signup: function(signupData){
         var deferred = $q.defer();
         return $http.post(config.signupUrl,signupData).success(function(data){
            deferred.resolve(data);
         }).error(function(err){deferred.reject(err); });
       },

       logout: function(){
          $rolerrCookies.remove(config.keyTokenName);
         return $q.when();
       },

       get: function(url){
         var deferred = $q.defer();
          return $http.get(url).success(function(res){
            deferred.resolve(res);
          }).error(function(err){deferred.reject(err); });
       },

       post: function(url, data){
         var deferred = $q.defer();
         return $http.post(url, data).success(function(res){
          deferred.resolve(res);
         }).error(function(err){deferred.reject(err);});
       }
    };

 }])
 .factory('rolerr',['ngRolerrConfig',
  '$q','$window',
  '$timeout','serviceStorage',
  function(config, $q, $window, $timeout, $storage) {
    var _token = undefined,
      _authenticated = false,
        dataRoles = {};

    return {
      isTokenResolved: function() {
        return angular.isDefined(_token);
      },
      getToken: function() {
        return $storage.getItem(config.storageName);
      },
      isAuthenticated: function() {
        if(config.storageType)
        var _token = $storage.getItem(config.keyTokenName);
          if (_token) {
            if (_token.split('.').length === 3) {
              var base64Url = _token.split('.')[1];
              var base64 = base64Url.replace('-', '+').replace('_', '/');
              var exp = JSON.parse($window.atob(base64)).exp;
              if (exp) {
                var isExpired = Math.round(new Date().getTime() / 1000) >= exp;

                if (isExpired) {
                  alert("This authentication is expire");
                  $storage.removeItem(config.keyTokenName);
                  return false;
                } else {
                  return true;
                }
              }
              return true;
            }
            return true;
          }
          return false;
      },

      authenticate: function(identity) {
        _token = identity;
        _authenticated = identity != null;
        var expireDate = new Date();
             expireDate.setDate(expireDate.getDate() + 1);
        if (identity)
           $storage.setItem(config.keyTokenName, identity,{expires: expireDate});
        else $storage.removeItem(config.keyTokenName);
      },

      identity: function(force) {
        var deferred = $q.defer();

        if (force === true) _token = undefined;

        if (angular.isDefined(_token)) {
          deferred.resolve(_token);

          return deferred.promise;
        }

        var self = this;
         $timeout(function() {
          _token =  $storage.getItem(config.keyTokenName);
          self.authenticate(_token);
          deferred.resolve(_token);
         });

        return deferred.promise;
      }
    };
  }])
.factory('shareservice', [ 'ngRolerrConfig', '$q', 'rolerr', 'service', function( config, $q, rolerr, service){

   Array.prototype.equals = function (arr) {
      if (!arr) return false;
      if (this === null || arr === null) return false;
      if (this !== this && arr !== arr) return true;

    for(var i = 0, l=this.length; i < l; i++) {

        for(var j = 0, m=arr.length; j < m; j++){

            if (this[i] === arr[j]){
                return true;
            }
        }
    }
      return false;
};
  return  {

        checkRolesSource: function(getrr, roles) {
              var dataArr=[];
          if( !rolerr.isAuthenticated() || !rolerr.identity) return false;

           for(var i=0; i<getrr.roles.length;i++)
          dataArr.push(getrr.roles[i].name);
           return roles.equals(dataArr);
        }
  };
}])
.factory('authorizer', ['$location', 'service','shareservice','$rootScope', '$state', 'rolerr',
  function($location,service,shareservice, $rootScope, $state, rolerr) {
    return {
      authorize: function() {
         return  rolerr.identity()
            .then(function() {

          if (!rolerr.isAuthenticated()){
                $rootScope.returnToState = $rootScope.toState;
                $rootScope.returnToStateParams = $rootScope.toStateParams;
                if(!$rootScope.toState.data.failedTo)
                   $location.path($rootScope.toState.url);
                 else{
                  //alert("Logged in is expire!");
                 $state.go($rootScope.toState.data.failedTo);
               }
                 //console.log('Not Login ');
           }else{
            service.getRoles().then(function(data){
             if ($rootScope.toState.data.roles && $rootScope.toState.data.roles.length > 0 && !shareservice.checkRolesSource(data, $rootScope.toState.data.roles)) {
                 $state.go($rootScope.toState.data.deniedTo);
             }
           }, function(data) {
                    console.log('data retrieval failed.');
                });
     }
           });
      }
    };
  }
])
.factory('$rolerrCookies', ['$$cookieReader', '$$cookieWriter', function($$cookieReader,$$cookieWriter){
   var defaults = this.defaults = {};
    function calcOptions(options) {
      return options ? angular.extend({}, defaults, options) : defaults;
    }

  return {
    get : function(key) {
          return $$cookieReader()[key];
      },

    put : function(key, value, options) {
          $$cookieWriter(key, value, calcOptions(options));
      },

    remove : function(key, options) {
          $$cookieWriter(key, undefined, calcOptions(options));
      }
};
}]);
/* Spacial Thank to angular-cookies */

function $$CookieWriter($document, $log, $browser) {
  var cookiePath = $browser.baseHref();
  var rawDocument = $document[0];

  function buildCookieString(name, value, options) {
    var path, expires;
    options = options || {};
    expires = options.expires;
    path = angular.isDefined(options.path) ? options.path : cookiePath;
    if (value === undefined) {
      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
      value = '';
    }
    if (angular.isString(expires)) {
      expires = new Date(expires);
    }

    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    str += path ? ';path=' + path : '';
    str += options.domain ? ';domain=' + options.domain : '';
    str += expires ? ';expires=' + expires.toUTCString() : '';
    str += options.secure ? ';secure' : '';

    var cookieLength = str.length + 1;
    if (cookieLength > 4096) {
      $log.warn("Cookie '" + name +
        "' possibly not set or overflowed because it was too large (" +
        cookieLength + " > 4096 bytes)!");
    }

    return str;
  }

  return function(name, value, options) {
    rawDocument.cookie = buildCookieString(name, value, options);
  };
}

$$CookieWriter.$inject = ['$document', '$log', '$browser'];

angular.module('ngRolerr').provider('$$cookieWriter', function $$CookieWriterProvider() {
  this.$get = $$CookieWriter;
})

.config(['$httpProvider', function($httpProvider) {
      $httpProvider.interceptors.push(['$q','serviceStorage', 'ngRolerrConfig', 'rolerr',
  function($q, $storage, config, rolerr){
  return {
        request: function(request) {
         // if (request.skipAuthorization) {
           // return request;
          // }

          if (rolerr.isAuthenticated() && config.modeInterceptor) {
             var token =  $storage.getItem(config.keyTokenName);

                token =config.header && config.tokenType ? config.tokenType + ' ' + token:
                    $storage.getItem(config.keyTokenName);

              request.headers[config.header] = token;
               return request || $q.when(request);
            }

            return request;
          },
          responseError: function(response) {
            return $q.reject(response);
          }
        };
  }]);
}]);
}));
<|endoftext|>


<commit_before>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

import {spawn} from "child_process";

let StringDecoder = require("string_decoder").StringDecoder;
let tmp = require("tmp");
let decoder = new StringDecoder("utf8");

const fs = require("fs");
const kill = require("tree-kill");

const EXPOSE_REPLAY_PATH = "expoSE replay";

class Spawn {

	constructor(script, file, opts) {
		this.script = script;
		this.file = file;
		this.options = opts;
		this.args = [this.file.path, JSON.stringify(this.file.input)];
		this.tmpCoverageFile = tmp.fileSync();
		this.tmpOutFile = tmp.fileSync();

		this.env = JSON.parse(JSON.stringify(process.env));
		this.env.EXPOSE_OUT_PATH = this.tmpOutFile.name;
		this.env.EXPOSE_COVERAGE_PATH = this.tmpCoverageFile.name;
	}

	_tryParse(data, type, errors) {
		try {
			return JSON.parse(data);
		} catch (e) {
			errors.push({error: "Exception E: " + e + " of " + type + " on " + data});
			return null;
		}
	}

	startTime() {
		return this._startTime;
	}

	endTime() {
		return this._endTime;
	}

	time() {
		return this._endTime - this._startTime;
	}

	_recordEndTime() {
		this._endTime = (new Date()).getTime();
	}

	_processEnded(code, done) {

		this._recordEndTime();

		let me = this;
		let errors = [];
		let coverage = null;
		let finalOut = null;
		let count = 0;
		let test = this;

		function cb(err) {

			count++;

			if (err) {
				errors.push({error: err});
			}

			if (count == 2) {
				test.tmpOutFile.removeCallback();
				test.tmpCoverageFile.removeCallback();
				done(me, code, test, finalOut, coverage, errors);
			}
		}

		fs.readFile(this.tmpOutFile.name, {encoding: "utf8"}, function(err, data) {
			if (!err) {
				finalOut = test._tryParse(data, "test data", errors);
			}
			cb(err);
		});

		fs.readFile(this.tmpCoverageFile.name, {encoding: "utf8"}, function(err, data) {
			if (!err) {
				coverage = test._tryParse(data, "coverage data", errors);
			}
			cb(err);
		});
	}

	shellescape(a) {
		let ret = [];

		a.forEach(function(s) {

			if (/[^A-Za-z0-9_\/:=-]/.test(s)) {
				s = "'" + s.replace(/'/g, "'\\''") + "'";
			}

			ret.push(s);
		});

		return ret.join(" ");
	}

	_mkEnvReplay() {
		let envStr = "";
		for (let i in this.env) {
			envStr += i + "=\"" + this.env[i] + "\" ";
		}
		return envStr;
	}

	makeReplayString() {
		return /* this._mkEnvReplay() + */ EXPOSE_REPLAY_PATH + " " + this.shellescape(this.args);
	}

	kill() {
		kill(this._pid, "SIGKILL");
	}

	_buildTimeout() {
		return setTimeout(() => {
			this.kill();
		}, this.options.timeout);
	}

	start(done) {

		function insertData(data) {
			data = decoder.write(data);
			if (this.options.log) {
				process.stdout.write(data);
			}
		}

		this._startTime = (new Date()).getTime();

		try {
			const prc = spawn(this.script, this.args, {
				env: this.env,
				disconnected: false
			});

			prc.stdout.on("data", insertData.bind(this));
			prc.stderr.on("data", insertData.bind(this));

			prc.stdout.on("close", code => {
				clearTimeout(this._killTimeout);
				this._processEnded(code, done);
			});

			this._killTimeout = this._buildTimeout();
			this._pid = prc.pid;
		} catch (ex) {
			console.log("Distributor ERROR: " + ex + " just falling back to default error");
			this._processEnded(99999, done);
		}

		return this;
	}
}

export default Spawn;
<commit_msg>Handle stdio better in Distributor, don't rely on faulty on('data')<commit_after>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

import {spawn} from "child_process";

const tmp = require("tmp");
const fs = require("fs");
const kill = require("tree-kill");

const EXPOSE_REPLAY_PATH = "expoSE replay";

class Spawn {

	constructor(script, file, opts) {
		this.script = script;
		this.file = file;
		this.options = opts;
		this.args = [this.file.path, JSON.stringify(this.file.input)];
		this.tmpCoverageFile = tmp.fileSync();
		this.tmpOutFile = tmp.fileSync();

		this.env = JSON.parse(JSON.stringify(process.env));
		this.env.EXPOSE_OUT_PATH = this.tmpOutFile.name;
		this.env.EXPOSE_COVERAGE_PATH = this.tmpCoverageFile.name;
	}

	_tryParse(data, type, errors) {
		try {
			return JSON.parse(data);
		} catch (e) {
			errors.push({error: "Exception E: " + e + " of " + type + " on " + data});
			return null;
		}
	}

	startTime() {
		return this._startTime;
	}

	endTime() {
		return this._endTime;
	}

	time() {
		return this._endTime - this._startTime;
	}

	_recordEndTime() {
		this._endTime = (new Date()).getTime();
	}

	_processEnded(code, done) {

		this._recordEndTime();

		let me = this;
		let errors = [];
		let coverage = null;
		let finalOut = null;
		let count = 0;
		let test = this;

		function cb(err) {

			count++;

			if (err) {
				errors.push({error: err});
			}

			if (count == 2) {
				test.tmpOutFile.removeCallback();
				test.tmpCoverageFile.removeCallback();
				done(me, code, test, finalOut, coverage, errors);
			}
		}

		fs.readFile(this.tmpOutFile.name, {encoding: "utf8"}, function(err, data) {
			if (!err) {
				finalOut = test._tryParse(data, "test data", errors);
			}
			cb(err);
		});

		fs.readFile(this.tmpCoverageFile.name, {encoding: "utf8"}, function(err, data) {
			if (!err) {
				coverage = test._tryParse(data, "coverage data", errors);
			}
			cb(err);
		});
	}

	shellescape(a) {
		let ret = [];

		a.forEach(function(s) {

			if (/[^A-Za-z0-9_\/:=-]/.test(s)) {
				s = "'" + s.replace(/'/g, "'\\''") + "'";
			}

			ret.push(s);
		});

		return ret.join(" ");
	}

	_mkEnvReplay() {
		let envStr = "";
		for (let i in this.env) {
			envStr += i + "=\"" + this.env[i] + "\" ";
		}
		return envStr;
	}

	makeReplayString() {
		return /* this._mkEnvReplay() + */ EXPOSE_REPLAY_PATH + " " + this.shellescape(this.args);
	}

	kill() {
		kill(this._pid, "SIGKILL");
	}

	_buildTimeout() {
		return setTimeout(() => {
			this.kill();
		}, this.options.timeout);
	}

	start(done) {

		this._startTime = (new Date()).getTime();

		try {
			const stdio = this.options.log ? [0, 1, 2] : [0, null, null];
			const prc = spawn(this.script, this.args, {
				stdio: stdio,
				env: this.env,
				disconnected: false
			});

			prc.on("exit", code => {
				clearTimeout(this._killTimeout);
				this._processEnded(code, done);
			});

			this._killTimeout = this._buildTimeout();
			this._pid = prc.pid;
		} catch (ex) {
			console.log("Distributor ERROR: " + ex + " just falling back to default error");
			this._processEnded(99999, done);
		}

		return this;
	}
}

export default Spawn;
<|endoftext|>


<commit_before>/*
 * nssocket.js - Wraps a TLS/TCP socket to emit namespace events also auto-buffers.
 *
 * (C) 2011, Nodejitsu Inc.
 *
 */

var net = require('net'),
    tls = require('tls'),
    util = require('util'),
    events2 = require('eventemitter2'),
    Lazy = require('lazy'),
    common = require('./common');

//
// ### function NsSocket (socket, options)
// #### @socket {Object} TCP or TLS 'socket' either from a 'connect' 'new' or from a server
// #### @options {Object} Options for this NsSocket
// NameSpace Socket, NsSocket, is a thin wrapper above TLS/TCP.
// It provides automatic buffering and name space based data emits.
//
var NsSocket = exports.NsSocket = function (socket, options) {
  if (!(this instanceof NsSocket)) {
    return new NsSocket(socket, options);
  }

  //
  // If there is no Socket instnace to wrap,
  // create one.
  //
  if (!options) {
    options = socket;
    socket = common.createSocket(options);
  }

  //
  // Options should be
  //
  //    {
  //      type : 'tcp' or 'tls',
  //      delimiter : '::', delimiter that separates between segments
  //      msgLength : 3 //number of segments in a complete message
  //    }
  //
  options = options || {};

  var self = this,
      startName;

  //
  // Setup underlying socket state.
  //
  this.socket     = socket;
  this.connected  = options.connected || socket.writable && socket.readable || false;

  //
  // Setup reconnect options.
  //
  this._reconnect = options.reconnect  || false;
  this.retry      = {
    retries:  0,
    max:      options.maxRetries || 10,
    interval: options.retryInterval || 5000,
    wait:     options.retryInterval || 5000
  };

  //
  // Setup default instance variables.
  //
  this._options   = options;
  this._type      = options.type || 'tcp4',
  this._delimiter = options.delimiter || '::';

  events2.EventEmitter2.call(this, {
    delimiter: this._delimiter,
    wildcard: true,
    maxListeners: options.maxListeners || 10
  });

  this._setup();
};

//
// Inherit from `events2.EventEmitter2`.
//
util.inherits(NsSocket, events2.EventEmitter2);

//
// ### function createServer (options, connectionListener)
// #### @options {Object} **Optional**
// Creates a new TCP/TLS server which wraps every incoming connection
// in an instance of `NsSocket`.
//
exports.createServer = function createServer(options, connectionListener) {
  if (!connectionListener && typeof options === 'function') {
    connectionListener = options;
    options = {};
  }

  options.type      = options.type || 'tcp4';
  options.delimiter = options.delimiter || '::';

  function onConnection (socket) {
    connectionListener(new NsSocket(socket, options));
  }

  return options.type === 'tls'
    ? tls.createServer(options, onConnection)
    : net.createServer(options, onConnection);
};

//
// ### function send (data, callback)
// #### @event {Array|string} The array (or string) that holds the event name
// #### @data {Literal|Object} The data to be sent with the event.
// #### @callback {Function} the callback function when send is done sending
// The send function follows write/send rules for TCP/TLS/UDP
// in that the callback is called when sending is complete, not when delivered
//
NsSocket.prototype.send = function send(event, data, callback) {
  var dataType = typeof data,
      message;

  // rebinds
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  if (dataType === 'undefined' || dataType === 'function') {
    callback = data;
    data = null;
  }

  // if we aren't connected/socketed, then error
  if (!this.socket || !this.connected) {
    return this.emit('error', new Error('NsSocket: sending on a bad socket'));
  }

  message = Buffer(JSON.stringify(event.concat(data)) + '\n');

  if (this.socket.cleartext) {
    this.socket.cleartext.write(message, callback);
  }
  else {
    // now actually write to the socket
    this.socket.write(message, callback);
  }
};

//
// ### function data (event, callback)
// #### @event {Array|string} Namespaced `data` event to listen to.
// #### @callback {function} Continuation to call when the event is raised.
// Shorthand function for listening to `['data', '*']` events.
//
NsSocket.prototype.data = function (event, callback) {
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  this.on(['data'].concat(event), callback);
};

//
// ### function data (event, callback)
// #### @event {Array|string} Namespaced `data` event to listen to once.
// #### @callback {function} Continuation to call when the event is raised.
// Shorthand function for listening to `['data', '*']` events once.
//
NsSocket.prototype.dataOnce = function (event, callback) {
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  this.once(['data'].concat(event), callback);
};

//
// ### function setIdle (time, callback)
// #### @time {Integer} how often to emit idle
// Set the idle/timeout timer
//
NsSocket.prototype.setIdle = function setIdle(time) {
  this.socket.setTimeout(time);
  this._timeout = time;
};

//
// ### function destroy (void)
// #### forcibly destroys this nsSocket, unregister socket, remove all callbacks
//
NsSocket.prototype.destroy = function destroy() {
  // this should be forcibly remove EVERY listener
  this.removeAllListeners();

  if (this.socket) {
    try {
      this.socket.end(); // send FIN
      this.socket.destroy(); // make sure fd's are gone
    }
    catch (ex) {
      // do nothing on errors
    }
  }

  // clear buffer
  this.data = '';
  this.emit('destroy');
};

//
// ### function end (void)
// #### closes the underlying socket, recommend you call destroy after
//
NsSocket.prototype.end = function end() {
  var hadErr;
  this.connected = false;

  if (this.socket) {
    try {
      this.socket.end();
    }
    catch (ex) {
      this.emit('error', ex);
      hadErr = true;
      return;
    }

    this.socket = null;
  }

  return this.emit('close', hadErr || undefined);
};

//
// ### function connect (port[, host, callback])
// A passthrough to the underlying socket's connect function
//
NsSocket.prototype.connect = function connect(/*port, host, callback*/) {
  var args = Array.prototype.slice.call(arguments),
      self = this,
      callback,
      host,
      port;

  args.forEach(function handle(arg) {
    var type = typeof arg;
    switch (type) {
      case 'number':
        port = arg;
        break;
      case 'string':
        host = arg;
        break;
      case 'function':
        callback = arg;
        break;
      default:
        self.emit('error', new Error('bad argument to connect'));
        break;
    }
  });

  host = host || '127.0.0.1';
  this.port = port || this.port;
  this.host = host || this.host;
  args = [this.port, this.host];

  if (callback) {
    args.push(callback);
  }

  if (['tcp4', 'tls'].indexOf(this._type) === -1) {
    return this.emit('error', new Error('Unknown Socket Type'));
  }

  this.connected = true;
  this.socket.connect.apply(this.socket, args);
};

//
// ### function reconnect ()
// Attempts to reconnect the current socket on `close` or `error`.
// This instance will attempt to reconnect until `this.retry.max` is reached,
// with an interval increasing by powers of 10.
//
NsSocket.prototype.reconnect = function reconnect() {
  var self = this;

  //
  // Helper function containing the core reconnect logic
  //
  function doReconnect() {
    //
    // Cleanup and recreate the socket associated
    // with this instance.
    //
    self.retry.waiting = true;
    self.socket.removeAllListeners();
    self.socket = common.createSocket(self._options);

    //
    // Cleanup reconnect logic once the socket connects
    //
    self.socket.once('connect', function () {
      self.retry.waiting = false;
      self.retry.retries = 0;
    });

    //
    // Attempt to reconnect the socket
    //
    self._setup();
    self.connect();
  }

  //
  // Helper function which attempts to retry if
  // it is less than the maximum
  //
  function tryReconnect() {
    self.retry.retries++;
    if (self.retry.retries >= self.retry.max) {
      return self.emit('error', new Error('Did not reconnect after maximum retries: ' + self.retry.max));
    }

    doReconnect();
  }

  this.retry.wait = this.retry.interval * Math.pow(10, this.retry.retries);
  setTimeout(tryReconnect, this.retry.wait);
};

//
// ### @private function _setup ()
// Sets up the underlying socket associate with this instance.
//
NsSocket.prototype._setup = function () {
  var self = this,
      startName;

  //
  // Because of how the code node.js `tls` module works, we have
  // to separate some bindings. The main difference is on
  // connection, some socket activities.
  //
  if (this._type === 'tcp4') {
    startName = 'connect';

    Lazy(this.socket)
      .lines
      .map(String)
      .forEach(this._onData.bind(this));

    // create a stub for the setKeepAlive functionality
    this.setKeepAlive = function () {
      self.socket.setKeepAlive.apply(self.socket, arguments);
    };
  }
  else if (this._type === 'tls') {
    startName = 'secureConnection';
    this.socket.once('connect', function () {
      Lazy(self.socket.cleartext)
        .lines
        .map(String)
        .forEach(self._onData.bind(self));
    });

    // create a stub for the setKeepAlive functionality
    this.setKeepAlive = function () {
      self.socket.socket.setKeepAlive.apply(self.socket.socket, arguments);
    };
  }
  else {
    // bad arguments, so throw an error
    this.emit('error', new Error('Bad Option Argument [type]'));
    return null;
  }

  // make sure we listen to the underlying socket
  this.socket.on(startName, this._onStart.bind(this));
  this.socket.on('close',   this._onClose.bind(this));

  if (this.socket.socket) {
    //
    // otherwise we get a error passed from net.js
    // they need to backport the fix from v5 to v4
    //
    this.socket.socket.on('error', this._onError.bind(this));
  }

  this.socket.on('error',   this._onError.bind(this));
  this.socket.on('timeout', this._onIdle.bind(this));
};

//
// ### @private function _onStart ()
// Emits a start event when the underlying socket finish connecting
// might be used to do other activities.
//
NsSocket.prototype._onStart = function _onStart() {
  this.emit('start');
};

//
// ### @private function _onData (message)
// #### @message {String} literal message from the data event of the socket
// Messages are assumed to be delimited properly (if using nssocket to send)
// otherwise the delimiter should exist at the end of every message
// We assume messages arrive in order.
//
NsSocket.prototype._onData = function _onData(message) {
  var parsed,
      data;

  try {
    parsed = JSON.parse(message);
    data = parsed.pop();
    this.emit(['data'].concat(parsed), data)
  }
  catch (err) {
    //
    // Don't do anything, assume that the message is only partially
    // received.
    //
  }
};

//
// ### @private function _onClose (hadError)
// #### @hadError {Boolean} true if there was an error, which then include the
// actual error included by the underlying socket
//
NsSocket.prototype._onClose = function _onClose(hadError) {
  if (hadError) {
    this.emit('close', hadError, arguments[1]);
  }
  else {
    this.emit('close');
  }

  this.connected = false;
  if (this._reconnect) {
    this.reconnect();
  }
};

//
// ### @private function _onError (error)
// #### @error {Error} emits and error event in place of the socket
// Error event is raise with an error if there was one
//
NsSocket.prototype._onError = function _onError(error) {
  this.connected = false;

  if (!this._reconnect) {
    return this.emit('error', error || new Error('An Unknown Error occured'));
  }

  this.reconnect();
};

//
// ### @private function _onIdle ()
// #### Emits the idle event (based on timeout)
//
NsSocket.prototype._onIdle = function _onIdle() {
  this.emit('idle');
  if (this._timeout) {
    this.socket.setTimeout(this._timeout);
  }
};

<commit_msg>[fix api] Allow for listening on Unix pipe<commit_after>/*
 * nssocket.js - Wraps a TLS/TCP socket to emit namespace events also auto-buffers.
 *
 * (C) 2011, Nodejitsu Inc.
 *
 */

var net = require('net'),
    tls = require('tls'),
    util = require('util'),
    events2 = require('eventemitter2'),
    Lazy = require('lazy'),
    common = require('./common');

//
// ### function NsSocket (socket, options)
// #### @socket {Object} TCP or TLS 'socket' either from a 'connect' 'new' or from a server
// #### @options {Object} Options for this NsSocket
// NameSpace Socket, NsSocket, is a thin wrapper above TLS/TCP.
// It provides automatic buffering and name space based data emits.
//
var NsSocket = exports.NsSocket = function (socket, options) {
  if (!(this instanceof NsSocket)) {
    return new NsSocket(socket, options);
  }

  //
  // If there is no Socket instnace to wrap,
  // create one.
  //
  if (!options) {
    options = socket;
    socket = common.createSocket(options);
  }

  //
  // Options should be
  //
  //    {
  //      type : 'tcp' or 'tls',
  //      delimiter : '::', delimiter that separates between segments
  //      msgLength : 3 //number of segments in a complete message
  //    }
  //
  options = options || {};

  var self = this,
      startName;

  //
  // Setup underlying socket state.
  //
  this.socket     = socket;
  this.connected  = options.connected || socket.writable && socket.readable || false;

  //
  // Setup reconnect options.
  //
  this._reconnect = options.reconnect  || false;
  this.retry      = {
    retries:  0,
    max:      options.maxRetries || 10,
    interval: options.retryInterval || 5000,
    wait:     options.retryInterval || 5000
  };

  //
  // Setup default instance variables.
  //
  this._options   = options;
  this._type      = options.type || 'tcp4',
  this._delimiter = options.delimiter || '::';

  events2.EventEmitter2.call(this, {
    delimiter: this._delimiter,
    wildcard: true,
    maxListeners: options.maxListeners || 10
  });

  this._setup();
};

//
// Inherit from `events2.EventEmitter2`.
//
util.inherits(NsSocket, events2.EventEmitter2);

//
// ### function createServer (options, connectionListener)
// #### @options {Object} **Optional**
// Creates a new TCP/TLS server which wraps every incoming connection
// in an instance of `NsSocket`.
//
exports.createServer = function createServer(options, connectionListener) {
  if (!connectionListener && typeof options === 'function') {
    connectionListener = options;
    options = {};
  }

  options.type      = options.type || 'tcp4';
  options.delimiter = options.delimiter || '::';

  function onConnection (socket) {
    connectionListener(new NsSocket(socket, options));
  }

  return options.type === 'tls'
    ? tls.createServer(options, onConnection)
    : net.createServer(options, onConnection);
};

//
// ### function send (data, callback)
// #### @event {Array|string} The array (or string) that holds the event name
// #### @data {Literal|Object} The data to be sent with the event.
// #### @callback {Function} the callback function when send is done sending
// The send function follows write/send rules for TCP/TLS/UDP
// in that the callback is called when sending is complete, not when delivered
//
NsSocket.prototype.send = function send(event, data, callback) {
  var dataType = typeof data,
      message;

  // rebinds
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  if (dataType === 'undefined' || dataType === 'function') {
    callback = data;
    data = null;
  }

  // if we aren't connected/socketed, then error
  if (!this.socket || !this.connected) {
    return this.emit('error', new Error('NsSocket: sending on a bad socket'));
  }

  message = Buffer(JSON.stringify(event.concat(data)) + '\n');

  if (this.socket.cleartext) {
    this.socket.cleartext.write(message, callback);
  }
  else {
    // now actually write to the socket
    this.socket.write(message, callback);
  }
};

//
// ### function data (event, callback)
// #### @event {Array|string} Namespaced `data` event to listen to.
// #### @callback {function} Continuation to call when the event is raised.
// Shorthand function for listening to `['data', '*']` events.
//
NsSocket.prototype.data = function (event, callback) {
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  this.on(['data'].concat(event), callback);
};

//
// ### function data (event, callback)
// #### @event {Array|string} Namespaced `data` event to listen to once.
// #### @callback {function} Continuation to call when the event is raised.
// Shorthand function for listening to `['data', '*']` events once.
//
NsSocket.prototype.dataOnce = function (event, callback) {
  if (typeof event === 'string') {
    event = event.split(this._delimiter);
  }

  this.once(['data'].concat(event), callback);
};

//
// ### function setIdle (time, callback)
// #### @time {Integer} how often to emit idle
// Set the idle/timeout timer
//
NsSocket.prototype.setIdle = function setIdle(time) {
  this.socket.setTimeout(time);
  this._timeout = time;
};

//
// ### function destroy (void)
// #### forcibly destroys this nsSocket, unregister socket, remove all callbacks
//
NsSocket.prototype.destroy = function destroy() {
  // this should be forcibly remove EVERY listener
  this.removeAllListeners();

  if (this.socket) {
    try {
      this.socket.end(); // send FIN
      this.socket.destroy(); // make sure fd's are gone
    }
    catch (ex) {
      // do nothing on errors
    }
  }

  // clear buffer
  this.data = '';
  this.emit('destroy');
};

//
// ### function end (void)
// #### closes the underlying socket, recommend you call destroy after
//
NsSocket.prototype.end = function end() {
  var hadErr;
  this.connected = false;

  if (this.socket) {
    try {
      this.socket.end();
    }
    catch (ex) {
      this.emit('error', ex);
      hadErr = true;
      return;
    }

    this.socket = null;
  }

  return this.emit('close', hadErr || undefined);
};

//
// ### function connect (port[, host, callback])
// A passthrough to the underlying socket's connect function
//
NsSocket.prototype.connect = function connect(/*port, host, callback*/) {
  var args = Array.prototype.slice.call(arguments),
      self = this,
      callback,
      host,
      port;

  args.forEach(function handle(arg) {
    var type = typeof arg;
    switch (type) {
      case 'number':
        port = arg;
        break;
      case 'string':
        host = arg;
        break;
      case 'function':
        callback = arg;
        break;
      default:
        self.emit('error', new Error('bad argument to connect'));
        break;
    }
  });

  host = host || '127.0.0.1';
  this.port = port || this.port;
  this.host = host || this.host;
  args = this.port ? [this.port, this.host] : [this.host];

  if (callback) {
    args.push(callback);
  }

  if (['tcp4', 'tls'].indexOf(this._type) === -1) {
    return this.emit('error', new Error('Unknown Socket Type'));
  }

  this.connected = true;
  this.socket.connect.apply(this.socket, args);
};

//
// ### function reconnect ()
// Attempts to reconnect the current socket on `close` or `error`.
// This instance will attempt to reconnect until `this.retry.max` is reached,
// with an interval increasing by powers of 10.
//
NsSocket.prototype.reconnect = function reconnect() {
  var self = this;

  //
  // Helper function containing the core reconnect logic
  //
  function doReconnect() {
    //
    // Cleanup and recreate the socket associated
    // with this instance.
    //
    self.retry.waiting = true;
    self.socket.removeAllListeners();
    self.socket = common.createSocket(self._options);

    //
    // Cleanup reconnect logic once the socket connects
    //
    self.socket.once('connect', function () {
      self.retry.waiting = false;
      self.retry.retries = 0;
    });

    //
    // Attempt to reconnect the socket
    //
    self._setup();
    self.connect();
  }

  //
  // Helper function which attempts to retry if
  // it is less than the maximum
  //
  function tryReconnect() {
    self.retry.retries++;
    if (self.retry.retries >= self.retry.max) {
      return self.emit('error', new Error('Did not reconnect after maximum retries: ' + self.retry.max));
    }

    doReconnect();
  }

  this.retry.wait = this.retry.interval * Math.pow(10, this.retry.retries);
  setTimeout(tryReconnect, this.retry.wait);
};

//
// ### @private function _setup ()
// Sets up the underlying socket associate with this instance.
//
NsSocket.prototype._setup = function () {
  var self = this,
      startName;

  //
  // Because of how the code node.js `tls` module works, we have
  // to separate some bindings. The main difference is on
  // connection, some socket activities.
  //
  if (this._type === 'tcp4') {
    startName = 'connect';

    Lazy(this.socket)
      .lines
      .map(String)
      .forEach(this._onData.bind(this));

    // create a stub for the setKeepAlive functionality
    this.setKeepAlive = function () {
      self.socket.setKeepAlive.apply(self.socket, arguments);
    };
  }
  else if (this._type === 'tls') {
    startName = 'secureConnection';
    this.socket.once('connect', function () {
      Lazy(self.socket.cleartext)
        .lines
        .map(String)
        .forEach(self._onData.bind(self));
    });

    // create a stub for the setKeepAlive functionality
    this.setKeepAlive = function () {
      self.socket.socket.setKeepAlive.apply(self.socket.socket, arguments);
    };
  }
  else {
    // bad arguments, so throw an error
    this.emit('error', new Error('Bad Option Argument [type]'));
    return null;
  }

  // make sure we listen to the underlying socket
  this.socket.on(startName, this._onStart.bind(this));
  this.socket.on('close',   this._onClose.bind(this));

  if (this.socket.socket) {
    //
    // otherwise we get a error passed from net.js
    // they need to backport the fix from v5 to v4
    //
    this.socket.socket.on('error', this._onError.bind(this));
  }

  this.socket.on('error',   this._onError.bind(this));
  this.socket.on('timeout', this._onIdle.bind(this));
};

//
// ### @private function _onStart ()
// Emits a start event when the underlying socket finish connecting
// might be used to do other activities.
//
NsSocket.prototype._onStart = function _onStart() {
  this.emit('start');
};

//
// ### @private function _onData (message)
// #### @message {String} literal message from the data event of the socket
// Messages are assumed to be delimited properly (if using nssocket to send)
// otherwise the delimiter should exist at the end of every message
// We assume messages arrive in order.
//
NsSocket.prototype._onData = function _onData(message) {
  var parsed,
      data;

  try {
    parsed = JSON.parse(message);
    data = parsed.pop();
    this.emit(['data'].concat(parsed), data)
  }
  catch (err) {
    //
    // Don't do anything, assume that the message is only partially
    // received.
    //
  }
};

//
// ### @private function _onClose (hadError)
// #### @hadError {Boolean} true if there was an error, which then include the
// actual error included by the underlying socket
//
NsSocket.prototype._onClose = function _onClose(hadError) {
  if (hadError) {
    this.emit('close', hadError, arguments[1]);
  }
  else {
    this.emit('close');
  }

  this.connected = false;
  if (this._reconnect) {
    this.reconnect();
  }
};

//
// ### @private function _onError (error)
// #### @error {Error} emits and error event in place of the socket
// Error event is raise with an error if there was one
//
NsSocket.prototype._onError = function _onError(error) {
  this.connected = false;

  if (!this._reconnect) {
    return this.emit('error', error || new Error('An Unknown Error occured'));
  }

  this.reconnect();
};

//
// ### @private function _onIdle ()
// #### Emits the idle event (based on timeout)
//
NsSocket.prototype._onIdle = function _onIdle() {
  this.emit('idle');
  if (this._timeout) {
    this.socket.setTimeout(this._timeout);
  }
};

<|endoftext|>


<commit_before>"use strict";

module.exports = local;
local.usage = ["",
        "fhc local proxy=<true|false> app=<appId> domain=<domain> port=<port> packages=<package[,package...]> watch=<true|false>",
        "Run from app root. All params are optional",
        "",
        "'domain' is the domain where your the app is hosted (For example: 'http://apps.feedhenry.com' - domain=apps)",
        "'proxy' specifies whether act calls should be handled locally or proxied to the feedhenry cloud, defaults to false",
        "'port' is not required, the default port is 8888",
        "'packages' is not required, packages are used to tell the server where to look for files. Multiple packages can be specified, seperated by a ','",
        "'watch' only applies if proxy=false, if true, any changes to the cloud code will be reloaded automatically without having to restart the server. watch defaults to true",
        ""].join("\n");

var http = require("http"),
  https = require("https"),
  url = require("url"),
  path = require("path"),
  fs = require("fs"),
  util = require("util"),
  events = require("events"),
  common = require("./common"),
  log = require("./utils/log"),
  fhc = require("./fhc"),
  hosts = require("./hosts"),
  mimeTypes = {
    json: "application/json",
    js: "text/javascript",
    css: "text/css",
    html: "text/html",
    xml: "text/xml",
    txt: "text/plain",
    woff: "font/opentype"
  },
  defaultArgs = {
    baseDomain: { required: true,
      val: "feedhenry.com",
      type: "string"
    },
    port: {
      required: true,
      val: 8888,
      type: "number"
    },
    domain: {
      required: true,
      val: "apps",
      type: "string"
    },
    app: {
      required: true,
      val: "localguidplaceholder",
      type: "guid"
    },
    packages: {
      required: false,
      type: "array"
    },
    index: {
      required: true,
      val: "index.html",
      type: "string"
    },
    proxy: {
      required: true,
      val: "false",
      type: "boolean"
    },
    watch: {
      required: true,
      val: "true",
      type: "boolean"
    }
  };

fs.exists = fs.exists || path.exists;
fs.existsSync = fs.existsSync || path.existsSync;

function tryParse(data, defaultVal) {
  var res;
  try {
    res = JSON.parse(data);
  }
  catch(e) {
    res = defaultVal;
  }
  return res;
}

function validateArgs(args) {
  for(var i in defaultArgs) {
    var defaultArg = defaultArgs[i],
      currentArg = args[i];
    if(args[i] === undefined) {

      if(defaultArg.required) {
        if(!defaultArg.val) {
          throw new Error("Missing '" + i + "' parameter");
        }
        else if(defaultArg.val) {
          currentArg = args[i] = defaultArg.val;
        }
      }
    }
    if(currentArg !== undefined) {
      switch(defaultArg.type) {
        case "boolean":
          args[i] = typeof currentArg === "boolean" ? currentArg : currentArg === "true" ? true : false;
          break;
        case "array":
          args[i] = currentArg.split(defaultArg.delim || ",");
          break;
        case "guid":
          args[i] = fhc.appId(currentArg);
          break;
        case "number":
          args[i] = parseInt(currentArg, 10);
          break;
      }
    }
  }
}

function local(args, cb) {
  var argObj;
  try {
    argObj = common.parseArgs(args);
    validateArgs(argObj);
  } catch (x) {
    return cb("Error processing args: " + x + "\nUsage: " + local.usage);
  }

  var staticHandler = new StaticHandler(argObj),
    actHandler = argObj.proxy ? new RemoteActHandler(argObj) : new LocalActHandler(argObj);

  var server = http.createServer(function(request, response) {
    if (request.url === '/box/srv/1.1/app/init') {
      response.end(JSON.stringify({"domain":"apps","firstTime":false,"hosts":{"debugCloudType":"fh","debugCloudUrl":"http://127.0.0.1:8888","releaseCloudType":"fh","releaseCloudUrl":"http://127.0.0.1:8888"},"status":"ok"}));
    }
    else if(actHandler.canHandle(request)) {
      actHandler.handleRequest(request, response);
    }
    else if(staticHandler.canHandle(request)) {
      staticHandler.handleRequest(request, response);
    }
    else response.end();
  });
  server.on("error", cb);
  staticHandler.on("error", cb);
  actHandler.on("error", cb);

  try {
    server.listen(argObj.port);
  }
  catch(e) {
    return cb(e);
  }
  console.log("server listening on port:", argObj.port);
  console.log("go to http://127.0.0.1:" + argObj.port + "/ in your browser");
}

function RequestHandler(options) {
  options = options || {};
  this.subDomain = options.domain || "apps";
  this.baseDomain = options.baseDomain || "feedhenry.com";
  this.target = this.subDomain + "." + options.baseDomain;
  this.guid = options.app || options.guid || "";
}
util.inherits(RequestHandler, events.EventEmitter);
RequestHandler.prototype.handleError = function(e, res) {
  this.emit("error", e);
};
RequestHandler.prototype.handleRequest = function(request, response) {};

// this might need a callback, however for now, it's unlikely that any changes
// will be made in the milliseconds that it takes to do this...provided that you
//haven't got a *huge* set of dependencies
RequestHandler.prototype.listenTo = function(directory, recursive) {
  var self = this;
  var timeout;

  if(!fs.statSync(directory).isDirectory()) {
    this.handleError(new Error("\"" + directory + "\" is not a directory" ));
  }

  if(recursive) {
    fs.readdir(directory, function(err, files) {

      for(var i = 0, il = files.length; i < il; i++) {
        var file = path.join(directory, files[i]);

        if(fs.statSync(file).isDirectory()) {
          self.listenTo(file, true);
        }
      }

    });
  }

  fs.watch(directory, function(e, filename) {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
      self.handleFileSystemChange(e, filename);
    }, 10);
  });
};
RequestHandler.prototype.handleFileSystemChange = function() {};

function ActHandler(options) {
  options = options || {};
  RequestHandler.call(this, options);
}
util.inherits(ActHandler, RequestHandler);

ActHandler.prototype.canHandle = function(request) {
  return request.method === "POST";
};

// remote act handler
// proxies act requests to the feedhenry cloud and
// writes the response back to the client
function RemoteActHandler(options) {
  options = options || {};
  ActHandler.call(this, options);

  var self = this,
    env = this.env = options.env === "dev" ? "development" : options.env !== undefined ? options.env : "millicore";

  // set up access to proper node endpoint, without proxy through millicore
  switch (options.env) {
    case "dev":
    case "live":
      hosts([this.guid], function(err, res) {
        if(err) {
          //leave defaults
          return;
        }
        self.target = url.parse(res.hosts[env + "-url"]).hostname;
      });
      break;
  }
}
util.inherits(RemoteActHandler, ActHandler);

// unwanted headers that mess up responses from millicore
var UNWANTED_HEADERS = [
  "host",
  "origin",
  "accept-encoding"
];

RemoteActHandler.prototype.requireHeaders = function(requestHeaders) {
  for(var i = 0, il = UNWANTED_HEADERS.length; i < il; i++) {
    delete requestHeaders[UNWANTED_HEADERS[i]];
  }
  return requestHeaders;
};

RemoteActHandler.prototype.handleRequest = function(request, response) {
  var requestParams = url.parse(request.url, true),
    uri = requestParams.pathname,
    uriComponents = uri.split("/"),
    act = uriComponents[uriComponents.length - 2],
    params = "";

  log.silly("Proxying act request");
  log.silly(uri, "url");
  log.silly(act, "act");

  var opts = {
    path: this.env === "millicore" ? uri : "/cloud/" + act,
    method: request.method,
    host: this.target,
    headers: this.requireHeaders(request.headers)
  };

  log.silly(opts, "request options");

  var proxyReq = https.request(opts, function(proxyRes) {
    response.writeHead(proxyRes.statusCode, proxyRes.headers);

    proxyRes.on("data", function(chunk) {
      response.write(chunk.toString());
    });
    proxyRes.on("end", function() {
      response.end();
    });
  });

  request.on("data", function(chunk) {
    params += chunk.toString();
    proxyReq.write(chunk.toString());
  });

  request.on("end", function() {
    var parsedParams;
    try {
      parsedParams = JSON.parse(params);
      log.silly(parsedParams,"params");
    }
    catch(e) {
      log.silly(params,"params");
    }
    proxyReq.end();
  });

};

// local act handler
// handles act request locally
function LocalActHandler(options) {
  options = options || {};
  ActHandler.call(this, options);

  this.cloud = options.cloud || "./cloud/";
  this.main = options.main || "main.js";
  this.watch = options.watch !== undefined ? options.watch : true;
  this.env = null;
  this.legacy = false;
  this.init();

  if(this.watch) {
    this.listenTo(this.cloud, true);
  }
}
util.inherits(LocalActHandler, ActHandler);

LocalActHandler.prototype.handleFileSystemChange = function(e, filename) {
  this.init();
};

LocalActHandler.prototype.init = function() {
  var env;

  console.log("loading cloud code...");

  try {
    var cloudPath = require.resolve(path.join(process.cwd(), this.cloud, this.main));
    //clear the required cloud code from the cache
    //as we won't be requiring anything again here for the local server,
    //it's safe enough to just nuke the cache
    //Module holds an internal reference to the cache which is modified,
    //so we have to loop through all the items in the cache and delete them one by one...
    var cache = require.cache;
    for(var i in cache) if(cache.hasOwnProperty(i)) {
      delete cache[i];
    }
    env = require(cloudPath);

    if(!Object.keys(env).length) {
      this.handleError(new Error("Looks like you didn't export any functions. Is this a rhino app?"));
    }
    if(env) {
      this.env = env;
      console.log("cloud code loaded...");
    }
  }
  catch(e) {
    if(this.env) {
      //we have an environment loaded but we got an error trying to reload
      log.error("Failed to reload environment, using current version");
      log.error(e);
    }
    else {
      log.error(e);
      this.handleError(new Error("Cannot load cloud code"));
    }
  }
};

LocalActHandler.prototype.handleRequest = function(request, response) {
  var self = this,
    uri = request.url,
    uriComponents = uri.split("/"),
    paramString = "",
    act = uriComponents[uriComponents.length - 2];

  log.silly("Handling act request locally");
  log.silly(uri, "url");
  log.silly(act, "act");

  request.on("data", function(chunk) {
    paramString += chunk.toString();
  });

  request.on("end", function() {
    var params = tryParse(paramString, null),
      env = self.env;

    // include headers set by client
    params = params || {};
    params._headers = request.headers;
    log.silly(params, "params");

    if(env.hasOwnProperty(act)) {
      return env[act](params, function(err, data, headers) {
        if(err) {
          return self.handleScriptError(err, act, response);
        }

        headers = headers || {};
        headers["content-type"] = headers["content-type"] || mimeTypes.json;

        response.writeHead(200, headers);
        response.end(typeof data !== "string" ? JSON.stringify(data) : data);
      });
    }
    else {
      return self.handle404Error(act, response);
    }
  });
};

LocalActHandler.prototype.handleScriptError = function(err, act, response) {
  response.writeHead(500);
  var error = {
    msg: "Internal error in " + act + ": " + err.message,
    error: JSON.stringify(err)
  };
  response.end(JSON.stringify(error));
};

LocalActHandler.prototype.handle404Error = function(act, response) {
  response.writeHead(404);
  response.end(JSON.stringify({
    error:"Error: no such function: " + act
  }));
};

// static file handler
// handles searching through package directories and
// writing files
function StaticHandler(options) {
  RequestHandler.call(this, options);

  this.index = options.main || "index.html";
  this.initParams = JSON.stringify({
    appMode: "debug",
    checkDeliveryScheme:true,
    debugCloudType:"fh",
    destination:{
      inline:false,
      name:"studio"
    },
    domain: this.subDomain,
    releaseCloudType:"fh",
    releaseCloudUrl:"https://",
    user: { id:"123456789", role: "sub" },
    widget: {
      guid: this.guid,
      inline:false,
      instance: this.guid,
      version:333
    }
  });
  this.packages = (options.packages || []).concat("default", "../shared");
}
util.inherits(StaticHandler, RequestHandler);

StaticHandler.prototype.canHandle = function(request) {
  return request.method === "GET";
};

StaticHandler.prototype.handleRequest = function(request, response) {
  var self = this,
    requestParams = url.parse(request.url, true),
    uri = requestParams.pathname;

  this.getPackageFile(uri, function(exists, filename) {
    if(!exists) {
      response.writeHead(404);
      return response.end("Not found\n");
    }
    fs.readFile(filename, "binary", function(err, file) {
      if(err) {
        response.writeHead(500);
        return response.end(err + "\n");
      }

      response.writeHead(200, {
        "content-type": mimeTypes[filename.split(".").pop()] || mimeTypes.txt
      });

      if(filename.indexOf(self.index) >= 0) {
        response.end(self.buildIndex(file, requestParams.query));
      }
      else {
        response.end(file, "binary");
      }
    });
  });
};

StaticHandler.prototype.getPackageFile = function(uri, cb) {
  var lookupIndex = 0,
    packages = this.packages,
    self = this;

  (function checkNextPath() {
    var filename = path.join(process.cwd(), "client", packages[lookupIndex++], uri);

    fs.exists(filename, function(exists) {
      if(!exists) {//try the next one
        if(lookupIndex >= packages.length) {
          cb(false);
        }
        else {
          checkNextPath();
        }
      }
      else if (fs.statSync(filename).isDirectory()) {
        //special case for directories
        //check is index.html available
        uri += '/' + self.index;
        lookupIndex--;
        checkNextPath();
      }
      else {
        cb(true, filename);
      }
    });
  })();

};

StaticHandler.prototype.buildIndex = function(file, requestQuery) {
  var html = new Element("html"),
    head = new Element("head"),
    body = new Element("body"),
    apiScript = new Element("script"),
    contentType = new Element("meta"),
    sdkInitScript = new Element("script"),
    sdkScript = new Element("script"),
    sdkConfigScript = new Element("script"),
    sdkStyle = new Element("style");

  contentType.setAttribute("http-equiv", "Content-Type" );
  contentType.setAttribute("content", "text/html; charset=utf-8");

  if(requestQuery.device !== undefined && requestQuery.version !== undefined) {
    var viewport = new Element("meta");
    viewport.setAttribute("name", "viewport");
    viewport.setAttribute("content", "width=device-width, height=device-height, user-scalable=no");
    apiScript.setAttribute("src", "http://" +
      this.target + "/static/mac/script/" +
      requestQuery.device + "_" +
      requestQuery.version + "/167-scripts.js");

    head.append(viewport);
  }
  else {
    sdkScript.setAttribute("src", "https://demo3.feedhenry.com/static/pec/script/studio/0-scripts.js");
  }

  sdkConfigScript.append('var fh_destination_code = \'studio\';' +
    'var fh_app_version = \'0\';' +
    'var fh_config = {host: "http://127.0.0.1:8888",appid: "localguidplaceholder",appkey: "localappkeyplaceholder",mode: "dev"};');
  sdkInitScript.append("$fh.ready({}, function(){$fh.init(fh_config);});");

  //head.append(contentType, apiScript, sdkInitScript);
  head.append(contentType, sdkConfigScript, sdkScript, sdkInitScript, sdkStyle);
  body.setAttribute('style', 'margin:0;padding:0');
  body.append(file);
  html.append(head, body);

  return "<!doctype html>" + html.toString();
};

//used for creating html files
function Element(tag) {
  this.tag = tag;
  this.children = [];
  this.attributes = {};
}
Element.prototype = {
  append: function() {
    Array.prototype.push.apply(this.children, arguments);
  },
  setAttribute: function(key, value) {
    this.attributes[key] = value;
  },
  toString: function() {
    var attributes = this.attributes,
      children = this.children,
      tag = this.tag,
      string = "<" + tag;

    for(var key in attributes) {
      string += " " + key + "=\"" + attributes[key] + "\"";
    }
    return string + ">" + children.join("") + "</" + tag + ">";
  }
};
<commit_msg>remove unused file<commit_after><|endoftext|>


<commit_before>'use strict';

var modelos = require('modelos');
var importarXml = require('componentes/importar-xml-v3');
var exportarXml = require('componentes/exportar-xml');
var salvarXml = require('componentes/salvar-xml');
var slugify = require('slugify');
var carregarServico = require('carregar-servico');

module.exports = {
  controller: function () {
    this.cabecalho = new modelos.Cabecalho();
    this.servico = carregarServico(m.route.param('id'), this.cabecalho);

    this.salvar = function () {
      return salvarXml(slugify(this.servico().nome()), exportarXml(this.servico()), this.cabecalho.metadados)
        .then(function(xml) {
          modelos.id.reset();
          return importarXml(xml);
        })
        .then(this.servico)
        .then(_.bind(this.cabecalho.limparErro, this.cabecalho), _.bind(function () {
          this.cabecalho.tentarNovamente(_.bind(this.salvar, this));
        }, this));
    };
  },

  view: function (ctrl) {
    var binding = {
      servico: ctrl.servico
    };

    var salvarAutomaticamente = _.debounce(ctrl.salvar.bind(ctrl), 300);

    return m('', [
      m.component(require('componentes/cabecalho'), {
        cabecalho: ctrl.cabecalho
      }),

      m.component(require('componentes/menu-lateral'), binding),

      m('#principal.auto-grid', {
        onchange: salvarAutomaticamente,
        onclick: _.wrap(salvarAutomaticamente, function (fn, e) {
          var target = jQuery(e.target);
          if (target.is('button') || target.parents('button').size() > 0) {
            return salvarAutomaticamente(e);
          }
        })
      }, [
        m.component(require('componentes/dados-basicos'), binding),
        m.component(require('componentes/solicitantes'), binding),
        m.component(require('componentes/etapas'), binding),
        m.component(require('componentes/dados-complementares'), binding),
      ])
    ]);
  }

};
<commit_msg>Aumenta o tempo de debounce para conexões mais lentas<commit_after>'use strict';

var modelos = require('modelos');
var importarXml = require('componentes/importar-xml-v3');
var exportarXml = require('componentes/exportar-xml');
var salvarXml = require('componentes/salvar-xml');
var slugify = require('slugify');
var carregarServico = require('carregar-servico');

module.exports = {
  controller: function () {
    this.cabecalho = new modelos.Cabecalho();
    this.servico = carregarServico(m.route.param('id'), this.cabecalho);

    this.salvar = function () {
      return salvarXml(slugify(this.servico().nome()), exportarXml(this.servico()), this.cabecalho.metadados)
        .then(function(xml) {
          modelos.id.reset();
          return importarXml(xml);
        })
        .then(this.servico)
        .then(_.bind(this.cabecalho.limparErro, this.cabecalho), _.bind(function () {
          this.cabecalho.tentarNovamente(_.bind(this.salvar, this));
        }, this));
    };
  },

  view: function (ctrl) {
    var binding = {
      servico: ctrl.servico
    };

    var salvarAutomaticamente = _.debounce(_.bind(ctrl.salvar, ctrl), 2000, {
      leading: false
    });

    return m('', [
      m.component(require('componentes/cabecalho'), {
        cabecalho: ctrl.cabecalho
      }),

      m.component(require('componentes/menu-lateral'), binding),

      m('#principal.auto-grid', {
        onchange: salvarAutomaticamente,
        onclick: _.wrap(salvarAutomaticamente, function (fn, e) {
          var target = jQuery(e.target);
          if (target.is('button') || target.parents('button').size() > 0) {
            return salvarAutomaticamente(e);
          }
        })
      }, [
        m.component(require('componentes/dados-basicos'), binding),
        m.component(require('componentes/solicitantes'), binding),
        m.component(require('componentes/etapas'), binding),
        m.component(require('componentes/dados-complementares'), binding),
      ])
    ]);
  }

};
<|endoftext|>


<commit_before>/*
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*jslint bitwise:true */
/*global esmangle:true, exports:true, define:true*/
(function (factory, global) {
    'use strict';

    function namespace(str, obj) {
        var i, iz, names, name;
        names = str.split('.');
        for (i = 0, iz = names.length; i < iz; ++i) {
            name = names[i];
            if (obj.hasOwnProperty(name)) {
                obj = obj[name];
            } else {
                obj = (obj[name] = {});
            }
        }
        return obj;
    }

    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
    // and plain browser loading,
    if (typeof define === 'function' && define.amd) {
        define('esmangle/common', ['exports'], factory);
    } else if (typeof exports !== 'undefined') {
        factory(exports);
    } else if (typeof window !== 'undefined') {
        factory(namespace('esmangle.optimizer', window));
    } else {
        factory(namespace('esmangle.optimizer', global));
    }
}(function (exports) {
    'use strict';

    var statuses, passes;

    function addPass(pass) {
        var name;
        if (typeof pass !== 'function') {
            // automatic lookup pass (esmangle pass format)
            name = Object.keys(pass)[0];
            pass = pass[name];
        }
        if (pass.hasOwnProperty('passName')) {
            name = pass.passName;
        } else {
            name = pass.name;
        }
        passes.push(pass);
        statuses.push(false);
    }

    function fillStatuses(i, last, bool) {
        for (; i < last; ++i) {
            statuses[i] = bool;
        }
    }

    function run(tree) {
        var i, iz, pass, res, sl, changed;
        sl = statuses.length;
        fillStatuses(0, sl, true);
        do {
            changed = false;
            for (i = 0, iz = sl; i < iz; ++i) {
                pass = passes[i];
                if (statuses[i]) {
                    res = pass(tree, { destructive: false });
                    if (res.modified) {
                        changed = true;
                        fillStatuses(0, i, true);
                        fillStatuses(i + 1, sl, true);
                    }
                    statuses[i] = false;
                    tree = res.result;
                }
            }
        } while (changed);
        return tree;
    }

    function optimize(tree, p) {
        var i, iz;

        statuses = [];
        passes = [];

        for (i = 0, iz = p.length; i < iz; ++i) {
            addPass(p[i]);
        }

        return run(tree);
    }

    exports.optimize = optimize;
}, this));
/* vim: set sw=4 ts=4 et tw=80 : */
<commit_msg>Refactoring optimization pass<commit_after>/*
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*jslint bitwise:true */
/*global esmangle:true, exports:true, define:true*/
(function (factory, global) {
    'use strict';

    function namespace(str, obj) {
        var i, iz, names, name;
        names = str.split('.');
        for (i = 0, iz = names.length; i < iz; ++i) {
            name = names[i];
            if (obj.hasOwnProperty(name)) {
                obj = obj[name];
            } else {
                obj = (obj[name] = {});
            }
        }
        return obj;
    }

    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
    // and plain browser loading,
    if (typeof define === 'function' && define.amd) {
        define('esmangle/common', ['exports'], factory);
    } else if (typeof exports !== 'undefined') {
        factory(exports);
    } else if (typeof window !== 'undefined') {
        factory(namespace('esmangle.optimizer', window));
    } else {
        factory(namespace('esmangle.optimizer', global));
    }
}(function (exports) {
    'use strict';

    var statuses, passes;

    function addPass(pass) {
        var name;
        if (typeof pass !== 'function') {
            // automatic lookup pass (esmangle pass format)
            name = Object.keys(pass)[0];
            pass = pass[name];
        }
        if (pass.hasOwnProperty('passName')) {
            name = pass.passName;
        } else {
            name = pass.name;
        }
        passes.push(pass);
        statuses.push(true);
    }

    function fillStatuses(bool) {
        var i, iz;
        for (i = 0, iz = statuses.length; i < iz; ++i) {
            statuses[i] = bool;
        }
    }

    function run(tree) {
        var i, iz, pass, res, changed;
        do {
            changed = false;
            for (i = 0, iz = passes.length; i < iz; ++i) {
                pass = passes[i];
                if (statuses[i]) {
                    res = pass(tree, { destructive: false });
                    if (res.modified) {
                        changed = true;
                        fillStatuses(true);
                    } else {
                        statuses[i] = false;
                    }
                    tree = res.result;
                }
            }
        } while (changed);
        return tree;
    }

    function optimize(tree, p) {
        var i, iz;

        statuses = [];
        passes = [];

        for (i = 0, iz = p.length; i < iz; ++i) {
            addPass(p[i]);
        }

        return run(tree);
    }

    exports.optimize = optimize;
}, this));
/* vim: set sw=4 ts=4 et tw=80 : */
<|endoftext|>