<commit_before>angular.module('starter.services', [])

/**
 * A simple example service that returns some data.
 */
.factory('Friends', function(SocketManager, Sign) {
  // Might use a resource here that returns a JSON array

  // Some fake testing data
  var friends = [];
  var friendNames = [];
  var loginUserId = Sign.getUser().userId;

  return {
    all: function() {
      return friends;
    },
    add: function(userIds, callback) {
      SocketManager.get( function( socket ){
        socket.emit( 'group-add', {'userIds':userIds, 'groupId' : loginUserId}, function( data ){
          callback( data );
        });
      });
    },
    get: function(friendId) {
      // Simple index lookup
      return friends[friendId];
    },
    list : function(callback){

      SocketManager.get( function( socket ){
        socket.emit( 'group-list', {'groupId':loginUserId}, function( data ){
          if( data.status == 'ok' ){
            var users = data.result;
            console.log( users );
            var jnx = 0;
            for( var inx = 0 ; inx < users.length ; inx++ ){
              if( users[inx].userId != loginUserId ){
                if( friendNames.indexOf( users[inx].userId ) < 0 ){
                  friendNames.push( users[inx].userId );
                  friends.push( { 'id' : jnx++, 'userId' : users[inx].userId, 'userName': users[inx].datas.name,
                    'message' : users[inx].datas.message, 'image': users[inx].datas.image  } );
                }
              }
            }

            callback( friends );
          }
        });
      });
    }
  }
})
.factory('Users', function(SocketManager, Sign) {
  // Might use a resource here that returns a JSON array
  var loginUserId = Sign.getUser().userId;

  // Some fake testing data
  var users = [];
  var userIds = [];

  return {
    all: function() {
      return users;
    },
    get: function(userId) {
      // Simple index lookup
      return users[userId];
    },
    list : function(callback){

      SocketManager.get( function( socket ){
        socket.emit( 'user-list', {}, function( data ){
          console.log( 'user-list' );
          if( data.status == 'ok' ){
            var userArray = data.result;
            console.log( userArray );
            var jnx = 0;
            for( var inx = 0 ; inx < userArray.length ; inx++ ){
              var tmpUserId = userArray[inx].userId;
              if( tmpUserId != loginUserId ){
                if( userIds.indexOf( tmpUserId ) < 0 ){
                  userIds.push( tmpUserId );
                  users.push( { 'id' : jnx++, 'userId' : userArray[inx].userId, 'userName': userArray[inx].datas.name,
                    'message' : users[inx].datas.message, 'image': userArray[inx].datas.image } );
                }
              }
            }

            console.log( "users");
            console.log( users );
            callback( users );
          }
        });
      });
    }
  }
})
.factory('Channels', function(DB, UTIL, APP_INFO) {
  // Might use a resource here that returns a JSON array
  var scope;

  return {
    get : function( channelId ){
      return DB.query(
        'SELECT channel_id, channel_name, channel_users, unread_count FROM TB_CHANNEL where channel_id = ? ', [channelId]
      ).then(function(result) {
          return DB.fetch(result);
        });
    },
    list : function( $scope ){
      scope = $scope;

      return DB.query(
        'SELECT channel_id, channel_name, channel_users, unread_count FROM TB_CHANNEL ORDER BY channel_updated DESC'
      ).then(function(result) {
          return DB.fetchAll(result);
        });
    },
    add : function(jsonObj){

      var channelId = '';

      var query =
        "INSERT OR REPLACE INTO TB_CHANNEL "+
        "(channel_id, channel_name, channel_users, unread_count, channel_updated) VALUES "+
        "(?, ?, ?, ?, ?)";

      var cond = [
        jsonObj.channel,
        jsonObj.name,
        jsonObj.users,
        1,
        Date.now()
      ];

      if( scope != undefined ){
        var channel = {'channel_id':jsonObj.channel,'channel_name':jsonObj.name,'unread_count':1};

        var dupFlag = false;
        for( var inx = 0; !dupFlag && inx < scope.channels.length ; inx++){
          if( scope.channels[inx].channelId == channel.channelId ){
            dupFlag = true;
          }
        }

        if( !dupFlag ){
          console.log( channel );
          scope.channels.push(angular.extend({}, channel));
          scope.$apply();
        }
      }

      return DB.query(query, cond).then(function(result) {
        return result;
      });
    },
    generateId : function(jsonObj){
      var channelId;
      if( jsonObj.users.length > 2 ){
        channelId = UTIL.getUniqueKey()+"^"+APP_INFO.appKey;;
      } else {
        jsonObj.users.sort();
        channelId = jsonObj.users.join( "$" )+"^"+APP_INFO.appKey;
      }
      return channelId;
    }
  }
})
.factory('Messages', function(DB) {
  // Might use a resource here that returns a JSON array
  var scope;

  return {
    list : function( $scope, channel ){
      scope = $scopeji
      return DB.query(
        'SELECT message, time FROM TB_MESSAGE ORDER BY time ASC WHERE channel = ?', [channel]
      ).then(function(result) {
          return DB.fetchAll(result);
        });
    },
    add : function(jsonObj){

      var query =
        "INSERT INTO TB_MESSAGE "+
        "(channel, sender, message, type, time) VALUES "+
        "(?, ?, ?, ?, ?)";

      var cond = [
        jsonObj.channel,
        jsonObj.sender,
        jsonObj.message,
        '1',
        Date.now()
      ];

      if( scope != undefined ){
        var message = {'id':jsonObj.id,'name':jsonObj.name,'unread_count':1};

        scope.messages.push(angular.extend({}, message));
        scope.$apply();
      }

      return DB.query(query, cond).then(function(result) {
        return result;
      });
    }
  }
})
.factory('SocketManager', function($http, Sign, Channels) {
  var sessionSocket;
  var initFlag = false;
  return {
    get : function(callback){
      if( !initFlag ){
        this.init( function( socket ) {
          sessionSocket = socket;
          callback( sessionSocket );
        });
      } else {
        callback( sessionSocket );
      }
    },
    init : function(callback){

     var loginUser = Sign.getUser();

      var socketOptions ={
        transports: ['websocket'],
        'force new connection': true
      };

      var query =
        'app='+loginUser.app+'&'+
        'userId='+encodeURIComponent(loginUser.userId)+'&'+
        'deviceId='+loginUser.deviceId+'&'+
        'token='+loginUser.userToken;

      // Session Socket
      console.log( loginUser.sessionServer );
      var socket = io.connect(loginUser.sessionServer+'/session?'+query, socketOptions);
      socket.on('connect', function() {
        console.log( 'session socket connect');
        initFlag = true;
        callback( socket );
      });

      socket.on('_event', function (messageObject) {
        if( messageObject.event == 'NOTIFICATION' ){
          var data = messageObject.data;

          console.log( 'NOTI : ' + data );

          var channel = {'channel': data.channel, 'name': data.user.id };
          if( data.channel.indexOf( "$" ) > -1 ){
            channel.users = data.channel.split( "^" )[0].split( "$" ).join( "," );
          }

          Channels.add( channel );
        }
      });

      socket.on('disconnect', function (data) {
        console.info('session socket disconnect');
      });
    }
  }
})
.factory('Sign', function($http, BASE_URL) {
  var loginUser;
  return {
    login : function( params, callback ){
      $http.post("http://"+BASE_URL+":8000/auth", params)
      .success(function(data) {
        callback( data );
      })
      .error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },
    register : function( params, callback ){
      $http.post("http://"+BASE_URL+":8000/user/register", params)
      .success(function(data) {
        callback( data );
      })
      .error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },

    setUser : function( user ){
      loginUser = user;
    },
    getUser : function(){
      return loginUser;
    }
  }
})
.factory('Chat', function($http, BASE_URL) {
  var channelSocket;
  var CONF = {};

  return {
    init : function( params, loginUser, $scope, callback ){
      $http.get("http://"+BASE_URL+":8000/node/"+ encodeURIComponent( params.app ) + "/"+ encodeURIComponent( params.channel )+'?1=1' )
      .success(function( data ) {

        var socketServerUrl = data.result.server.url;

        CONF._app = params.app;
        CONF._channel = params.channel;
        CONF._user = { id : loginUser.userId, name : loginUser.name, url :'', image : loginUser.image};

        var query = "app=" + params.app + "&channel=" + params.channel + "&userId=" + params.userId + "&deviceId=" + params.deviceId
         + "&server=" + data.result.server.name;

        var socketOptions ={
          'force new connection': true
        };

        console.log( socketServerUrl );
        channelSocket = io.connect(socketServerUrl+'/channel?'+query, socketOptions);

        channelSocket.on('connect', function() {
          console.log( 'channel connect' );
          channelSocket.emit( 'message-unread', function(jsonObj){
            var unreadMessages = jsonObj.result;

            var messages = [];
            for( var inx = 0 ; inx < unreadMessages.length ; inx++ ){
              var data = JSON.parse( unreadMessages[inx].message.data );
              var content;
              content = '
'+data.user.id+'
' ;
              content = content + '';
              content = content + ''+decodeURIComponent( data.message )+'' ;
              messages.push( { content : content, from : 'you' } );
            }

            //message received complete
            if( unreadMessages != undefined && unreadMessages.length > 0 ){
              channelSocket.emit("message-received");
            }

            callback(messages);
          });
        });

        channelSocket.on('connect_error', function(data) {
          console.log( data );
        });

        channelSocket.on('message', function (data) {
          //console.info('\t MESSAGE : '+JSON.stringify(data));
          data.timestamp = Date.now()
          //var chatText = '
'+getTimeStamp()+':'+data.sender+'
';
          // var msgClass = data.sender==_userId?'from-op':'from-visitor';
          //chatText +='
'+decodeURIComponent(data.message)+'
';

          data.message = decodeURIComponent(data.message);
          var from = data.user.id == loginUser.userId ? 'me': 'you' ;

          var content;
          if(from == 'you'){
            data.sender = data.user.id;
            data.picture = data.user.image;

            content = '
'+data.sender+'
' ;
            content = content + '';
            content = content + ''+data.message+'' ;

          } else {
            content = ''+data.message+''
          }

          var nextMessage = { content : content, from : from };
          $scope.add( nextMessage );
        });
      })
      .error(function(data, status, headers, config) {
        console.log( status );
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },
    send : function(msg){
      var param = {
        app:      CONF._app,
        channel:  CONF._channel,
        name:     'message',
        data:     {
          user:     CONF._user,
          message:  msg,
          sender : 'operator'
        }
      };

      channelSocket.emit('send', param, function (data) {
      });
    },
    join : function( users, callback){
      channelSocket.emit('join', users, function (data) {
        callback( data );
      });
    },
    exit : function(){
      channelSocket.disconnect();
    }
  }
})
.factory('DB', function($q, DB_CONFIG) {
  var self = this;
  self.db = null;

  self.init = function() {
    // Use self.db = window.sqlitePlugin.openDatabase({name: DB_CONFIG.name}); in production

    try {
      if (!window.openDatabase) {
        window.plugins.toast.showShortCenter(
          "죄송합니다. DB를 지원하지 않습니다. \n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );
      } else {
        var shortName = DB_CONFIG.name;
        var version = '1.0';
        var displayName = 'news database';
        var maxSize = 5 * 1024 * 1024; // in bytes
        self.db = openDatabase(shortName, version, displayName, maxSize);
      }
    } catch(e) {
      // Error handling code goes here.
      if (e == INVALID_STATE_ERR) {
        // Version number mismatch.
        window.plugins.toast.showShortCenter(
          "죄송합니다. DB 버젼을 지원하지 않습니다.\n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );
      } else {

        window.plugins.toast.showShortCenter(
          "죄송합니다. "+e+"\n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );

      }
      return;
    }

    angular.forEach(DB_CONFIG.tables, function(table) {
      var columns = [];

      angular.forEach(table.columns, function(column) {
        columns.push(column.name + ' ' + column.type);
      });

      var query = 'DROP TABLE ' + table.name;
      self.query(query);

      var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
      self.query(query);
    });
  };

  self.query = function(query, bindings) {
    bindings = typeof bindings !== 'undefined' ? bindings : [];
    var deferred = $q.defer();

    self.db.transaction(function(transaction) {
      transaction.executeSql(query, bindings, function(transaction, result) {
        deferred.resolve(result);
      }, function(transaction, error) {
        deferred.reject(error);
      });
    });

    return deferred.promise;
  };

  self.fetchAll = function(result) {
    var output = [];

    for (var i = 0; i < result.rows.length; i++) {
      output.push(result.rows.item(i));
    }

    return output;
  };

  self.fetch = function(result) {
    return result.rows.item(0);
  };

  return self;
})
.factory('UTIL', function(){
  return {
    getUniqueKey : function () {
      var s = [], itoh = '0123456789ABCDEF';
      for (var i = 0; i < 36; i++) s[i] = Math.floor(Math.random()*0x10);
      s[14] = 4;
      s[19] = (s[19] & 0x3) | 0x8;

      for (var x = 0; x < 36; x++) s[x] = itoh[s[x]];
      s[8] = s[13] = s[18] = s[23] = '-';

      return s.join('');
    }
  }
});<commit_msg>:gem: bug fix<commit_after>angular.module('starter.services', [])

/**
 * A simple example service that returns some data.
 */
.factory('Friends', function(SocketManager, Sign) {
  // Might use a resource here that returns a JSON array

  // Some fake testing data
  var friends = [];
  var friendNames = [];
  var loginUserId = Sign.getUser().userId;

  return {
    all: function() {
      return friends;
    },
    add: function(userIds, callback) {
      SocketManager.get( function( socket ){
        socket.emit( 'group-add', {'userIds':userIds, 'groupId' : loginUserId}, function( data ){
          callback( data );
        });
      });
    },
    get: function(friendId) {
      // Simple index lookup
      return friends[friendId];
    },
    list : function(callback){

      SocketManager.get( function( socket ){
        socket.emit( 'group-list', {'groupId':loginUserId}, function( data ){
          if( data.status == 'ok' ){
            var users = data.result;
            console.log( users );
            var jnx = 0;
            for( var inx = 0 ; inx < users.length ; inx++ ){
              if( users[inx].userId != loginUserId ){
                if( friendNames.indexOf( users[inx].userId ) < 0 ){
                  friendNames.push( users[inx].userId );
                  friends.push( { 'id' : jnx++, 'userId' : users[inx].userId, 'userName': users[inx].datas.name,
                    'message' : users[inx].datas.message, 'image': users[inx].datas.image  } );
                }
              }
            }

            callback( friends );
          }
        });
      });
    }
  }
})
.factory('Users', function(SocketManager, Sign) {
  // Might use a resource here that returns a JSON array
  var loginUserId = Sign.getUser().userId;

  return {
    all: function() {
      return users;
    },
    get: function(userId) {
      // Simple index lookup
      return users[userId];
    },
    list : function(callback){

      var users = [];
      var userIds = [];

      SocketManager.get( function( socket ){
        socket.emit( 'user-list', {}, function( data ){
          console.log( 'user-list' );
          if( data.status == 'ok' ){
            var userArray = data.result;
            console.log( userArray );
            var jnx = 0;
            for( var inx = 0 ; inx < userArray.length ; inx++ ){
              var tmpUserId = userArray[inx].userId;
              console.log( "tmpUserId : " + tmpUserId );
              if( tmpUserId != loginUserId ){
                if( userIds.indexOf( tmpUserId ) < 0 ){
                  userIds.push( tmpUserId );
                  users.push( { 'id' : jnx++, 'userId' : userArray[inx].userId, 'userName': userArray[inx].datas.name, 'image': userArray[inx].datas.image } );
                }
              }
            }

            callback( users );
          }
        });
      });
    }
  }
})
.factory('Channels', function(DB, UTIL, APP_INFO) {
  // Might use a resource here that returns a JSON array
  var scope;

  return {
    get : function( channelId ){
      return DB.query(
        'SELECT channel_id, channel_name, channel_users, unread_count FROM TB_CHANNEL where channel_id = ? ', [channelId]
      ).then(function(result) {
          return DB.fetch(result);
        });
    },
    list : function( $scope ){
      scope = $scope;

      return DB.query(
        'SELECT channel_id, channel_name, channel_users, unread_count FROM TB_CHANNEL ORDER BY channel_updated DESC'
      ).then(function(result) {
          return DB.fetchAll(result);
        });
    },
    add : function(jsonObj){

      var channelId = '';

      var query =
        "INSERT OR REPLACE INTO TB_CHANNEL "+
        "(channel_id, channel_name, channel_users, unread_count, channel_updated) VALUES "+
        "(?, ?, ?, ?, ?)";

      var cond = [
        jsonObj.channel,
        jsonObj.name,
        jsonObj.users,
        1,
        Date.now()
      ];

      if( scope != undefined ){
        var channel = {'channel_id':jsonObj.channel,'channel_name':jsonObj.name,'unread_count':1};

        var dupFlag = false;
        for( var inx = 0; !dupFlag && inx < scope.channels.length ; inx++){
          if( scope.channels[inx].channelId == channel.channelId ){
            dupFlag = true;
          }
        }

        if( !dupFlag ){
          console.log( channel );
          scope.channels.push(angular.extend({}, channel));
          scope.$apply();
        }
      }

      return DB.query(query, cond).then(function(result) {
        return result;
      });
    },
    generateId : function(jsonObj){
      var channelId;
      if( jsonObj.users.length > 2 ){
        channelId = UTIL.getUniqueKey()+"^"+APP_INFO.appKey;;
      } else {
        jsonObj.users.sort();
        channelId = jsonObj.users.join( "$" )+"^"+APP_INFO.appKey;
      }
      return channelId;
    }
  }
})
.factory('Messages', function(DB) {
  // Might use a resource here that returns a JSON array
  var scope;

  return {
    list : function( $scope, channel ){
      scope = $scopeji
      return DB.query(
        'SELECT message, time FROM TB_MESSAGE ORDER BY time ASC WHERE channel = ?', [channel]
      ).then(function(result) {
          return DB.fetchAll(result);
        });
    },
    add : function(jsonObj){

      var query =
        "INSERT INTO TB_MESSAGE "+
        "(channel, sender, message, type, time) VALUES "+
        "(?, ?, ?, ?, ?)";

      var cond = [
        jsonObj.channel,
        jsonObj.sender,
        jsonObj.message,
        '1',
        Date.now()
      ];

      if( scope != undefined ){
        var message = {'id':jsonObj.id,'name':jsonObj.name,'unread_count':1};

        scope.messages.push(angular.extend({}, message));
        scope.$apply();
      }

      return DB.query(query, cond).then(function(result) {
        return result;
      });
    }
  }
})
.factory('SocketManager', function($http, Sign, Channels) {
  var sessionSocket;
  var initFlag = false;
  return {
    get : function(callback){
      if( !initFlag ){
        this.init( function( socket ) {
          sessionSocket = socket;
          callback( sessionSocket );
        });
      } else {
        callback( sessionSocket );
      }
    },
    init : function(callback){

     var loginUser = Sign.getUser();

      var socketOptions ={
        transports: ['websocket'],
        'force new connection': true
      };

      var query =
        'app='+loginUser.app+'&'+
        'userId='+encodeURIComponent(loginUser.userId)+'&'+
        'deviceId='+loginUser.deviceId+'&'+
        'token='+loginUser.userToken;

      // Session Socket
      console.log( loginUser.sessionServer );
      var socket = io.connect(loginUser.sessionServer+'/session?'+query, socketOptions);
      socket.on('connect', function() {
        console.log( 'session socket connect');
        initFlag = true;
        callback( socket );
      });

      socket.on('_event', function (messageObject) {
        if( messageObject.event == 'NOTIFICATION' ){
          var data = messageObject.data;

          console.log( 'NOTI : ' + data );

          var channel = {'channel': data.channel, 'name': data.user.id };
          if( data.channel.indexOf( "$" ) > -1 ){
            channel.users = data.channel.split( "^" )[0].split( "$" ).join( "," );
          }

          Channels.add( channel );
        }
      });

      socket.on('disconnect', function (data) {
        console.info('session socket disconnect');
      });
    }
  }
})
.factory('Sign', function($http, BASE_URL) {
  var loginUser;
  return {
    login : function( params, callback ){
      $http.post("http://"+BASE_URL+":8000/auth", params)
      .success(function(data) {
        callback( data );
      })
      .error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },
    register : function( params, callback ){
      $http.post("http://"+BASE_URL+":8000/user/register", params)
      .success(function(data) {
        callback( data );
      })
      .error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },

    setUser : function( user ){
      loginUser = user;
    },
    getUser : function(){
      return loginUser;
    }
  }
})
.factory('Chat', function($http, BASE_URL) {
  var channelSocket;
  var CONF = {};

  return {
    init : function( params, loginUser, $scope, callback ){
      $http.get("http://"+BASE_URL+":8000/node/"+ encodeURIComponent( params.app ) + "/"+ encodeURIComponent( params.channel )+'?1=1' )
      .success(function( data ) {

        var socketServerUrl = data.result.server.url;

        CONF._app = params.app;
        CONF._channel = params.channel;
        CONF._user = { id : loginUser.userId, name : loginUser.name, url :'', image : loginUser.image};

        var query = "app=" + params.app + "&channel=" + params.channel + "&userId=" + params.userId + "&deviceId=" + params.deviceId
         + "&server=" + data.result.server.name;

        var socketOptions ={
          'force new connection': true
        };

        console.log( socketServerUrl );
        channelSocket = io.connect(socketServerUrl+'/channel?'+query, socketOptions);

        channelSocket.on('connect', function() {
          console.log( 'channel connect' );
          channelSocket.emit( 'message-unread', function(jsonObj){
            var unreadMessages = jsonObj.result;

            var messages = [];
            for( var inx = 0 ; inx < unreadMessages.length ; inx++ ){
              var data = JSON.parse( unreadMessages[inx].message.data );
              var content;
              content = '
'+data.user.id+'
' ;
              content = content + '';
              content = content + ''+decodeURIComponent( data.message )+'' ;
              messages.push( { content : content, from : 'you' } );
            }

            //message received complete
            if( unreadMessages != undefined && unreadMessages.length > 0 ){
              channelSocket.emit("message-received");
            }

            callback(messages);
          });
        });

        channelSocket.on('connect_error', function(data) {
          console.log( data );
        });

        channelSocket.on('message', function (data) {
          //console.info('\t MESSAGE : '+JSON.stringify(data));
          data.timestamp = Date.now()
          //var chatText = '
'+getTimeStamp()+':'+data.sender+'
';
          // var msgClass = data.sender==_userId?'from-op':'from-visitor';
          //chatText +='
'+decodeURIComponent(data.message)+'
';

          data.message = decodeURIComponent(data.message);
          var from = data.user.id == loginUser.userId ? 'me': 'you' ;

          var content;
          if(from == 'you'){
            data.sender = data.user.id;
            data.picture = data.user.image;

            content = '
'+data.sender+'
' ;
            content = content + '';
            content = content + ''+data.message+'' ;

          } else {
            content = ''+data.message+''
          }

          var nextMessage = { content : content, from : from };
          $scope.add( nextMessage );
        });
      })
      .error(function(data, status, headers, config) {
        console.log( status );
        // called asynchronously if an error occurs
        // or server returns response with an error status.
      });
    },
    send : function(msg){
      var param = {
        app:      CONF._app,
        channel:  CONF._channel,
        name:     'message',
        data:     {
          user:     CONF._user,
          message:  msg,
          sender : 'operator'
        }
      };

      channelSocket.emit('send', param, function (data) {
      });
    },
    join : function( users, callback){
      channelSocket.emit('join', users, function (data) {
        callback( data );
      });
    },
    exit : function(){
      channelSocket.disconnect();
    }
  }
})
.factory('DB', function($q, DB_CONFIG) {
  var self = this;
  self.db = null;

  self.init = function() {
    // Use self.db = window.sqlitePlugin.openDatabase({name: DB_CONFIG.name}); in production

    try {
      if (!window.openDatabase) {
        window.plugins.toast.showShortCenter(
          "죄송합니다. DB를 지원하지 않습니다. \n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );
      } else {
        var shortName = DB_CONFIG.name;
        var version = '1.0';
        var displayName = 'news database';
        var maxSize = 5 * 1024 * 1024; // in bytes
        self.db = openDatabase(shortName, version, displayName, maxSize);
      }
    } catch(e) {
      // Error handling code goes here.
      if (e == INVALID_STATE_ERR) {
        // Version number mismatch.
        window.plugins.toast.showShortCenter(
          "죄송합니다. DB 버젼을 지원하지 않습니다.\n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );
      } else {

        window.plugins.toast.showShortCenter(
          "죄송합니다. "+e+"\n북마크 기능을 사용하실 수 없습니다.",function(a){},function(b){}
        );

      }
      return;
    }

    angular.forEach(DB_CONFIG.tables, function(table) {
      var columns = [];

      angular.forEach(table.columns, function(column) {
        columns.push(column.name + ' ' + column.type);
      });

      var query = 'DROP TABLE ' + table.name;
      self.query(query);

      var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
      self.query(query);
    });
  };

  self.query = function(query, bindings) {
    bindings = typeof bindings !== 'undefined' ? bindings : [];
    var deferred = $q.defer();

    self.db.transaction(function(transaction) {
      transaction.executeSql(query, bindings, function(transaction, result) {
        deferred.resolve(result);
      }, function(transaction, error) {
        deferred.reject(error);
      });
    });

    return deferred.promise;
  };

  self.fetchAll = function(result) {
    var output = [];

    for (var i = 0; i < result.rows.length; i++) {
      output.push(result.rows.item(i));
    }

    return output;
  };

  self.fetch = function(result) {
    return result.rows.item(0);
  };

  return self;
})
.factory('UTIL', function(){
  return {
    getUniqueKey : function () {
      var s = [], itoh = '0123456789ABCDEF';
      for (var i = 0; i < 36; i++) s[i] = Math.floor(Math.random()*0x10);
      s[14] = 4;
      s[19] = (s[19] & 0x3) | 0x8;

      for (var x = 0; x < 36; x++) s[x] = itoh[s[x]];
      s[8] = s[13] = s[18] = s[23] = '-';

      return s.join('');
    }
  }
});<|endoftext|>


<commit_before>angular.module('mapasculturais.services', [])

.factory('BlankFactory', [function(){

}])

.service('BlankService', [function(){

}])

.service('MenuState', ['$rootScope', function($rootScope) {
    $rootScope.activeMenu = 'events';
    this.activeMenu = function(activeMenu){
        $rootScope.activeMenu = activeMenu;
    };
}])

.service('FavoriteEvents', ['$localStorage', function($localStorage) {

    var self = this
    this.favorites = [];

    var sync = function() {
        while (self.favorites.length > 0)
            self.favorites.pop()
        for (var key in $localStorage.favoriteEvents) {
            self.favorites.push($localStorage.favoriteEvents[key]);
        }
    }

    if (!$localStorage.favoriteEvents) {
        $localStorage.favoriteEvents = {}
    } else {
        sync();
    }

    var getKey = function(event) {
        // console.log(event.start.toString())
        var key = moment(event.start.toString()).format('X') + '|' + event.occurrence_id;
        return key;

    }

    this.favorite = function(event) {
        if (!event.favorite) {
            event.favorite = true;
            $localStorage.favoriteEvents[getKey(event)] = event;
        } else {
            event.favorite = false;
            delete $localStorage.favoriteEvents[getKey(event)]
        }
        sync()
    }

    this.isFavorite = function(event) {
        return !!$localStorage.favoriteEvents[getKey(event)]
    }

    this.clear = function(){
        $localStorage.favoriteEvents = {};
        sync();
    }

}])

.service('MapState', function(){
    // return function(mapTypeId, center){
    var center = new plugin.google.maps.LatLng(-23.5408, -46.6400);
    this.options = {
        'backgroundColor': 'transparent',
        'mapType': plugin.google.maps.MapTypeId.ROADMAP,
        'controls': {
            'myLocationButton': true,
            'indoorPicker': true,
            'zoom': true
        },
        'gestures': {
            'scroll': true,
            'tilt': true,
            'rotate': false,
            'zoom': true
        },
        'camera': {
            'latLng': center,
            'zoom': 14,
        }
    };
    this.markers = [];
        // map options that will be kept in memory ;)
    // }
})<commit_msg>fix horário dos eventos favoritados<commit_after>angular.module('mapasculturais.services', [])

.factory('BlankFactory', [function(){

}])

.service('BlankService', [function(){

}])

.service('MenuState', ['$rootScope', function($rootScope) {
    $rootScope.activeMenu = 'events';
    this.activeMenu = function(activeMenu){
        $rootScope.activeMenu = activeMenu;
    };
}])

.service('FavoriteEvents', ['$localStorage', function($localStorage) {

    var self = this
    this.favorites = [];

    var sync = function() {
        while (self.favorites.length > 0){
            self.favorites.pop();
        }
        for (var key in $localStorage.favoriteEvents) {
            var event = $localStorage.favoriteEvents[key];
            event.start = moment(event.start);
            event.end = moment(event.end);
            self.favorites.push(event);
        }
    }

    if (!$localStorage.favoriteEvents) {
        $localStorage.favoriteEvents = {}
    } else {
        sync();
    }

    var getKey = function(event) {
        // console.log(event.start.toString())
        var key = moment(event.start.toString()).format('X') + '|' + event.occurrence_id;
        return key;

    }

    this.favorite = function(event) {
        if (!event.favorite) {
            event.favorite = true;
            $localStorage.favoriteEvents[getKey(event)] = event;
        } else {
            event.favorite = false;
            delete $localStorage.favoriteEvents[getKey(event)]
        }
        sync()
    }

    this.isFavorite = function(event) {
        return !!$localStorage.favoriteEvents[getKey(event)]
    }

    this.clear = function(){
        $localStorage.favoriteEvents = {};
        sync();
    }

}])

.service('MapState', function(){
    // return function(mapTypeId, center){
    var center = new plugin.google.maps.LatLng(-23.5408, -46.6400);
    this.options = {
        'backgroundColor': 'transparent',
        'mapType': plugin.google.maps.MapTypeId.ROADMAP,
        'controls': {
            'myLocationButton': true,
            'indoorPicker': true,
            'zoom': true
        },
        'gestures': {
            'scroll': true,
            'tilt': true,
            'rotate': false,
            'zoom': true
        },
        'camera': {
            'latLng': center,
            'zoom': 14,
        }
    };
    this.markers = [];
        // map options that will be kept in memory ;)
    // }
})<|endoftext|>


<commit_before>angular.module('starter.services', ['ngResource'])

.factory('CepService', function($resource) {
  return $resource('https://viacep.com.br/ws/:cep/json/unicode', {}, {
    get: {
      headers: {'Accept': 'application/json'}
    }
  });
})

.factory('ProfileService', function($resource) {
  return $resource('http://localhost:3000/profiles/:id.:format', {format: 'json'}, {
    update: {
      method: 'PUT'
    }
  });
})

.factory('ScheduleService', function($resource) {
  return $resource('http://localhost:3000/schedules/:id.:format', {format: 'json'}, {
    update: {
      method: 'PUT'
    }
  });
});;<commit_msg>API url<commit_after>angular.module('starter.services', ['ngResource'])

.factory('API', function() {
  return {
    host: 'https://warm-dusk-4656.herokuapp.com'
  };
})

.factory('CepService', function($resource) {
  return $resource('https://viacep.com.br/ws/:cep/json/unicode', {}, {
    get: {
      headers: {'Accept': 'application/json'}
    }
  });
})

.factory('ProfileService', function($resource, API) {
  return $resource(API.host + '/profiles/:id.:format', {format: 'json'}, {
    update: {
      method: 'PUT'
    }
  });
})

.factory('ScheduleService', function($resource, API) {
  return $resource(API.host + '/schedules/:id.:format', {format: 'json'}, {
    update: {
      method: 'PUT'
    }
  });
});;<|endoftext|>


<commit_before>let File = require('../File');
let path = require('path');
let spawn = require('child_process').spawn;
let notifier = require('node-notifier');

class StandaloneSass {
    /**
     * Create a new StandaloneSass instance.
     *
     * @param {string} src
     * @param {string} output
     * @param {object} pluginOptions
     */
    constructor(src, output, pluginOptions) {
        src = new File(path.resolve(src)).parsePath();
        output = new File(output).parsePath();

        if (output.isDir) {
            output = new File(
                path.join(output.path, src.name + '.css')
            ).parsePath();
        }

        this.src = src;
        this.output = output;
        this.pluginOptions = pluginOptions;
        this.shouldWatch = process.argv.includes('--watch');
    }

    /**
     * Run the node-sass compiler.
     *
     * @param {Boolean} Mix
     */
    run(Mix) {
        this.Mix = Mix;

        this.compile();

        if (this.shouldWatch) this.watch(true);

        this.whenOutputIsAvailable((output, event) => {
            if (event === 'error') this.onFail(output);
            if (event === 'success') this.onSuccess(output);
        });
    }

    /**
     * Compile Sass.
     *
     * @param {Boolean} watch
     */
    compile(watch) {
        this.command = spawn(
            'node-sass', [this.src.path, this.output.path].concat(this.options(watch))
        );

        return this;
    }

    /**
     * Fetch the node-sass options.
     *
     * @param {Boolean} watch
     */
    options(watch) {
        let options = [
            '--precision=8',
            '--output-style=' + (this.Mix.inProduction ? 'compressed' : 'expanded'),
        ];

        if (watch) options.push('-w');

        if (this.pluginOptions.includePaths) {
            this.pluginOptions.includePaths.forEach(
                path => options.push('--include-path=' + path)
            );
        }

        if (this.Mix.options.sourcemaps && ! this.Mix.inProduction) {
            options.push('--source-map-embed');
        }

        return options;
    }

    /**
     * Compile Sass, while registering a watcher.
     */
    watch() {
        return this.compile(true);
    }

    /**
     * Register a callback for when output is available.
     *
     * @param {Function} callback
     */
    whenOutputIsAvailable(callback) {
        this.command.stderr.on('data', output => {
            output = output.toString();

            let event = 'change';
            if (/Error/.test(output)) event = 'error';
            if (/Wrote CSS/.test(output)) event = 'success';

            callback(output, event);
        });
    }

    /**
     * Handle successful compilation.
     *
     * @param {string} output
     */
    onSuccess(output) {
        console.log("\n");
        console.log('Sass Compilation Successful!');

        notifier.notify({
            title: 'Laravel Mix',
            message: 'Sass Compilation Successful',
            contentImage: 'node_modules/laravel-mix/icons/laravel.png'
        });
    }

    /**
     * Handle failed compilation.
     *
     * @param {string} output
     */
    onFail(output) {
        console.log("\n");
        console.log('Sass Compilation Failed!');
        console.log();
        console.log(output);

        notifier.notify({
            title: 'Laravel Mix',
            subtitle: 'Sass Compilation Failed',
            message: JSON.parse(output).message,
            contentImage: 'node_modules/laravel-mix/icons/laravel.png'
        });

        if (! this.shouldWatch) process.exit();
    }
}

module.exports = StandaloneSass;
<commit_msg>Join publicPath to output<commit_after>let File = require('../File');
let path = require('path');
let spawn = require('child_process').spawn;
let notifier = require('node-notifier');

class StandaloneSass {
    /**
     * Create a new StandaloneSass instance.
     *
     * @param {string} src
     * @param {string} output
     * @param {object} pluginOptions
     */
    constructor(src, output, pluginOptions) {
        src = new File(path.resolve(src)).parsePath();
        output = new File(output).parsePath();

        if (output.isDir) {
            output = new File(
                path.join(output.path, src.name + '.css')
            ).parsePath();
        }

        this.src = src;
        this.output = output;
        this.pluginOptions = pluginOptions;
        this.shouldWatch = process.argv.includes('--watch');
    }

    /**
     * Run the node-sass compiler.
     *
     * @param {Boolean} Mix
     */
    run(Mix) {
        this.Mix = Mix;

        this.compile();

        if (this.shouldWatch) this.watch(true);

        this.whenOutputIsAvailable((output, event) => {
            if (event === 'error') this.onFail(output);
            if (event === 'success') this.onSuccess(output);
        });
    }

    /**
     * Compile Sass.
     *
     * @param {Boolean} watch
     */
    compile(watch) {
        let output = this.output.path;

        if (! output.startsWith(this.Mix.publicPath)) {
            output = path.join(this.Mix.publicPath, output);
        }

        this.command = spawn(
            'node-sass', [this.src.path, output].concat(this.options(watch))
        );

        return this;
    }

    /**
     * Fetch the node-sass options.
     *
     * @param {Boolean} watch
     */
    options(watch) {
        let options = [
            '--precision=8',
            '--output-style=' + (this.Mix.inProduction ? 'compressed' : 'expanded'),
        ];

        if (watch) options.push('-w');

        if (this.pluginOptions.includePaths) {
            this.pluginOptions.includePaths.forEach(
                path => options.push('--include-path=' + path)
            );
        }

        if (this.Mix.options.sourcemaps && ! this.Mix.inProduction) {
            options.push('--source-map-embed');
        }

        return options;
    }

    /**
     * Compile Sass, while registering a watcher.
     */
    watch() {
        return this.compile(true);
    }

    /**
     * Register a callback for when output is available.
     *
     * @param {Function} callback
     */
    whenOutputIsAvailable(callback) {
        this.command.stderr.on('data', output => {
            output = output.toString();

            let event = 'change';
            if (/Error/.test(output)) event = 'error';
            if (/Wrote CSS/.test(output)) event = 'success';

            callback(output, event);
        });
    }

    /**
     * Handle successful compilation.
     *
     * @param {string} output
     */
    onSuccess(output) {
        console.log("\n");
        console.log('Sass Compilation Successful!');

        notifier.notify({
            title: 'Laravel Mix',
            message: 'Sass Compilation Successful',
            contentImage: 'node_modules/laravel-mix/icons/laravel.png'
        });
    }

    /**
     * Handle failed compilation.
     *
     * @param {string} output
     */
    onFail(output) {
        console.log("\n");
        console.log('Sass Compilation Failed!');
        console.log();
        console.log(output);

        notifier.notify({
            title: 'Laravel Mix',
            subtitle: 'Sass Compilation Failed',
            message: JSON.parse(output).message,
            contentImage: 'node_modules/laravel-mix/icons/laravel.png'
        });

        if (! this.shouldWatch) process.exit();
    }
}

module.exports = StandaloneSass;
<|endoftext|>


<commit_before>import WebGPUUniformsGroup from './WebGPUUniformsGroup.js';
import WebGPUSampler from './WebGPUSampler.js';
import WebGPUSampledTexture from './WebGPUSampledTexture.js';
import { Matrix4 } from '../../../../build/three.module.js';

class WebGPUBindings {

	constructor( device, info, properties, textures ) {

		this.device = device;
		this.info = info;
		this.properties = properties;
		this.textures = textures;

		this.uniformsData = new WeakMap();

		this.sharedUniformsGroups = new Map();

		this.updateMap = new WeakMap();

		this._setupSharedUniformsGroups();

	}

	get( object ) {

		let data = this.uniformsData.get( object );

		if ( data === undefined ) {

			const material = object.material;
			let bindings;

			// each material defines an array of bindings (ubos, textures, samplers etc.)

			if ( material.isMeshBasicMaterial ) {

				bindings = this._getMeshBasicBindings();

			} else if ( material.isPointsMaterial ) {

				bindings = this._getPointsBasicBindings();

			} else if ( material.isLineBasicMaterial ) {

				bindings = this._getLinesBasicBindings();

			} else {

				console.error( 'WebGPURenderer: Unknwon shader type' );

			}

			// setup (static) binding layout and (dynamic) binding group

			const bindLayout = this._createBindLayout( bindings );
			const bindGroup = this._createBindGroup( bindings, bindLayout );

			data = {
				layout: bindLayout,
				group: bindGroup,
				bindings: bindings
			};

			this.uniformsData.set( object, data );

		}

		return data;

	}

	update( object, camera ) {

		const data = this.get( object );
		const bindings = data.bindings;

		const updateMap = this.updateMap;
		const frame = this.info.render.frame;
		const sharedUniformsGroups = this.sharedUniformsGroups;

		let needsBindGroupRefresh = false;

		// iterate over all bindings and check if buffer updates or a new binding group is required

		for ( const binding of bindings ) {

			if ( binding.isUniformsGroup ) {

				const isShared = sharedUniformsGroups.has( binding.name );
				const isUpdated = updateMap.get( binding ) === frame;

				if ( isShared && isUpdated ) continue;

				const array = binding.array;
				const bufferGPU = binding.bufferGPU;

				const needsBufferWrite = binding.update( array, object, camera );

				if ( needsBufferWrite === true ) {

					this.device.defaultQueue.writeBuffer(
						bufferGPU,
						0,
						array,
						0
					);

				}

				updateMap.set( binding, frame );

			} else if ( binding.isSampler ) {

				const material = object.material;
				const texture = material[ binding.name ];

				this.textures.updateSampler( texture );
				const samplerGPU = this.textures.getSampler( texture );

				if ( binding.samplerGPU !== samplerGPU ) {

					binding.samplerGPU = samplerGPU;
					needsBindGroupRefresh = true;

				}

			} else if ( binding.isSampledTexture ) {

				const material = object.material;
				const texture = material[ binding.name ];

				this.textures.updateTexture( texture );
				const textureGPU = this.textures.getTextureGPU( texture );

				if ( binding.textureGPU !== textureGPU ) {

					binding.textureGPU = textureGPU;
					needsBindGroupRefresh = true;

				}

			}

		}

		if ( needsBindGroupRefresh === true ) {

			data.group = this._createBindGroup( bindings, data.layout );

		}

	}

	dispose() {

		this.uniformsData = new WeakMap();
		this.updateMap = new WeakMap();

	}

	_createBindLayout( bindings ) {

		let bindingPoint = 0;
		const entries = [];

		for ( const binding of bindings ) {

			entries.push( { binding: bindingPoint, visibility: binding.visibility, type: binding.type } );

			bindingPoint ++;

		}

		return this.device.createBindGroupLayout( { entries: entries } );

	}

	_createBindGroup( bindings, layout ) {

		let bindingPoint = 0;
		const entries = [];

		for ( const binding of bindings ) {

			if ( binding.isUniformsGroup ) {

				if ( binding.bufferGPU === null ) {

					const byteLength = binding.getByteLength();

					binding.array = new Float32Array( new ArrayBuffer( byteLength ) );

					binding.bufferGPU = this.device.createBuffer( {
						size: byteLength,
						usage: binding.usage,
					} );

				}

				entries.push( { binding: bindingPoint, resource: { buffer: binding.bufferGPU } } );

			} else if ( binding.isSampler ) {

				if ( binding.samplerGPU === null ) {

					binding.samplerGPU = this.textures.getDefaultSampler();

				}

				entries.push( { binding: bindingPoint, resource: binding.samplerGPU } );

			} else if ( binding.isSampledTexture ) {

				if ( binding.textureGPU === null ) {

					binding.textureGPU = this.textures.getDefaultTexture();

				}

				entries.push( { binding: bindingPoint, resource: binding.textureGPU.createView() } );

			}

			bindingPoint ++;

		}

		return this.device.createBindGroup( {
			layout: layout,
			entries: entries
		} );

	}

	_getMeshBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		// samplers

		const diffuseSampler = new WebGPUSampler();
		diffuseSampler.setName( 'map' );

		// textures

		const diffuseTexture = new WebGPUSampledTexture();
		diffuseTexture.setName( 'map' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );
		bindings.push( diffuseSampler );
		bindings.push( diffuseTexture );

		return bindings;

	}

	_getPointsBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );

		return bindings;

	}

	_getLinesBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );

		return bindings;

	}

	_setupSharedUniformsGroups() {

		const cameraGroup = new WebGPUUniformsGroup();
		cameraGroup.setName( 'cameraUniforms' );
		cameraGroup.setUniform( 'projectionMatrix', new Matrix4() );
		cameraGroup.setUniform( 'viewMatrix', new Matrix4() );
		cameraGroup.setUpdateCallback( function ( array, object, camera ) {

			array.set( camera.projectionMatrix.elements, 0 );
			array.set( camera.matrixWorldInverse.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		this.sharedUniformsGroups.set( cameraGroup.name, cameraGroup );

	}

}

export default WebGPUBindings;
<commit_msg>WebGPUBindings: Don't miss texture and sampler updates in update().<commit_after>import WebGPUUniformsGroup from './WebGPUUniformsGroup.js';
import WebGPUSampler from './WebGPUSampler.js';
import WebGPUSampledTexture from './WebGPUSampledTexture.js';
import { Matrix4 } from '../../../../build/three.module.js';

class WebGPUBindings {

	constructor( device, info, properties, textures ) {

		this.device = device;
		this.info = info;
		this.properties = properties;
		this.textures = textures;

		this.uniformsData = new WeakMap();

		this.sharedUniformsGroups = new Map();

		this.updateMap = new WeakMap();

		this._setupSharedUniformsGroups();

	}

	get( object ) {

		let data = this.uniformsData.get( object );

		if ( data === undefined ) {

			const material = object.material;
			let bindings;

			// each material defines an array of bindings (ubos, textures, samplers etc.)

			if ( material.isMeshBasicMaterial ) {

				bindings = this._getMeshBasicBindings();

			} else if ( material.isPointsMaterial ) {

				bindings = this._getPointsBasicBindings();

			} else if ( material.isLineBasicMaterial ) {

				bindings = this._getLinesBasicBindings();

			} else {

				console.error( 'WebGPURenderer: Unknwon shader type' );

			}

			// setup (static) binding layout and (dynamic) binding group

			const bindLayout = this._createBindLayout( bindings );
			const bindGroup = this._createBindGroup( bindings, bindLayout );

			data = {
				layout: bindLayout,
				group: bindGroup,
				bindings: bindings
			};

			this.uniformsData.set( object, data );

		}

		return data;

	}

	update( object, camera ) {

		const data = this.get( object );
		const bindings = data.bindings;

		const updateMap = this.updateMap;
		const frame = this.info.render.frame;
		const sharedUniformsGroups = this.sharedUniformsGroups;

		let needsBindGroupRefresh = false;

		// iterate over all bindings and check if buffer updates or a new binding group is required

		for ( const binding of bindings ) {

			if ( binding.isUniformsGroup ) {

				const isShared = sharedUniformsGroups.has( binding.name );
				const isUpdated = updateMap.get( binding ) === frame;

				if ( isShared && isUpdated ) continue;

				const array = binding.array;
				const bufferGPU = binding.bufferGPU;

				const needsBufferWrite = binding.update( array, object, camera );

				if ( needsBufferWrite === true ) {

					this.device.defaultQueue.writeBuffer(
						bufferGPU,
						0,
						array,
						0
					);

				}

				updateMap.set( binding, frame );

			} else if ( binding.isSampler ) {

				const material = object.material;
				const texture = material[ binding.name ];

				const forceUpdate = this.textures.updateSampler( texture );
				const samplerGPU = this.textures.getSampler( texture );

				if ( binding.samplerGPU !== samplerGPU || forceUpdate ) {

					binding.samplerGPU = samplerGPU;
					needsBindGroupRefresh = true;

				}

			} else if ( binding.isSampledTexture ) {

				const material = object.material;
				const texture = material[ binding.name ];

				const forceUpdate = this.textures.updateTexture( texture );
				const textureGPU = this.textures.getTextureGPU( texture );

				if ( binding.textureGPU !== textureGPU || forceUpdate ) {

					binding.textureGPU = textureGPU;
					needsBindGroupRefresh = true;

				}

			}

		}

		if ( needsBindGroupRefresh === true ) {

			data.group = this._createBindGroup( bindings, data.layout );

		}

	}

	dispose() {

		this.uniformsData = new WeakMap();
		this.updateMap = new WeakMap();

	}

	_createBindLayout( bindings ) {

		let bindingPoint = 0;
		const entries = [];

		for ( const binding of bindings ) {

			entries.push( { binding: bindingPoint, visibility: binding.visibility, type: binding.type } );

			bindingPoint ++;

		}

		return this.device.createBindGroupLayout( { entries: entries } );

	}

	_createBindGroup( bindings, layout ) {

		let bindingPoint = 0;
		const entries = [];

		for ( const binding of bindings ) {

			if ( binding.isUniformsGroup ) {

				if ( binding.bufferGPU === null ) {

					const byteLength = binding.getByteLength();

					binding.array = new Float32Array( new ArrayBuffer( byteLength ) );

					binding.bufferGPU = this.device.createBuffer( {
						size: byteLength,
						usage: binding.usage,
					} );

				}

				entries.push( { binding: bindingPoint, resource: { buffer: binding.bufferGPU } } );

			} else if ( binding.isSampler ) {

				if ( binding.samplerGPU === null ) {

					binding.samplerGPU = this.textures.getDefaultSampler();

				}

				entries.push( { binding: bindingPoint, resource: binding.samplerGPU } );

			} else if ( binding.isSampledTexture ) {

				if ( binding.textureGPU === null ) {

					binding.textureGPU = this.textures.getDefaultTexture();

				}

				entries.push( { binding: bindingPoint, resource: binding.textureGPU.createView() } );

			}

			bindingPoint ++;

		}

		return this.device.createBindGroup( {
			layout: layout,
			entries: entries
		} );

	}

	_getMeshBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		// samplers

		const diffuseSampler = new WebGPUSampler();
		diffuseSampler.setName( 'map' );

		// textures

		const diffuseTexture = new WebGPUSampledTexture();
		diffuseTexture.setName( 'map' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );
		bindings.push( diffuseSampler );
		bindings.push( diffuseTexture );

		return bindings;

	}

	_getPointsBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );

		return bindings;

	}

	_getLinesBasicBindings() {

		const bindings = [];

		// ubos

		const modelGroup = new WebGPUUniformsGroup();
		modelGroup.setName( 'modelUniforms' );
		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {

			array.set( object.matrixWorld.elements, 0 );
			array.set( object.modelViewMatrix.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );

		//

		bindings.push( modelGroup );
		bindings.push( cameraGroup );

		return bindings;

	}

	_setupSharedUniformsGroups() {

		const cameraGroup = new WebGPUUniformsGroup();
		cameraGroup.setName( 'cameraUniforms' );
		cameraGroup.setUniform( 'projectionMatrix', new Matrix4() );
		cameraGroup.setUniform( 'viewMatrix', new Matrix4() );
		cameraGroup.setUpdateCallback( function ( array, object, camera ) {

			array.set( camera.projectionMatrix.elements, 0 );
			array.set( camera.matrixWorldInverse.elements, 16 );

			return true; // TODO: implement caching (return false when cache hits occurs)

		} );

		this.sharedUniformsGroups.set( cameraGroup.name, cameraGroup );

	}

}

export default WebGPUBindings;
<|endoftext|>


<commit_before>import { GPUTextureFormat, GPUAddressMode, GPUFilterMode } from './constants.js';
import { Texture, NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, RepeatWrapping, MirroredRepeatWrapping } from '../../../../build/three.module.js';

class WebGPUTextures {

	constructor( device, properties ) {

		this.device = device;
		this.properties = properties;

		this.textures = new WeakMap();

		this.defaultTexture = null;
		this.defaultSampler = null;

		this.samplerCache = new WeakMap();

	}

	getDefaultSampler() {

		if ( this.defaultSampler === null ) {

			this.defaultSampler = this.device.createSampler( {} );

		}

		return this.defaultSampler;

	}

	getDefaultTexture() {

		if ( this.defaultTexture === null ) {

			this.defaultTexture = this._createTexture( new Texture() );

		}

		return this.defaultTexture;

	}

	getTextureGPU( texture ) {

		const textureProperties = this.properties.get( texture );

		return textureProperties.textureGPU;

	}

	getSampler( texture ) {

		const textureProperties = this.properties.get( texture );

		return textureProperties.sampler;

	}

	updateTexture( texture ) {

		let updated = false;

		const textureProperties = this.properties.get( texture );

		if ( texture.version > 0 && textureProperties.version !== texture.version ) {

			const image = texture.image;

			if ( image === undefined ) {

				console.warn( 'THREE.WebGPURenderer: Texture marked for update but image is undefined' );

			} else if ( image.complete === false ) {

				console.warn( 'THREE.WebGPURenderer: Texture marked for update but image is incomplete' );

			} else {

				if ( textureProperties.textureGPU !== undefined ) {

					// TODO: Avoid calling of destroy() in certain scenarios. When only the contents of a texture
					// are updated, a  call of _uploadTexture() should be sufficient. However, if the user changes
					// the dimensions of the texture, format or usage, a new instance of GPUTexture is required.

					textureProperties.textureGPU.destroy();

				}

				textureProperties.textureGPU = this._createTexture( texture );
				textureProperties.version = texture.version;
				updated = true;

			}

		}

		return updated;

	}

	updateSampler( texture ) {

		let updated = false;

		const array = [];

		array.push( texture.magFilter );
		array.push( texture.minFilter );
		array.push( texture.anisotropy );

		const newKey = array.join();
		const key = this.samplerCache.get( texture );

		if ( key !== newKey ) {

			this.samplerCache.set( texture, newKey );

			const sampler = this.device.createSampler( {
				addressModeU: this._convertAddressMode( texture.wrapS ),
				addressModeV: this._convertAddressMode( texture.wrapT ),
				addressModeW: this._convertAddressMode( texture.wrapR ),
				magFilter: this._convertFilterMode( texture.magFilter ),
				minFilter: this._convertFilterMode( texture.minFilter ),
				mipmapFilter: this._convertFilterMode( texture.minFilter ),
				maxAnisotropy: texture.anisotropy
			} );

			const textureProperties = this.properties.get( texture );
			textureProperties.sampler = sampler;

			updated = true;

		}

		return updated;

	}

	_convertAddressMode( value ) {

		let addressMode = GPUAddressMode.ClampToEdge;

		if ( value === RepeatWrapping ) {

			addressMode = GPUAddressMode.Repeat;

		} else if ( value === MirroredRepeatWrapping ) {

			addressMode = GPUAddressMode.MirrorRepeat;

		}

		return addressMode;

	}

	_convertFilterMode( value ) {

		let filterMode = GPUFilterMode.Linear;

		if ( value === NearestFilter || value === NearestMipmapNearestFilter || value === NearestMipmapLinearFilter ) {

			filterMode = GPUFilterMode.Nearest;

		}

		return filterMode;

	}

	_createTexture( texture ) {

		const device = this.device;
		const image = texture.image;

		const width = ( image !== undefined ) ? image.width : 1;
		const height = ( image !== undefined ) ? image.height : 1;

		const textureGPU = device.createTexture( {
			size: {
				width: width,
				height: height,
				depth: 1,
			},
			format: GPUTextureFormat.RGBA8Unorm,
			usage: GPUTextureUsage.SAMPLED | GPUTextureUsage.COPY_DST,
		} );

		// convert HTML iamges and canvas elements to ImageBitmap before copy

		if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
			( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ) {

			const options = {};

			options.imageOrientation = ( texture.flipY === true ) ? 'flipY' : 'none';

			createImageBitmap( image, 0, 0, width, height, options ).then( imageBitmap => {

				this._uploadTexture( imageBitmap, textureGPU );

			} );

		} else {

			if ( image !== undefined ) {

				// assuming ImageBitmap. Directly start copy operation of the contents of ImageBitmap into the destination texture

				this._uploadTexture( image, textureGPU );

			}

		}

		return textureGPU;

	}

	_uploadTexture( imageBitmap, textureGPU ) {

		const device = this.device;

		device.defaultQueue.copyImageBitmapToTexture(
			{
				imageBitmap: imageBitmap
			}, {
				texture: textureGPU
			}, {
				width: imageBitmap.width,
				height: imageBitmap.height,
				depth: 1
			}
		);

	}

}

export default WebGPUTextures;
<commit_msg>WebGPUTextures: Initial support for DataTexture.<commit_after>import { GPUTextureFormat, GPUAddressMode, GPUFilterMode } from './constants.js';
import { Texture, NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, RepeatWrapping, MirroredRepeatWrapping, FloatType, HalfFloatType } from '../../../../build/three.module.js';

class WebGPUTextures {

	constructor( device, properties ) {

		this.device = device;
		this.properties = properties;

		this.textures = new WeakMap();

		this.defaultTexture = null;
		this.defaultSampler = null;

		this.samplerCache = new WeakMap();

	}

	getDefaultSampler() {

		if ( this.defaultSampler === null ) {

			this.defaultSampler = this.device.createSampler( {} );

		}

		return this.defaultSampler;

	}

	getDefaultTexture() {

		if ( this.defaultTexture === null ) {

			this.defaultTexture = this._createTexture( new Texture() );

		}

		return this.defaultTexture;

	}

	getTextureGPU( texture ) {

		const textureProperties = this.properties.get( texture );

		return textureProperties.textureGPU;

	}

	getSampler( texture ) {

		const textureProperties = this.properties.get( texture );

		return textureProperties.sampler;

	}

	updateTexture( texture ) {

		let updated = false;

		const textureProperties = this.properties.get( texture );

		if ( texture.version > 0 && textureProperties.version !== texture.version ) {

			const image = texture.image;

			if ( image === undefined ) {

				console.warn( 'THREE.WebGPURenderer: Texture marked for update but image is undefined' );

			} else if ( image.complete === false ) {

				console.warn( 'THREE.WebGPURenderer: Texture marked for update but image is incomplete' );

			} else {

				if ( textureProperties.textureGPU !== undefined ) {

					// TODO: Avoid calling of destroy() in certain scenarios. When only the contents of a texture
					// are updated, a buffer upload should be sufficient. However, if the user changes
					// the dimensions of the texture, format or usage, a new instance of GPUTexture is required.

					textureProperties.textureGPU.destroy();

				}

				textureProperties.textureGPU = this._createTexture( texture );
				textureProperties.version = texture.version;
				updated = true;

			}

		}

		return updated;

	}

	updateSampler( texture ) {

		let updated = false;

		const array = [];

		array.push( texture.magFilter );
		array.push( texture.minFilter );
		array.push( texture.anisotropy );

		const newKey = array.join();
		const key = this.samplerCache.get( texture );

		if ( key !== newKey ) {

			this.samplerCache.set( texture, newKey );

			const sampler = this.device.createSampler( {
				addressModeU: this._convertAddressMode( texture.wrapS ),
				addressModeV: this._convertAddressMode( texture.wrapT ),
				addressModeW: this._convertAddressMode( texture.wrapR ),
				magFilter: this._convertFilterMode( texture.magFilter ),
				minFilter: this._convertFilterMode( texture.minFilter ),
				mipmapFilter: this._convertFilterMode( texture.minFilter ),
				maxAnisotropy: texture.anisotropy
			} );

			const textureProperties = this.properties.get( texture );
			textureProperties.sampler = sampler;

			updated = true;

		}

		return updated;

	}

	_convertAddressMode( value ) {

		let addressMode = GPUAddressMode.ClampToEdge;

		if ( value === RepeatWrapping ) {

			addressMode = GPUAddressMode.Repeat;

		} else if ( value === MirroredRepeatWrapping ) {

			addressMode = GPUAddressMode.MirrorRepeat;

		}

		return addressMode;

	}

	_convertFilterMode( value ) {

		let filterMode = GPUFilterMode.Linear;

		if ( value === NearestFilter || value === NearestMipmapNearestFilter || value === NearestMipmapLinearFilter ) {

			filterMode = GPUFilterMode.Nearest;

		}

		return filterMode;

	}

	_convertFormat( type ) {

		let formatGPU = GPUTextureFormat.RGBA8Unorm;

		if ( type === FloatType ) {

			formatGPU = GPUTextureFormat.RGBA32Float;

		} else if ( type === HalfFloatType ) {

			formatGPU = GPUTextureFormat.RGBA16Float;

		}

		return formatGPU;

	}

	_createTexture( texture ) {

		const device = this.device;
		const image = texture.image;

		const width = ( image !== undefined ) ? image.width : 1;
		const height = ( image !== undefined ) ? image.height : 1;

		const format = this._convertFormat( texture.type );

		const textureGPU = device.createTexture( {
			size: {
				width: width,
				height: height,
				depth: 1,
			},
			format: format,
			usage: GPUTextureUsage.SAMPLED | GPUTextureUsage.COPY_DST,
		} );

		if ( texture.isDataTexture ) {

			this.__copyBufferToTexture( image, format, textureGPU );

		} else {

			// convert HTML iamges and canvas elements to ImageBitmap before copy

			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ) {

				const options = {};

				options.imageOrientation = ( texture.flipY === true ) ? 'flipY' : 'none';

				createImageBitmap( image, 0, 0, width, height, options ).then( imageBitmap => {

					this._copyImageBitmapToTexture( imageBitmap, textureGPU );

				} );

			} else {

				if ( image !== undefined ) {

					// assuming ImageBitmap. Directly start copy operation of the contents of ImageBitmap into the destination texture

					this._copyImageBitmapToTexture( image, textureGPU );

				}

			}

		}

		return textureGPU;

	}

	__copyBufferToTexture( image, format, textureGPU ) {

		// this code assumes data textures in RGBA format
		// TODO: Consider to support valid buffer layouts with other formats like RGB

		const device = this.device;
		const data = image.data;

		const bytesPerTexel = this._getBytesPerTexel( format );
		const bytesPerRow = Math.ceil( image.width * bytesPerTexel / 256 ) * 256;

		const textureDataBuffer = device.createBuffer( {
			size: data.byteLength,
			usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
			mappedAtCreation: true,
		} );

		new data.constructor( textureDataBuffer.getMappedRange() ).set( data );
		textureDataBuffer.unmap();

		const commandEncoder = device.createCommandEncoder( {} );
		commandEncoder.copyBufferToTexture(
			{
				buffer: textureDataBuffer,
				bytesPerRow: bytesPerRow
			}, {
				texture: textureGPU
			}, {
				width: image.width,
				height: image.height,
				depth: 1
			} );

		device.defaultQueue.submit( [ commandEncoder.finish() ] );
		textureDataBuffer.destroy();

	}

	_getBytesPerTexel( format ) {

		if ( format === GPUTextureFormat.RGBA8Unorm ) return 4;
		if ( format === GPUTextureFormat.RGBA32Float ) return 16;
		if ( format === GPUTextureFormat.RGBA16Float ) return 8;

	}

	_copyImageBitmapToTexture( imageBitmap, textureGPU ) {

		const device = this.device;

		device.defaultQueue.copyImageBitmapToTexture(
			{
				imageBitmap: imageBitmap
			}, {
				texture: textureGPU
			}, {
				width: imageBitmap.width,
				height: imageBitmap.height,
				depth: 1
			}
		);

	}

}

export default WebGPUTextures;
<|endoftext|>


<commit_before>
import React, {
    Component,
} from 'react'
import {
    View,
    Text,
    StyleSheet,
    Dimensions,
    ActivityIndicator,
    Modal,
    Alert,
    NativeModules,
} from 'react-native'

import Button from 'react-native-smart-button'
import TimerEnhance from 'react-native-smart-timer-enhance'
import Toast from 'react-native-smart-toast'

class LoadingToast extends Component {

    constructor(props) {
        super(props)
        this.state = {}
    }

    render() {
        return (
            <View style={{ paddingTop: 64, flex: 1, backgroundColor: '#fff',}}>
                <Button
                    onPress={this._showTopToast}
                    touchableType={Button.constants.touchableTypes.fadeContent}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show top
                </Button>

                <Button
                    onPress={this._showCenterToast}
                    touchableType={Button.constants.touchableTypes.highlight}
                    underlayColor={'#C90000'}
                    style={{margin: 10, justifyContent: 'center', height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show center
                </Button>

                <Button
                    onPress={this._showBottomToast}
                    touchableType={Button.constants.touchableTypes.blur}
                    style={{margin: 10, justifyContent: 'center', height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17,  color: 'white'}}

                >
                    show bottom
                </Button>
                <Button
                    onPress={this._showFastToast}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show fast
                </Button>
                <Button
                    onPress={this._showFastToastAndAnimatedHide}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show fast immediate hide
                </Button>
                <Button
                    onPress={this._showImmediateToast}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show immediate
                </Button>
                <Button
                    onPress={this._showImmediateToastAndAnimatedHide}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show immediate animated hide
                </Button>

                <Toast ref={ component => this._toast = component }>
                    Unable to connect to app store
                </Toast>
            </View>
        )
    }

    _showTopToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.top,
        })
    }

    _showCenterToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
        })
    }

    _showBottomToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.bottom,
        })
    }

    _showFastToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 255,
        })
    }

    _showFastToastAndAnimatedHide = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 255,
            animationEnd : () => {
                this._toast._toastAnimationToggle = this.setTimeout( () => {
                    this._toast.hide({
                        duration: 0,
                        animationEnd: () => {
                            //do sth...
                        }
                    })
                }, 3000)
            }
        })
    }

    _showImmediateToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 0,
        })
    }
    _showImmediateToastAndAnimatedHide = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 0,
            animationEnd : () => {
                this._toast._toastAnimationToggle = this.setTimeout( () => {
                    this._toast.hide({
                        animationEnd: () => {
                            //do sth...
                        }
                    })
                }, 3000)
            }
        })
    }

}

export default TimerEnhance(LoadingToast)<commit_msg>added marginTop prop for Toast<commit_after>
import React, {
    Component,
} from 'react'
import {
    View,
    Text,
    StyleSheet,
    Dimensions,
    ActivityIndicator,
    Modal,
    Alert,
    NativeModules,
} from 'react-native'

import Button from 'react-native-smart-button'
import TimerEnhance from 'react-native-smart-timer-enhance'
import Toast from 'react-native-smart-toast'

class LoadingToast extends Component {

    constructor(props) {
        super(props)
        this.state = {}
    }

    render() {
        return (
            <View style={{ paddingTop: 64, flex: 1, backgroundColor: '#fff',}}>
                <Button
                    onPress={this._showTopToast}
                    touchableType={Button.constants.touchableTypes.fadeContent}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show top
                </Button>

                <Button
                    onPress={this._showCenterToast}
                    touchableType={Button.constants.touchableTypes.highlight}
                    underlayColor={'#C90000'}
                    style={{margin: 10, justifyContent: 'center', height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show center
                </Button>

                <Button
                    onPress={this._showBottomToast}
                    touchableType={Button.constants.touchableTypes.blur}
                    style={{margin: 10, justifyContent: 'center', height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17,  color: 'white'}}

                >
                    show bottom
                </Button>
                <Button
                    onPress={this._showFastToast}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show fast
                </Button>
                <Button
                    onPress={this._showFastToastAndAnimatedHide}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show fast immediate hide
                </Button>
                <Button
                    onPress={this._showImmediateToast}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show immediate
                </Button>
                <Button
                    onPress={this._showImmediateToastAndAnimatedHide}
                    style={{margin: 10, height: 40, backgroundColor: 'red', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: 'red', justifyContent: 'center',}}
                    textStyle={{fontSize: 17, color: 'white'}}
                >
                    show immediate animated hide
                </Button>

                <Toast
                    ref={ component => this._toast = component }
                    marginTop={64}>
                    Unable to connect to app store
                </Toast>
            </View>
        )
    }

    _showTopToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.top,
        })
    }

    _showCenterToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
        })
    }

    _showBottomToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.bottom,
        })
    }

    _showFastToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 255,
        })
    }

    _showFastToastAndAnimatedHide = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 255,
            animationEnd : () => {
                this._toast._toastAnimationToggle = this.setTimeout( () => {
                    this._toast.hide({
                        duration: 0,
                        animationEnd: () => {
                            //do sth...
                        }
                    })
                }, 3000)
            }
        })
    }

    _showImmediateToast = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 0,
        })
    }
    _showImmediateToastAndAnimatedHide = () => {
        this._toast.show({
            position: Toast.constants.gravity.center,
            duration: 0,
            animationEnd : () => {
                this._toast._toastAnimationToggle = this.setTimeout( () => {
                    this._toast.hide({
                        animationEnd: () => {
                            //do sth...
                        }
                    })
                }, 3000)
            }
        })
    }

}

export default TimerEnhance(LoadingToast)<|endoftext|>


<commit_before>var css = [
  '.ninja {',
  '  visibility: hidden;',
  '  color: black;',
  '}'
].join('\n')

var css2jss = require('..').cssToJss
var jss = css2jss(css)
console.log(JSON.stringify(jss, null, 2))
<commit_msg>consistency ftw :-)<commit_after>var css = [
  '.ninja {',
  '  visibility: hidden;',
  '  color: black;',
  '}'
].join('\n')

var cssToJss = require('..').cssToJss
var jss = cssToJss(css)
console.log(JSON.stringify(jss, null, 2))
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');
var Rawr = require('../lib/promptosaurus');
var rawr = new Rawr();

var pkg = {
    "name": '',
    "title": '',
    "description": '',
    "version": "0.1.0",
    "author": {
        "name": '',
        "email": ''
    },
    "repository": {
        "type": "git",
        "url": ""
    }
};

rawr.add('What is the project\'s name?', function(data){
    pkg.name = data;
    pkg.title = data.charAt(0).toUpperCase() + data.slice(1);
})
.add('What does your project do?', function(data){
    pkg.description = data;
})
.add('What is your name?', function(data){
    pkg.author.name = data;
    pkg.repository.url = "git@github.com/";
    pkg.repository.url += pkg.author.name + '/';
    pkg.repository.url += pkg.name + '.git';
})
.add('What is your email?', function(data){
    pkg.author.email = data;
})
.done(function(){
    fs.writeFileSync(process.cwd() + '/package.json', JSON.stringify(pkg), 'utf8');
})
.ask();
<commit_msg>removed example<commit_after><|endoftext|>


<commit_before>/**
 * @fileoverview
 * Data objects and classes for the http logger
 *
 */

/**
 * @class
 * Data class for http logger
 */
window.HTTPLoggerData = new function()
{
    requestList = [];
    requestMap = {};
    selectedRequestId = null;
    var lastModifiedRequestId = null;

    _views = [ "request_info_raw",
               "response_info_raw",
               "request_info_headers",
               "response_info_headers",
               "request_overview",
               "response_info_body",
               "request_list"
             ];

    /**
     * Get the log as a list
     */
    this.getLog = function()
    {
        return requestList;
    }

    /**
     * Get a specific request
     * @argument {string} id the id of the request
     * @returns {object} data object for the request or null if not found
     */
    this.getRequestById = function(id)
    {
        if (id in requestMap) { return requestMap[id] }
        else { return null }
    }

    /**
     * Clear the log data
     *
     */
    this.clearLog = function()
    {
        requestList = [];
        requestMap = {};
        selectedRequestId = null;
        _updateViews();
    }

    /**
     * Add a request to the log
     */
    this.addRequest = function(request)
    {
        var r = { id:request["request-id"],
                  "request": request,
                  response:null, duration: null
                }

        requestList.push(r);
        requestMap[r.id] = r;
        lastModifiedRequestId = r.id;
        _updateViews();
    }

    /**
     * Add a response object to an existing request
     * fixme: now we silently ignore repsonses to non-exstant requests
     */
    this.addResponse = function(response)
    {
        var r = requestMap[response["request-id"]];
        if (r)
        {
            r.response = response;
            if (r.request.time && r.response.time)
            {
                var s = Math.round(parseFloat(r.request.time))
                var e = Math.round(parseFloat(r.response.time))
                r.duration = e-s;
            }
            else
            {
                r.duration = "?";
            }
            lastModifiedRequestId = r.id;
            _updateViews();
        }
    }

    /**
     * Set the currently selected request, that is, the request that is being
     * inspected
     */
    this.setSelectedRequestId = function(id)
    {
        selectedRequestId = id;
        _updateViews();
    }

    /**
     * Clear the selected request
     */
    this.clearSelectedRequest = function()
    {
        selectedRequestId = null;
        _updateViews();
    }

    /**
     * Get the selected request
     */
    this.getSelectedRequest = function()
    {
        if (selectedRequestId && selectedRequestId in requestMap)
        {
            return requestMap[selectedRequestId];
        }
        else
        {
            return null;
        }
    }

    /**
     * Get the ID of the selected request
     */
    this.getSelectedRequestId = function()
    {
        return selectedRequestId;
    }

    this.getLastModifiedRequestId = function()
    {
        return lastModifiedRequestId;
    }

    /**
     * Update all views that use this as a data source
     */
    var _updateViews = function()
    {
        for (var n=0, e; e=_views[n]; n++)
        {
            if (e in window.views) { window.views[e].update() }
        }
    }

}
<commit_msg>Fixed bug with variables being global rather than private<commit_after>/**
 * @fileoverview
 * Data objects and classes for the http logger
 *
 */

/**
 * @class
 * Data class for http logger
 */
window.HTTPLoggerData = new function()
{
    var requestList = [];
    var requestMap = {};
    var selectedRequestId = null;
    var lastModifiedRequestId = null;

    _views = [ "request_info_raw",
               "response_info_raw",
               "request_info_headers",
               "response_info_headers",
               "request_overview",
               "response_info_body",
               "request_list"
             ];

    /**
     * Get the log as a list
     */
    this.getLog = function()
    {
        return requestList;
    }

    /**
     * Get a specific request
     * @argument {string} id the id of the request
     * @returns {object} data object for the request or null if not found
     */
    this.getRequestById = function(id)
    {
        if (id in requestMap) { return requestMap[id] }
        else { return null }
    }

    /**
     * Clear the log data
     *
     */
    this.clearLog = function()
    {
        requestList = [];
        requestMap = {};
        selectedRequestId = null;
        _updateViews();
    }

    /**
     * Add a request to the log
     */
    this.addRequest = function(request)
    {
        var r = { id:request["request-id"],
                  "request": request,
                  response:null, duration: null
                }

        requestList.push(r);
        requestMap[r.id] = r;
        lastModifiedRequestId = r.id;
        _updateViews();
    }

    /**
     * Add a response object to an existing request
     * fixme: now we silently ignore repsonses to non-exstant requests
     */
    this.addResponse = function(response)
    {
        var r = requestMap[response["request-id"]];
        if (r)
        {
            r.response = response;
            if (r.request.time && r.response.time)
            {
                var s = Math.round(parseFloat(r.request.time))
                var e = Math.round(parseFloat(r.response.time))
                r.duration = e-s;
            }
            else
            {
                r.duration = "?";
            }
            lastModifiedRequestId = r.id;
            _updateViews();
        }
    }

    /**
     * Set the currently selected request, that is, the request that is being
     * inspected
     */
    this.setSelectedRequestId = function(id)
    {
        selectedRequestId = id;
        _updateViews();
    }

    /**
     * Clear the selected request
     */
    this.clearSelectedRequest = function()
    {
        selectedRequestId = null;
        _updateViews();
    }

    /**
     * Get the selected request
     */
    this.getSelectedRequest = function()
    {
        if (selectedRequestId && selectedRequestId in requestMap)
        {
            return requestMap[selectedRequestId];
        }
        else
        {
            return null;
        }
    }

    /**
     * Get the ID of the selected request
     */
    this.getSelectedRequestId = function()
    {
        return selectedRequestId;
    }

    this.getLastModifiedRequestId = function()
    {
        return lastModifiedRequestId;
    }

    /**
     * Update all views that use this as a data source
     */
    var _updateViews = function()
    {
        for (var n=0, e; e=_views[n]; n++)
        {
            if (e in window.views) { window.views[e].update() }
        }
    }

}
<|endoftext|>