<commit_before>/* global PouchDB */
'use strict';
var S = S || {};

//TODO paginataion
var req_limit = 1000000;

/**** DEBUG ****/
//TODO disable for live
//PouchDB.debug.enable('*');
PouchDB.debug.disable();
/**** ***** ****/

S.db = {
  /*"localDB" : new PouchDB("local-"+S.config.db.name.replace(/^\/+/, '')), */
  /*"remoteDB" : new PouchDB(S.config.db._full_url, {skipSetup: true}), */
  setUrl : function(dbConfig) {
    S.config.db = dbConfig; //TODO check
    localStorage["sofia-server-config"] = JSON.stringify(S.config.db);
    S.config.db._full_url = S.config.db.url.replace(/\/+$/, '')+"/"+S.config.db.name.replace(/^\/+/, '');
    S.config.db._local_url ="local-"+S.config.db._full_url.replace(/:/gi, '').replace(/\/+/gi, '#');
    //S.config.db._local_url = "local-"+S.config.db.name.replace(/^\/+/, '');

    S.db.localDB = new PouchDB(S.config.db._local_url); // Use the full url in case same db on other domain could lead to corruption //TODO maybe clean it if exist ?
    S.db.remoteDB = new PouchDB(S.config.db._full_url, {skipSetup: true});
  },
  clearLocal : function(){
    return S.db.localDB.destroy();
  }
}

S.db.setUrl(S.config.db);
//S.db_users = new PouchDB(S.config.db._user_url, {skipSetup: true});

S.db.config = {
  getUsers : function(){
    var deferred = new $.Deferred();
    S.db.localDB.get('_design/sofia-config').then(function(doc){
      console.log(deferred.resolve(doc.users || [])) //Return empty array if not present in DB (old version) depends on adentes-org/sofia-db#dd9feee
    }).catch(function (err) {
      console.log(err);
    });
    return deferred.promise();
  },
  getMemo : function(){
    var deferred = new $.Deferred();
    S.db.localDB.getAttachment('_design/sofia-config', 'memo.html').then(function (blob) {
      // handle result
      var reader = new FileReader();
      reader.onload = function(){
        deferred.resolve({ memo : reader.result});
      };
      reader.readAsText(blob);
    }).catch(function (err) {
      console.log(err);
    });
    return deferred.promise();
  }
}
S.db.users = {
  login : function(user,pass,silent){
    //TODO don't use jquery promise
    var deferred = new $.Deferred();
    S.db.remoteDB.login(user, pass, function (err, response) {
      if (err) {
        console.log(err);
        if(!silent){
          //alert(err.message);
          navigator.notification.alert(err.message);
        }
        deferred.reject(err);
      }else{
        if(response.ok) {
          //We are logged in
          console.log("We are logged in !", response);
          S.user.set(user,pass,response);
          S.db.fiches.startSync();
          deferred.resolve(response);
        }
      }
    });
    return deferred.promise();
  }
}

S.db.fiches = {
  changeToParse : 0,
  parseSync : function(info) {
          console.log("Parsing sync : ", info);

          S.vue.router.app.$children[0].$data.options.displayLoadingBar = false;

          console.log("Currently shown page : ",window.location.hash.slice(3).split("/")[0]);
          //switch($(S.vue.router.app.$children[1].$el).attr("id")){
          //TODO detect if refresh needed base on the element refresh and the one being displayed
          switch(window.location.hash.slice(3).split("/")[0]){
              case "memo" :
                        S.db.config.getMemo().then(function(data){
                          S.vue.router.app.$children[1].$data.memo = data.memo;
                          console.log("Updating memo data : ",data)
                        })
                        break;
              case "home" :
                        S.db.fiches.getAllWithMine().then(function(data){
                          S.vue.router.app.$children[1].$data.fiches = data.fiches;
                          S.vue.router.app.$children[1].$data.my_fiches = data.my_fiches;
                          console.log("Updating home data : ",data)
                        })
                        break;
              case "fiche" :
                        var ficheid= window.location.hash.slice(3).split("/")[1]
                        S.db.fiches.getByID(ficheid).then(function (doc) {
                          //S.vue.router.app.$children[1].$data.history
                          //S.vue.router.app.$children[1].$data.fiche
                          S.vue.router.app.$children[1].$data.fiche = doc;
                          S.vue.router.app.$children[0].$data.options.title = doc.patient.firstname +" "+ doc.patient.lastname;

                          //S.vue.router.app.$children[1].$set('fiche', 2)
                        });
                      break;
              default :
                        S.vue.router.replace(window.location.hash.slice(2)); //TODO better reload data not page
                        break;
          }
          if(S.db.fiches.changeToParse>0)
            S.db.fiches.changeToParse--;
  },
  watch : function(sync) {
    sync.on('change', function (change) {
      S.db.fiches.changeToParse++;
      console.log("Pouchdb.sync.change event",change,Date());// yo, something changed!
    }).on('paused', function (info) {
      // replication was paused, usually because of a lost connection or end of transmission
      console.log("Pouchdb.sync.paused event",info,Date());
      //We jsut receive data from server so wa are online
        if(S.vue.router.app.$children[0].$data.options.backColor !== S.config.header.backColor){
          //The header is display not as online
          console.log("Setting header color to online")
          S.vue.router.app.$children[0].$data.options.backColor = S.config.header.backColor;
        } else {
          //The header is display as online
          if(S.db.fiches.offlineTimeout){
            console.log("Clearing offline timeout")
            window.clearTimeout(S.db.fiches.offlineTimeout)
          }
          //We are changing the color if in the n second swe did'nt comme back here
          S.db.fiches.offlineTimeout = window.setTimeout("console.log('Setting header color to offline');S.vue.router.app.$children[0].$data.options.backColor = S.config.header.backColorOffline;",S.config.header.timeoutOffline*1000);
        }
        if(S.db.fiches.changeToParse>0 || S.vue.router.app.$children[0].$data.options.displayLoadingBar)
          S.db.fiches.parseSync(info);
    }).on('active', function (info) {
      console.log("Pouchdb.sync.active event",info,Date());
      // replication was resumed
      S.vue.router.app.$children[0].$data.options.displayLoadingBar = true;
    }).on('error', function (err) {
      console.log("Pouchdb.sync.error event",err,Date());
      // totally unhandled error (shouldn't happen)
    }).on('complete', function (info) {
      console.log("Pouchdb.sync.complete event",info,Date());
      // replication was canceled!
      S.db.fiches.watch(S.db.localDB.sync(S.db.remoteDB, {
        live: true,
        retry: true
      })); //Reload Sync
    });
  },
  startSync : function() {
              console.log("Starting sync ...");
              S.db.fiches.watch(S.db.localDB.sync(S.db.remoteDB, {
                live: true,
                retry: true
              }));
              console.log("Sync in place !");
  },
  post : function(obj) { //Create
    return S.db.localDB.post(obj);
  },
  put : function(obj) { //Update or Create
    //TODO check-up
    obj.pathologys = S.tool.uniq(obj.pathologys); // Remove any duplicate
    return S.db.localDB.put(obj).catch(function (err) {
            console.log(err);
            if (err.status === 409) {
              // conflict! //TODO handle
            } else {
              // some other error
            }
        });
  },
  getByID : function(id) {
    var deferred = new $.Deferred()
    S.db.localDB.get(id).then(function (doc) {
      console.log(doc);
      deferred.resolve(doc);
    }).catch(function (err) {
      // handle err
      console.log(err);
      deferred.reject(err);
    });

    return deferred.promise();

  },
  filterMine : function(fiches) {
    var my_fiches = [];
    $.each(fiches, function( index, doc ) {
      if(doc.owner_id === S.user._current.name){
        my_fiches[my_fiches.length] = doc;
      }
    });
    return my_fiches;
  },
  getAllWithMine : function() {
      var deferred = new $.Deferred()
      S.db.fiches.getAll().then(function(result){
        result.my_fiches = S.db.fiches.filterMine(result.fiches);
        deferred.resolve(result);
      });
      return deferred.promise();
    },
  getAll : function() {
    var deferred = new $.Deferred()
    S.db.localDB.allDocs({include_docs: true,skip:0,limit:req_limit}).then(function (result) {
      // handle result
      var ret = {
          user : S.user._current,
          fiches: []
      }
      $.each(result.rows, function( index, value ) {
        if(value.doc["_id"].split("/")[0] === "_design" ){
          return; //If it's a design doc
        }
        ret.fiches[ret.fiches.length] = value.doc;
        value.doc.last_update = value.doc.events[value.doc.events.length -1].timestamp
        var m = moment(value.doc.last_update);
        value.doc.last_update_since = m.fromNow();
        value.doc.last_update_is_old = m.add(3, 'hours').isBefore();
        var d = moment(value.doc.patient.birthdate);
        value.doc.patient.age = moment().diff(d, 'years')
        value.doc.patient.age_formatted = d.fromNow(true)
      });
      ret.lang =  S.lang;
      deferred.resolve(ret);
    }).catch(function (err) {
      // handle err
      console.log(err);
      deferred.reject(err);
    });
    return deferred.promise();
  },
  //TODO maybe use startkey for get all the team fiches?
  getMyCreationCount : function (){
    var deferred = new $.Deferred()

    S.db.localDB.allDocs({include_docs: true,skip:0,limit:req_limit}).then(function (result) {
      var count = 0;
      $.each(result.rows, function( index, value ) {
        if(value.doc["_id"].split("/")[0] == "_design" ){
          return; //If it's a design doc
        }
        if(value.doc.uid.split("-")[0] === S.user._current.name){
          count ++;
        }
      });
      console.log(count);
      deferred.resolve(count);
    }).catch(function (err) {
        // handle err
        console.log(err);
        deferred.reject(err);
    });

    return deferred.promise();
  },
}
<commit_msg>Follow codacy recommendations<commit_after>/* global PouchDB */
'use strict';
var S = S || {};

//TODO paginataion
var req_limit = 1000000;

/**** DEBUG ****/
//TODO disable for live
//PouchDB.debug.enable('*');
PouchDB.debug.disable();
/**** ***** ****/

S.db = {
  /*"localDB" : new PouchDB("local-"+S.config.db.name.replace(/^\/+/, '')), */
  /*"remoteDB" : new PouchDB(S.config.db._full_url, {skipSetup: true}), */
  setUrl : function(dbConfig) {
    S.config.db = dbConfig; //TODO check
    localStorage["sofia-server-config"] = JSON.stringify(S.config.db);
    S.config.db._full_url = S.config.db.url.replace(/\/+$/, '')+"/"+S.config.db.name.replace(/^\/+/, '');
    S.config.db._local_url ="local-"+S.config.db._full_url.replace(/:/gi, '').replace(/\/+/gi, '#');
    //S.config.db._local_url = "local-"+S.config.db.name.replace(/^\/+/, '');

    S.db.localDB = new PouchDB(S.config.db._local_url); // Use the full url in case same db on other domain could lead to corruption //TODO maybe clean it if exist ?
    S.db.remoteDB = new PouchDB(S.config.db._full_url, {skipSetup: true});
  },
  clearLocal : function(){
    return S.db.localDB.destroy();
  }
}

S.db.setUrl(S.config.db);
//S.db_users = new PouchDB(S.config.db._user_url, {skipSetup: true});

S.db.config = {
  getUsers : function(){
    var deferred = new $.Deferred();
    S.db.localDB.get('_design/sofia-config').then(function(doc){
      console.log(deferred.resolve(doc.users || [])) //Return empty array if not present in DB (old version) depends on adentes-org/sofia-db#dd9feee
    }).catch(function (err) {
      console.log(err);
    });
    return deferred.promise();
  },
  getMemo : function(){
    var deferred = new $.Deferred();
    S.db.localDB.getAttachment('_design/sofia-config', 'memo.html').then(function (blob) {
      // handle result
      var reader = new FileReader();
      reader.onload = function(){
        deferred.resolve({ memo : reader.result});
      };
      reader.readAsText(blob);
    }).catch(function (err) {
      console.log(err);
    });
    return deferred.promise();
  }
}
S.db.users = {
  login : function(user,pass,silent){
    //TODO don't use jquery promise
    var deferred = new $.Deferred();
    S.db.remoteDB.login(user, pass, function (err, response) {
      if (err) {
        console.log(err);
        if(!silent){
          //alert(err.message);
          navigator.notification.alert(err.message);
        }
        deferred.reject(err);
      }else{
        if(response.ok) {
          //We are logged in
          console.log("We are logged in !", response);
          S.user.set(user,pass,response);
          S.db.fiches.startSync();
          deferred.resolve(response);
        }
      }
    });
    return deferred.promise();
  }
}

S.db.fiches = {
  changeToParse : 0,
  parseSync : function(info) {
          console.log("Parsing sync : ", info);

          S.vue.router.app.$children[0].$data.options.displayLoadingBar = false;

          console.log("Currently shown page : ",window.location.hash.slice(3).split("/")[0]);
          //switch($(S.vue.router.app.$children[1].$el).attr("id")){
          //TODO detect if refresh needed base on the element refresh and the one being displayed
          switch(window.location.hash.slice(3).split("/")[0]){
              case "memo" :
                        S.db.config.getMemo().then(function(data){
                          S.vue.router.app.$children[1].$data.memo = data.memo;
                          console.log("Updating memo data : ",data)
                        })
                        break;
              case "home" :
                        S.db.fiches.getAllWithMine().then(function(data){
                          S.vue.router.app.$children[1].$data.fiches = data.fiches;
                          S.vue.router.app.$children[1].$data.my_fiches = data.my_fiches;
                          console.log("Updating home data : ",data)
                        })
                        break;
              case "fiche" :
                        var ficheid= window.location.hash.slice(3).split("/")[1]
                        S.db.fiches.getByID(ficheid).then(function (doc) {
                          //S.vue.router.app.$children[1].$data.history
                          //S.vue.router.app.$children[1].$data.fiche
                          S.vue.router.app.$children[1].$data.fiche = doc;
                          S.vue.router.app.$children[0].$data.options.title = doc.patient.firstname +" "+ doc.patient.lastname;

                          //S.vue.router.app.$children[1].$set('fiche', 2)
                        });
                      break;
              default :
                        S.vue.router.replace(window.location.hash.slice(2)); //TODO better reload data not page
                        break;
          }
          if(S.db.fiches.changeToParse>0)
            S.db.fiches.changeToParse--;
  },
  watch : function(sync) {
    sync.on('change', function (change) {
      S.db.fiches.changeToParse++;
      console.log("Pouchdb.sync.change event",change,Date());// yo, something changed!
    }).on('paused', function (info) {
      // replication was paused, usually because of a lost connection or end of transmission
      console.log("Pouchdb.sync.paused event",info,Date());
      //We jsut receive data from server so wa are online
        if(S.vue.router.app.$children[0].$data.options.backColor !== S.config.header.backColor){
          //The header is display not as online
          console.log("Setting header color to online")
          S.vue.router.app.$children[0].$data.options.backColor = S.config.header.backColor;
        } else {
          //The header is display as online
          if(S.db.fiches.offlineTimeout){
            console.log("Clearing offline timeout")
            window.clearTimeout(S.db.fiches.offlineTimeout)
          }
          //We are changing the color if in the n second swe did'nt comme back here
          S.db.fiches.offlineTimeout = window.setTimeout("console.log('Setting header color to offline');S.vue.router.app.$children[0].$data.options.backColor = S.config.header.backColorOffline;",S.config.header.timeoutOffline*1000);
        }
        if(S.db.fiches.changeToParse>0 || S.vue.router.app.$children[0].$data.options.displayLoadingBar)
          S.db.fiches.parseSync(info);
    }).on('active', function (info) {
      console.log("Pouchdb.sync.active event",info,Date());
      // replication was resumed
      S.vue.router.app.$children[0].$data.options.displayLoadingBar = true;
    }).on('error', function (err) {
      console.log("Pouchdb.sync.error event",err,Date());
      // totally unhandled error (shouldn't happen)
    }).on('complete', function (info) {
      console.log("Pouchdb.sync.complete event",info,Date());
      // replication was canceled!
      S.db.fiches.watch(S.db.localDB.sync(S.db.remoteDB, {
        live: true,
        retry: true
      })); //Reload Sync
    });
  },
  startSync : function() {
              console.log("Starting sync ...");
              S.db.fiches.watch(S.db.localDB.sync(S.db.remoteDB, {
                live: true,
                retry: true
              }));
              console.log("Sync in place !");
  },
  post : function(obj) { //Create
    return S.db.localDB.post(obj);
  },
  put : function(obj) { //Update or Create
    //TODO check-up
    obj.pathologys = S.tool.uniq(obj.pathologys); // Remove any duplicate
    return S.db.localDB.put(obj).catch(function (err) {
            console.log(err);
            if (err.status === 409) {
              // conflict! //TODO handle
            } else {
              // some other error
            }
        });
  },
  getByID : function(id) {
    var deferred = new $.Deferred()
    S.db.localDB.get(id).then(function (doc) {
      console.log(doc);
      deferred.resolve(doc);
    }).catch(function (err) {
      // handle err
      console.log(err);
      deferred.reject(err);
    });

    return deferred.promise();

  },
  filterMine : function(fiches) {
    var my_fiches = [];
    $.each(fiches, function( index, doc ) {
      if(doc.owner_id === S.user._current.name){
        my_fiches[my_fiches.length] = doc;
      }
    });
    return my_fiches;
  },
  getAllWithMine : function() {
      var deferred = new $.Deferred()
      S.db.fiches.getAll().then(function(result){
        result.my_fiches = S.db.fiches.filterMine(result.fiches);
        deferred.resolve(result);
      });
      return deferred.promise();
    },
  getAll : function() {
    var deferred = new $.Deferred()
    S.db.localDB.allDocs({include_docs: true,skip:0,limit:req_limit}).then(function (result) {
      // handle result
      var ret = {
          user : S.user._current,
          fiches: []
      }
      $.each(result.rows, function( index, value ) {
        if(value.doc["_id"].split("/")[0] === "_design" ){
          return; //If it's a design doc
        }
        ret.fiches[ret.fiches.length] = value.doc;
        value.doc.last_update = value.doc.events[value.doc.events.length -1].timestamp
        var m = moment(value.doc.last_update);
        value.doc.last_update_since = m.fromNow();
        value.doc.last_update_is_old = m.add(3, 'hours').isBefore();
        var d = moment(value.doc.patient.birthdate);
        value.doc.patient.age = moment().diff(d, 'years')
        value.doc.patient.age_formatted = d.fromNow(true)
      });
      ret.lang =  S.lang;
      deferred.resolve(ret);
    }).catch(function (err) {
      // handle err
      console.log(err);
      deferred.reject(err);
    });
    return deferred.promise();
  },
  //TODO maybe use startkey for get all the team fiches?
  getMyCreationCount : function (){
    var deferred = new $.Deferred()

    S.db.localDB.allDocs({include_docs: true,skip:0,limit:req_limit}).then(function (result) {
      var count = 0;
      $.each(result.rows, function( index, value ) {
        if(value.doc["_id"].split("/")[0] === "_design" ){
          return; //If it's a design doc
        }
        if(value.doc.uid.split("-")[0] === S.user._current.name){
          count ++;
        }
      });
      console.log(count);
      deferred.resolve(count);
    }).catch(function (err) {
        // handle err
        console.log(err);
        deferred.reject(err);
    });

    return deferred.promise();
  },
}
<|endoftext|>


<commit_before>;(function($$){ 'use strict';

  var defaults = {
    fit: true, // whether to fit the viewport to the graph
    directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)
    padding: 30, // padding on fit
    circle: false, // put depths in concentric circles if true, put depths top down if false
    boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space
    roots: undefined, // the roots of the trees
    maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)
    animate: false, // whether to transition the node positions
    animationDuration: 500, // duration of animation in ms if enabled
    ready: undefined, // callback on layoutready
    stop: undefined // callback on layoutstop
  };

  function BreadthFirstLayout( options ){
    this.options = $$.util.extend({}, defaults, options);
  }

  BreadthFirstLayout.prototype.run = function(){
    var params = this.options;
    var options = params;

    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    var graph = eles;

    var bb = $$.util.makeBoundingBox( options.boundingBox ? options.boundingBox : {
      x1: 0, y1: 0, w: cy.width(), h: cy.height()
    } );

    var roots;
    if( $$.is.elementOrCollection(options.roots) ){
      roots = options.roots;
    } else if( $$.is.array(options.roots) ){
      var rootsArray = [];

      for( var i = 0; i < options.roots.length; i++ ){
        var id = options.roots[i];
        var ele = cy.getElementById( id );
        rootsArray.push( ele );
      }

      roots = new $$.Collection( cy, rootsArray );
    } else if( $$.is.string(options.roots) ){
      roots = cy.$( options.roots );

    } else {
      if( options.directed ){
        roots = nodes.roots();
      } else {
        var components = [];
        var unhandledNodes = nodes;

        while( unhandledNodes.length > 0 ){
          var currComp = cy.collection();

          eles.bfs({
            roots: unhandledNodes[0],
            visit: function(i, depth, node, edge, pNode){
              currComp = currComp.add( node );
            },
            directed: false
          });

          unhandledNodes = unhandledNodes.not( currComp );
          components.push( currComp );
        }

        roots = cy.collection();
        for( var i = 0; i < components.length; i++ ){
          var comp = components[i];
          var maxDegree = comp.maxDegree( false );
          var compRoots = comp.filter(function(){
            return this.degree(false) === maxDegree;
          });

          roots = roots.add( compRoots );
        }

      }
    }

    var depths = [];
    var foundByBfs = {};
    var id2depth = {};
    var prevNode = {};
    var prevEdge = {};
    var successors = {};

    // find the depths of the nodes
    graph.bfs({
      roots: roots,
      directed: options.directed,
      visit: function(i, depth, node, edge, pNode){
        var ele = this[0];
        var id = ele.id();

        if( !depths[depth] ){
          depths[depth] = [];
        }

        depths[depth].push( ele );
        foundByBfs[ id ] = true;
        id2depth[ id ] = depth;
        prevNode[ id ] = pNode;
        prevEdge[ id ] = edge;

        if( pNode ){
          var prevId = pNode.id();
          var succ = successors[ prevId ] = successors[ prevId ] || [];

          succ.push( node );
        }
      }
    });

    // check for nodes not found by bfs
    var orphanNodes = [];
    for( var i = 0; i < nodes.length; i++ ){
      var ele = nodes[i];

      if( foundByBfs[ ele.id() ] ){
        continue;
      } else {
        orphanNodes.push( ele );
      }
    }

    // assign orphan nodes a depth from their neighborhood
    var maxChecks = orphanNodes.length * 3;
    var checks = 0;
    while( orphanNodes.length !== 0 && checks < maxChecks ){
      var node = orphanNodes.shift();
      var neighbors = node.neighborhood().nodes();
      var assignedDepth = false;

      for( var i = 0; i < neighbors.length; i++ ){
        var depth = id2depth[ neighbors[i].id() ];

        if( depth !== undefined ){
          depths[depth].push( node );
          assignedDepth = true;
          break;
        }
      }

      if( !assignedDepth ){
        orphanNodes.push( node );
      }

      checks++;
    }

    // assign orphan nodes that are still left to the depth of their subgraph
    while( orphanNodes.length !== 0 ){
      var node = orphanNodes.shift();
      //var subgraph = graph.bfs( node ).path;
      var assignedDepth = false;

      // for( var i = 0; i < subgraph.length; i++ ){
      //   var depth = id2depth[ subgraph[i].id() ];

      //   if( depth !== undefined ){
      //     depths[depth].push( node );
      //     assignedDepth = true;
      //     break;
      //   }
      // }

      if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0
        if( depths.length === 0 ){
          depths.push([]);
        }

        depths[0].push( node );
      }
    }

    // assign the nodes a depth and index
    var assignDepthsToEles = function(){
      for( var i = 0; i < depths.length; i++ ){
        var eles = depths[i];

        for( var j = 0; j < eles.length; j++ ){
          var ele = eles[j];

          ele._private.scratch.breadthfirst = {
            depth: i,
            index: j
          };
        }
      }
    };
    assignDepthsToEles();

    var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth
      var edges = node.connectedEdges(function(){
        return this.data('target') === node.id();
      });
      var thisInfo = node._private.scratch.breadthfirst;
      var highestDepthOfOther = 0;
      var highestOther;
      for( var i = 0; i < edges.length; i++ ){
        var edge = edges[i];
        var otherNode = edge.source()[0];
        var otherInfo = otherNode._private.scratch.breadthfirst;

        if( thisInfo.depth <= otherInfo.depth && highestDepthOfOther < otherInfo.depth ){
          highestDepthOfOther = otherInfo.depth;
          highestOther = otherNode;
        }
      }

      return highestOther;
    };

     // make maximal if so set by adjusting depths
    for( var adj = 0; adj < options.maximalAdjustments; adj++ ){

      var nDepths = depths.length;
      var elesToMove = [];
      for( var i = 0; i < nDepths; i++ ){
        var depth = depths[i];

        var nDepth = depth.length;
        for( var j = 0; j < nDepth; j++ ){
          var ele = depth[j];
          var info = ele._private.scratch.breadthfirst;
          var intEle = intersectsDepth(ele);

          if( intEle ){
            info.intEle = intEle;
            elesToMove.push( ele );
          }
        }
      }

      for( var i = 0; i < elesToMove.length; i++ ){
        var ele = elesToMove[i];
        var info = ele._private.scratch.breadthfirst;
        var intEle = info.intEle;
        var intInfo = intEle._private.scratch.breadthfirst;

        depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index

        // add to end of new depth
        var newDepth = intInfo.depth + 1;
        while( newDepth > depths.length - 1 ){
          depths.push([]);
        }
        depths[ newDepth ].push( ele );

        info.depth = newDepth;
        info.index = depths[newDepth].length - 1;
      }

      assignDepthsToEles();
    }

    // find min distance we need to leave between nodes
    var minDistance = 0;
    if( options.avoidOverlap ){
      for( var i = 0; i < nodes.length; i++ ){
        var w = nodes[i].outerWidth();
        var h = nodes[i].outerHeight();

        minDistance = Math.max(minDistance, w, h);
      }
      minDistance *= 1.75; // just to have some nice spacing
    }

    // get the weighted percent for an element based on its connectivity to other levels
    var cachedWeightedPercent = {};
    var getWeightedPercent = function( ele ){
      if( cachedWeightedPercent[ ele.id() ] ){
        return cachedWeightedPercent[ ele.id() ];
      }

      var eleDepth = ele._private.scratch.breadthfirst.depth;
      var neighbors = ele.neighborhood().nodes();
      var percent = 0;
      var samples = 0;

      for( var i = 0; i < neighbors.length; i++ ){
        var neighbor = neighbors[i];
        var index = neighbor._private.scratch.breadthfirst.index;
        var depth = neighbor._private.scratch.breadthfirst.depth;
        var nDepth = depths[depth].length;

        if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above
          percent += index / nDepth;
          samples++;
        }
      }

      samples = Math.max(1, samples);
      percent = percent / samples;

      if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting
        percent = undefined;
      }

      cachedWeightedPercent[ ele.id() ] = percent;
      return percent;
    };

    // rearrange the indices in each depth level based on connectivity

    var sortFn = function(a, b){
      var apct = getWeightedPercent( a );
      var bpct = getWeightedPercent( b );

      return apct - bpct;
    };

    for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result

      for( var i = 0; i < depths.length; i++ ){
        depths[i] = depths[i].sort( sortFn );
      }
      assignDepthsToEles(); // and update

    }

    var biggestDepthSize = 0;
    for( var i = 0; i < depths.length; i++ ){
      biggestDepthSize = Math.max( depths[i].length, biggestDepthSize );
    }

    var center = {
      x: bb.x1 + bb.w/2,
      y: bb.x1 + bb.h/2
    };

    var getPosition = function( ele, isBottomDepth ){
      var info = ele._private.scratch.breadthfirst;
      var depth = info.depth;
      var index = info.index;
      var depthSize = depths[depth].length;

      if( options.strictHierarchy ){
        depthSize = biggestDepthSize;
      }

      var distanceX = Math.max( bb.w / (depthSize + 1), minDistance );
      var distanceY = Math.max( bb.h / (depths.length + 1), minDistance );
      var radiusStepSize = Math.min( bb.w / 2 / depths.length, bb.h / 2 / depths.length );
      radiusStepSize = Math.max( radiusStepSize, minDistance );

      if( options.strictHierarchy && !options.circle ){

        var epos = {
          x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,
          y: (depth + 1) * distanceY
        };

        if( isBottomDepth ){
          return epos;
        }

        var succs = successors[ ele.id() ];
        if( succs ){
          epos.x = 0;

          for( var i = 0 ; i < succs.length; i++ ){
            var spos = pos[ succs[i].id() ];

            epos.x += spos.x;
          }

          epos.x /= succs.length;
        } else {
          //debugger;
        }

        return epos;

      } else {
        if( options.circle ){
          var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0);
          var theta = 2 * Math.PI / depths[depth].length * index;

          if( depth === 0 && depths[0].length === 1 ){
            radius = 1;
          }

          return {
            x: center.x + radius * Math.cos(theta),
            y: center.y + radius * Math.sin(theta)
          };

        } else {
          return {
            x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,
            y: (depth + 1) * distanceY
          };
        }
      }

    };

    // get positions in reverse depth order
    var pos = {};
    for( var i = depths.length - 1; i >=0; i-- ){
      var depth = depths[i];

      for( var j = 0; j < depth.length; j++ ){
        var node = depth[j];

        pos[ node.id() ] = getPosition( node, i === depths.length - 1 );
      }
    }

    nodes.layoutPositions(this, options, function(){
      return pos[ this.id() ];
    });

    return this; // chaining
  };

  $$('layout', 'breadthfirst', BreadthFirstLayout);

})( cytoscape );
<commit_msg>remove refs to strictHierarchy for #891<commit_after>;(function($$){ 'use strict';

  var defaults = {
    fit: true, // whether to fit the viewport to the graph
    directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)
    padding: 30, // padding on fit
    circle: false, // put depths in concentric circles if true, put depths top down if false
    boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space
    roots: undefined, // the roots of the trees
    maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)
    animate: false, // whether to transition the node positions
    animationDuration: 500, // duration of animation in ms if enabled
    ready: undefined, // callback on layoutready
    stop: undefined // callback on layoutstop
  };

  function BreadthFirstLayout( options ){
    this.options = $$.util.extend({}, defaults, options);
  }

  BreadthFirstLayout.prototype.run = function(){
    var params = this.options;
    var options = params;

    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    var graph = eles;

    var bb = $$.util.makeBoundingBox( options.boundingBox ? options.boundingBox : {
      x1: 0, y1: 0, w: cy.width(), h: cy.height()
    } );

    var roots;
    if( $$.is.elementOrCollection(options.roots) ){
      roots = options.roots;
    } else if( $$.is.array(options.roots) ){
      var rootsArray = [];

      for( var i = 0; i < options.roots.length; i++ ){
        var id = options.roots[i];
        var ele = cy.getElementById( id );
        rootsArray.push( ele );
      }

      roots = new $$.Collection( cy, rootsArray );
    } else if( $$.is.string(options.roots) ){
      roots = cy.$( options.roots );

    } else {
      if( options.directed ){
        roots = nodes.roots();
      } else {
        var components = [];
        var unhandledNodes = nodes;

        while( unhandledNodes.length > 0 ){
          var currComp = cy.collection();

          eles.bfs({
            roots: unhandledNodes[0],
            visit: function(i, depth, node, edge, pNode){
              currComp = currComp.add( node );
            },
            directed: false
          });

          unhandledNodes = unhandledNodes.not( currComp );
          components.push( currComp );
        }

        roots = cy.collection();
        for( var i = 0; i < components.length; i++ ){
          var comp = components[i];
          var maxDegree = comp.maxDegree( false );
          var compRoots = comp.filter(function(){
            return this.degree(false) === maxDegree;
          });

          roots = roots.add( compRoots );
        }

      }
    }

    var depths = [];
    var foundByBfs = {};
    var id2depth = {};
    var prevNode = {};
    var prevEdge = {};
    var successors = {};

    // find the depths of the nodes
    graph.bfs({
      roots: roots,
      directed: options.directed,
      visit: function(i, depth, node, edge, pNode){
        var ele = this[0];
        var id = ele.id();

        if( !depths[depth] ){
          depths[depth] = [];
        }

        depths[depth].push( ele );
        foundByBfs[ id ] = true;
        id2depth[ id ] = depth;
        prevNode[ id ] = pNode;
        prevEdge[ id ] = edge;

        if( pNode ){
          var prevId = pNode.id();
          var succ = successors[ prevId ] = successors[ prevId ] || [];

          succ.push( node );
        }
      }
    });

    // check for nodes not found by bfs
    var orphanNodes = [];
    for( var i = 0; i < nodes.length; i++ ){
      var ele = nodes[i];

      if( foundByBfs[ ele.id() ] ){
        continue;
      } else {
        orphanNodes.push( ele );
      }
    }

    // assign orphan nodes a depth from their neighborhood
    var maxChecks = orphanNodes.length * 3;
    var checks = 0;
    while( orphanNodes.length !== 0 && checks < maxChecks ){
      var node = orphanNodes.shift();
      var neighbors = node.neighborhood().nodes();
      var assignedDepth = false;

      for( var i = 0; i < neighbors.length; i++ ){
        var depth = id2depth[ neighbors[i].id() ];

        if( depth !== undefined ){
          depths[depth].push( node );
          assignedDepth = true;
          break;
        }
      }

      if( !assignedDepth ){
        orphanNodes.push( node );
      }

      checks++;
    }

    // assign orphan nodes that are still left to the depth of their subgraph
    while( orphanNodes.length !== 0 ){
      var node = orphanNodes.shift();
      //var subgraph = graph.bfs( node ).path;
      var assignedDepth = false;

      // for( var i = 0; i < subgraph.length; i++ ){
      //   var depth = id2depth[ subgraph[i].id() ];

      //   if( depth !== undefined ){
      //     depths[depth].push( node );
      //     assignedDepth = true;
      //     break;
      //   }
      // }

      if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0
        if( depths.length === 0 ){
          depths.push([]);
        }

        depths[0].push( node );
      }
    }

    // assign the nodes a depth and index
    var assignDepthsToEles = function(){
      for( var i = 0; i < depths.length; i++ ){
        var eles = depths[i];

        for( var j = 0; j < eles.length; j++ ){
          var ele = eles[j];

          ele._private.scratch.breadthfirst = {
            depth: i,
            index: j
          };
        }
      }
    };
    assignDepthsToEles();

    var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth
      var edges = node.connectedEdges(function(){
        return this.data('target') === node.id();
      });
      var thisInfo = node._private.scratch.breadthfirst;
      var highestDepthOfOther = 0;
      var highestOther;
      for( var i = 0; i < edges.length; i++ ){
        var edge = edges[i];
        var otherNode = edge.source()[0];
        var otherInfo = otherNode._private.scratch.breadthfirst;

        if( thisInfo.depth <= otherInfo.depth && highestDepthOfOther < otherInfo.depth ){
          highestDepthOfOther = otherInfo.depth;
          highestOther = otherNode;
        }
      }

      return highestOther;
    };

     // make maximal if so set by adjusting depths
    for( var adj = 0; adj < options.maximalAdjustments; adj++ ){

      var nDepths = depths.length;
      var elesToMove = [];
      for( var i = 0; i < nDepths; i++ ){
        var depth = depths[i];

        var nDepth = depth.length;
        for( var j = 0; j < nDepth; j++ ){
          var ele = depth[j];
          var info = ele._private.scratch.breadthfirst;
          var intEle = intersectsDepth(ele);

          if( intEle ){
            info.intEle = intEle;
            elesToMove.push( ele );
          }
        }
      }

      for( var i = 0; i < elesToMove.length; i++ ){
        var ele = elesToMove[i];
        var info = ele._private.scratch.breadthfirst;
        var intEle = info.intEle;
        var intInfo = intEle._private.scratch.breadthfirst;

        depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index

        // add to end of new depth
        var newDepth = intInfo.depth + 1;
        while( newDepth > depths.length - 1 ){
          depths.push([]);
        }
        depths[ newDepth ].push( ele );

        info.depth = newDepth;
        info.index = depths[newDepth].length - 1;
      }

      assignDepthsToEles();
    }

    // find min distance we need to leave between nodes
    var minDistance = 0;
    if( options.avoidOverlap ){
      for( var i = 0; i < nodes.length; i++ ){
        var w = nodes[i].outerWidth();
        var h = nodes[i].outerHeight();

        minDistance = Math.max(minDistance, w, h);
      }
      minDistance *= 1.75; // just to have some nice spacing
    }

    // get the weighted percent for an element based on its connectivity to other levels
    var cachedWeightedPercent = {};
    var getWeightedPercent = function( ele ){
      if( cachedWeightedPercent[ ele.id() ] ){
        return cachedWeightedPercent[ ele.id() ];
      }

      var eleDepth = ele._private.scratch.breadthfirst.depth;
      var neighbors = ele.neighborhood().nodes();
      var percent = 0;
      var samples = 0;

      for( var i = 0; i < neighbors.length; i++ ){
        var neighbor = neighbors[i];
        var index = neighbor._private.scratch.breadthfirst.index;
        var depth = neighbor._private.scratch.breadthfirst.depth;
        var nDepth = depths[depth].length;

        if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above
          percent += index / nDepth;
          samples++;
        }
      }

      samples = Math.max(1, samples);
      percent = percent / samples;

      if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting
        percent = undefined;
      }

      cachedWeightedPercent[ ele.id() ] = percent;
      return percent;
    };

    // rearrange the indices in each depth level based on connectivity

    var sortFn = function(a, b){
      var apct = getWeightedPercent( a );
      var bpct = getWeightedPercent( b );

      return apct - bpct;
    };

    for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result

      for( var i = 0; i < depths.length; i++ ){
        depths[i] = depths[i].sort( sortFn );
      }
      assignDepthsToEles(); // and update

    }

    var biggestDepthSize = 0;
    for( var i = 0; i < depths.length; i++ ){
      biggestDepthSize = Math.max( depths[i].length, biggestDepthSize );
    }

    var center = {
      x: bb.x1 + bb.w/2,
      y: bb.x1 + bb.h/2
    };

    var getPosition = function( ele, isBottomDepth ){
      var info = ele._private.scratch.breadthfirst;
      var depth = info.depth;
      var index = info.index;
      var depthSize = depths[depth].length;

      var distanceX = Math.max( bb.w / (depthSize + 1), minDistance );
      var distanceY = Math.max( bb.h / (depths.length + 1), minDistance );
      var radiusStepSize = Math.min( bb.w / 2 / depths.length, bb.h / 2 / depths.length );
      radiusStepSize = Math.max( radiusStepSize, minDistance );

      if( !options.circle ){

        var epos = {
          x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,
          y: (depth + 1) * distanceY
        };

        if( isBottomDepth ){
          return epos;
        }

        var succs = successors[ ele.id() ];
        if( succs ){
          epos.x = 0;

          for( var i = 0 ; i < succs.length; i++ ){
            var spos = pos[ succs[i].id() ];

            epos.x += spos.x;
          }

          epos.x /= succs.length;
        } else {
          //debugger;
        }

        return epos;

      } else {
        if( options.circle ){
          var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0);
          var theta = 2 * Math.PI / depths[depth].length * index;

          if( depth === 0 && depths[0].length === 1 ){
            radius = 1;
          }

          return {
            x: center.x + radius * Math.cos(theta),
            y: center.y + radius * Math.sin(theta)
          };

        } else {
          return {
            x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,
            y: (depth + 1) * distanceY
          };
        }
      }

    };

    // get positions in reverse depth order
    var pos = {};
    for( var i = depths.length - 1; i >=0; i-- ){
      var depth = depths[i];

      for( var j = 0; j < depth.length; j++ ){
        var node = depth[j];

        pos[ node.id() ] = getPosition( node, i === depths.length - 1 );
      }
    }

    nodes.layoutPositions(this, options, function(){
      return pos[ this.id() ];
    });

    return this; // chaining
  };

  $$('layout', 'breadthfirst', BreadthFirstLayout);

})( cytoscape );
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Definitions for W3C's Navigation Timing specification.
 *
 * Created from
 * http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
 *
 * @externs
 */

/** @constructor */
function PerformanceTiming() {}
/** @type {number} */ PerformanceTiming.prototype.navigationStart;
/** @type {number} */ PerformanceTiming.prototype.unloadEventStart;
/** @type {number} */ PerformanceTiming.prototype.unloadEventEnd;
/** @type {number} */ PerformanceTiming.prototype.redirectStart;
/** @type {number} */ PerformanceTiming.prototype.redirectEnd;
/** @type {number} */ PerformanceTiming.prototype.fetchStart;
/** @type {number} */ PerformanceTiming.prototype.domainLookupStart;
/** @type {number} */ PerformanceTiming.prototype.domainLookupEnd;
/** @type {number} */ PerformanceTiming.prototype.connectStart;
/** @type {number} */ PerformanceTiming.prototype.connectEnd;
/** @type {number} */ PerformanceTiming.prototype.secureConnectionStart;
/** @type {number} */ PerformanceTiming.prototype.requestStart;
/** @type {number} */ PerformanceTiming.prototype.responseStart;
/** @type {number} */ PerformanceTiming.prototype.responseEnd;
/** @type {number} */ PerformanceTiming.prototype.domLoading;
/** @type {number} */ PerformanceTiming.prototype.domInteractive;
/** @type {number} */ PerformanceTiming.prototype.domContentLoadedEventStart;
/** @type {number} */ PerformanceTiming.prototype.domContentLoadedEventEnd;
/** @type {number} */ PerformanceTiming.prototype.domComplete;
/** @type {number} */ PerformanceTiming.prototype.loadEventStart;
/** @type {number} */ PerformanceTiming.prototype.loadEventEnd;

/** @constructor */
function PerformanceNavigation() {}
/** @type {number} */ PerformanceNavigation.prototype.TYPE_NAVIGATE = 0;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_RELOAD = 1;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_BACK_FORWARD = 2;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_RESERVED = 255;
/** @type {number} */ PerformanceNavigation.prototype.type;
/** @type {number} */ PerformanceNavigation.prototype.redirectCount;

// Only available in WebKit, and only with the --enable-memory-info flag.
/** @constructor */
function PerformanceMemory() {}
/** @type {number} */ PerformanceMemory.prototype.jsHeapSizeLimit;
/** @type {number} */ PerformanceMemory.prototype.totalJSHeapSize;
/** @type {number} */ PerformanceMemory.prototype.usedJSHeapSize;

/** @constructor */
function Performance() {}
/** @type {PerformanceTiming} */ Performance.prototype.timing;
/** @type {PerformanceNavigation} */ Performance.prototype.navigation;

// Only available in WebKit, and only with the --enable-memory-info flag.
/** @type {PerformanceMemory} */ Performance.prototype.memory;

/** @type {Performance} */
Window.prototype.performance;
<commit_msg><commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Definitions for W3C's Navigation Timing specification.
 *
 * Created from
 * @see http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
 * @see http://w3c-test.org/webperf/specs/ResourceTiming
 * @see http://www.w3.org/TR/performance-timeline
 *
 * @externs
 */

/** @constructor */
function PerformanceTiming() {}
/** @type {number} */ PerformanceTiming.prototype.navigationStart;
/** @type {number} */ PerformanceTiming.prototype.unloadEventStart;
/** @type {number} */ PerformanceTiming.prototype.unloadEventEnd;
/** @type {number} */ PerformanceTiming.prototype.redirectStart;
/** @type {number} */ PerformanceTiming.prototype.redirectEnd;
/** @type {number} */ PerformanceTiming.prototype.fetchStart;
/** @type {number} */ PerformanceTiming.prototype.domainLookupStart;
/** @type {number} */ PerformanceTiming.prototype.domainLookupEnd;
/** @type {number} */ PerformanceTiming.prototype.connectStart;
/** @type {number} */ PerformanceTiming.prototype.connectEnd;
/** @type {number} */ PerformanceTiming.prototype.secureConnectionStart;
/** @type {number} */ PerformanceTiming.prototype.requestStart;
/** @type {number} */ PerformanceTiming.prototype.responseStart;
/** @type {number} */ PerformanceTiming.prototype.responseEnd;
/** @type {number} */ PerformanceTiming.prototype.domLoading;
/** @type {number} */ PerformanceTiming.prototype.domInteractive;
/** @type {number} */ PerformanceTiming.prototype.domContentLoadedEventStart;
/** @type {number} */ PerformanceTiming.prototype.domContentLoadedEventEnd;
/** @type {number} */ PerformanceTiming.prototype.domComplete;
/** @type {number} */ PerformanceTiming.prototype.loadEventStart;
/** @type {number} */ PerformanceTiming.prototype.loadEventEnd;

/** @constructor */
function PerformanceEntry() {}
/** @type {string} */ PerformanceEntry.prototype.name;
/** @type {string} */ PerformanceEntry.prototype.entryType;
/** @type {number} */ PerformanceEntry.prototype.startTime;
/** @type {number} */ PerformanceEntry.prototype.duration;

/**
 * @constructor
 * @extends {PerformanceEntry}
 */
function PerformanceResourceTiming() {}
/** @type {number} */ PerformanceResourceTiming.prototype.redirectStart;
/** @type {number} */ PerformanceResourceTiming.prototype.redirectEnd;
/** @type {number} */ PerformanceResourceTiming.prototype.fetchStart;
/** @type {number} */ PerformanceResourceTiming.prototype.domainLookupStart;
/** @type {number} */ PerformanceResourceTiming.prototype.domainLookupEnd;
/** @type {number} */ PerformanceResourceTiming.prototype.connectStart;
/** @type {number} */ PerformanceResourceTiming.prototype.connectEnd;
/** @type {number} */
PerformanceResourceTiming.prototype.secureConnectionStart;
/** @type {number} */ PerformanceResourceTiming.prototype.requestStart;
/** @type {number} */ PerformanceResourceTiming.prototype.responseStart;
/** @type {number} */ PerformanceResourceTiming.prototype.responseEnd;
/** @type {string} */ PerformanceResourceTiming.prototype.initiatorType;

/** @constructor */
function PerformanceNavigation() {}
/** @type {number} */ PerformanceNavigation.prototype.TYPE_NAVIGATE = 0;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_RELOAD = 1;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_BACK_FORWARD = 2;
/** @type {number} */ PerformanceNavigation.prototype.TYPE_RESERVED = 255;
/** @type {number} */ PerformanceNavigation.prototype.type;
/** @type {number} */ PerformanceNavigation.prototype.redirectCount;

// Only available in WebKit, and only with the --enable-memory-info flag.
/** @constructor */
function PerformanceMemory() {}
/** @type {number} */ PerformanceMemory.prototype.jsHeapSizeLimit;
/** @type {number} */ PerformanceMemory.prototype.totalJSHeapSize;
/** @type {number} */ PerformanceMemory.prototype.usedJSHeapSize;

/** @constructor */
function Performance() {}
/** @type {PerformanceTiming} */ Performance.prototype.timing;
/** @type {PerformanceNavigation} */ Performance.prototype.navigation;

/**
 * Clears the buffer used to store the current list of
 * PerformanceResourceTiming resources.
 * @return {undefined}
 */
Performance.prototype.clearResourceTimings = function() {};

/**
 * Set the maximum number of PerformanceResourceTiming resources that may be
 * stored in the buffer.
 * @param {number} maxSize
 */
Performance.prototype.setResourceTimingBufferSize = function(maxSize) {};

/**
 * @return {Array.<PerformanceEntry>} A copy of the PerformanceEntry list,
 *     in chronological order with respect to startTime.
 */
Performance.prototype.getEntries = function() {};

/**
 * @param {string} entryType Only return {@code PerformanceEntry}s with this
 *     entryType.
 * @return {Array.<PerformanceEntry>} A copy of the PerformanceEntry list,
 *     in chronological order with respect to startTime.
 */
Performance.prototype.getEntriesByType = function(entryType) {};

/**
 * @param {string} name Only return {@code PerformanceEntry}s with this name.
 * @param {string=} opt_entryType Only return {@code PerformanceEntry}s with
 *     this entryType.
 * @return {Array.<PerformanceEntry>} PerformanceEntry list in chronological
 *     order with respect to startTime.
 */
Performance.prototype.getEntriesByName = function(name, opt_entryType) {};

// Only available in WebKit, and only with the --enable-memory-info flag.
/** @type {PerformanceMemory} */ Performance.prototype.memory;

/** @type {Performance} */
Window.prototype.performance;
<|endoftext|>


<commit_before>var _ = require('underscore');
var Model = require('../core/model');

var STATUS = {
  PENDING: 'pending',
  WAITING: 'waiting',
  RUNNING: 'running',
  FAILED: 'failed',
  READY: 'ready'
};

var AnalysisModel = Model.extend({

  initialize: function (attrs, opts) {
    opts = opts || {};
    if (!opts.camshaftReference) {
      throw new Error('chamshaftReference is required');
    }

    if (!opts.vis) {
      throw new Error('vis is required');
    }

    this._camshaftReference = opts.camshaftReference;
    this._vis = opts.vis;
    this._initBinds();
  },

  url: function () {
    var url = this.get('url');
    if (url) {
      if (this.get('apiKey')) {
        url += '?api_key=' + this.get('apiKey');
      } else if (this.get('authToken')) {
        var authToken = this.get('authToken');
        if (authToken instanceof Array) {
          var tokens = _.map(authToken, function (token) {
            return 'auth_token[]=' + token;
          });
          url += '?' + tokens.join('&');
        } else {
          url += '?auth_token=' + authToken;
        }
      }
      return url;
    }
  },

  setOk: function () {
    this.unset('error');
  },

  setError: function (error) {
    this.set({
      error: error,
      status: STATUS.FAILED
    });
  },

  _initBinds: function () {
    this.bind('change:type', function () {
      this.unbind(null, null, this);
      this._initBinds();
      this._reloadVis();
    }, this);

    _.each(this.getParamNames(), function (paramName) {
      this.bind('change:' + paramName, this._reloadVis, this);
    }, this);
  },

  _reloadVis: function (opts) {
    opts = opts || {};
    opts.error = this._onMapReloadError.bind(this);
    this._vis.reload(opts);
  },

  _onMapReloadError: function () {
    this.set('status', STATUS.FAILED);
  },

  remove: function () {
    this.trigger('destroy', this);
    this.stopListening();
  },

  findAnalysisById: function (analysisId) {
    if (this.get('id') === analysisId) {
      return this;
    }
    var sources = _.chain(this._getSourceNames())
      .map(function (sourceName) {
        var source = this.get(sourceName);
        if (source) {
          return source.findAnalysisById(analysisId);
        }
      }, this)
      .compact()
      .value();

    return sources[0];
  },

  _getSourceNames: function () {
    return this._camshaftReference.getSourceNamesForAnalysisType(this.get('type'));
  },

  isDone: function () {
    return this._anyStatus(STATUS.READY, STATUS.FAILED);
  },

  isFailed: function () {
    return this._anyStatus(STATUS.FAILED);
  },

  isLoading: function () {
    return this._anyStatus(STATUS.PENDING, STATUS.WAITING, STATUS.RUNNING);
  },

  _anyStatus: function () {
    var list = Array.prototype.slice.call(arguments, 0);
    return list.indexOf(this.get('status')) !== -1;
  },

  toJSON: function () {
    var json = _.pick(this.attributes, 'id', 'type');
    json.params = _.pick(this.attributes, this.getParamNames());
    var sourceNames = this._getSourceNames();
    _.each(sourceNames, function (sourceName) {
      var source = {};
      var sourceInfo = this.get(sourceName);
      if (sourceInfo) {
        source[sourceName] = sourceInfo.toJSON();
        _.extend(json.params, source);
      }
    }, this);

    return json;
  },

  getParamNames: function () {
    return this._camshaftReference.getParamNamesForAnalysisType(this.get('type'));
  },

  /**
   * Compare two analysisModels.
   */
  equals: function (analysisModel) {
    if (!(analysisModel instanceof AnalysisModel)) {
      return false;
    }
    // Since all analysis are created using the analysisFactory different ids ensure different nodes.
    return this.get('id') === analysisModel.get('id');
  }
}, {
    STATUS: STATUS
  });

module.exports = AnalysisModel;
<commit_msg>Whitespaces<commit_after>var _ = require('underscore');
var Model = require('../core/model');

var STATUS = {
  PENDING: 'pending',
  WAITING: 'waiting',
  RUNNING: 'running',
  FAILED: 'failed',
  READY: 'ready'
};

var AnalysisModel = Model.extend({

  initialize: function (attrs, opts) {
    opts = opts || {};
    if (!opts.camshaftReference) {
      throw new Error('chamshaftReference is required');
    }

    if (!opts.vis) {
      throw new Error('vis is required');
    }

    this._camshaftReference = opts.camshaftReference;
    this._vis = opts.vis;
    this._initBinds();
  },

  url: function () {
    var url = this.get('url');
    if (url) {
      if (this.get('apiKey')) {
        url += '?api_key=' + this.get('apiKey');
      } else if (this.get('authToken')) {
        var authToken = this.get('authToken');
        if (authToken instanceof Array) {
          var tokens = _.map(authToken, function (token) {
            return 'auth_token[]=' + token;
          });
          url += '?' + tokens.join('&');
        } else {
          url += '?auth_token=' + authToken;
        }
      }
      return url;
    }
  },

  setOk: function () {
    this.unset('error');
  },

  setError: function (error) {
    this.set({
      error: error,
      status: STATUS.FAILED
    });
  },

  _initBinds: function () {
    this.bind('change:type', function () {
      this.unbind(null, null, this);
      this._initBinds();
      this._reloadVis();
    }, this);

    _.each(this.getParamNames(), function (paramName) {
      this.bind('change:' + paramName, this._reloadVis, this);
    }, this);
  },

  _reloadVis: function (opts) {
    opts = opts || {};
    opts.error = this._onMapReloadError.bind(this);
    this._vis.reload(opts);
  },

  _onMapReloadError: function () {
    this.set('status', STATUS.FAILED);
  },

  remove: function () {
    this.trigger('destroy', this);
    this.stopListening();
  },

  findAnalysisById: function (analysisId) {
    if (this.get('id') === analysisId) {
      return this;
    }
    var sources = _.chain(this._getSourceNames())
      .map(function (sourceName) {
        var source = this.get(sourceName);
        if (source) {
          return source.findAnalysisById(analysisId);
        }
      }, this)
      .compact()
      .value();

    return sources[0];
  },

  _getSourceNames: function () {
    return this._camshaftReference.getSourceNamesForAnalysisType(this.get('type'));
  },

  isDone: function () {
    return this._anyStatus(STATUS.READY, STATUS.FAILED);
  },

  isFailed: function () {
    return this._anyStatus(STATUS.FAILED);
  },

  isLoading: function () {
    return this._anyStatus(STATUS.PENDING, STATUS.WAITING, STATUS.RUNNING);
  },

  _anyStatus: function () {
    var list = Array.prototype.slice.call(arguments, 0);
    return list.indexOf(this.get('status')) !== -1;
  },

  toJSON: function () {
    var json = _.pick(this.attributes, 'id', 'type');
    json.params = _.pick(this.attributes, this.getParamNames());
    var sourceNames = this._getSourceNames();
    _.each(sourceNames, function (sourceName) {
      var source = {};
      var sourceInfo = this.get(sourceName);
      if (sourceInfo) {
        source[sourceName] = sourceInfo.toJSON();
        _.extend(json.params, source);
      }
    }, this);

    return json;
  },

  getParamNames: function () {
    return this._camshaftReference.getParamNamesForAnalysisType(this.get('type'));
  },

  /**
   * Compare two analysisModels.
   */
  equals: function (analysisModel) {
    if (!(analysisModel instanceof AnalysisModel)) {
      return false;
    }
    // Since all analysis are created using the analysisFactory different ids ensure different nodes.
    return this.get('id') === analysisModel.get('id');
  }
}, {
  STATUS: STATUS
});

module.exports = AnalysisModel;
<|endoftext|>


<commit_before>/*global process, require, BuiltinAssets, requirejs, global */
define(["FS","Platform","root"], function (FS,Platform,root) {
	var P=FS.PathUtil;
	var loc=document.location.href;
	const WebSite=root.WebSite||{};
	root.WebSite=WebSite;
	WebSite.runType=WebSite.runType||root.WebSite_runType;
	var prot=location.protocol;
	var k;

	var VER=1631679046610;
	if (!prot.match(/^http/)) prot="https:";
	switch(WebSite.runType) {
	case "IDE":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		WebSite.builtinAssetNames={
			"images/Ball.png":{name:"$pat_ball", url: "images/Ball.png"},
			"images/base.png":{name:"$pat_base", url: "images/base.png", pwidth:32, pheight:32},
			"images/Sample.png":{name:"$pat_sample", url: "images/Sample.png"},
			"images/inputPad.png":{name:"$pat_inputPad", url: "images/inputPad.png"},
			"images/neko.png":{name:"$pat_neko", url: "images/neko.png", pwidth:32, pheight:32},
			"images/mapchip.png":{name:"$pat_mapchip", url: "images/mapchip.png", pwidth:32, pheight:32}
		};
		if (!WebSite.pluginTop) {
			WebSite.pluginTop=WebSite.top+"/js/plugins";
		}
		WebSite.sampleImg=WebSite.top+"/images";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.mp4Disabled=WebSite.isNW;
		WebSite.tonyuHome="/Tonyu/";
		WebSite.PathSep="/";
		if (WebSite.isNW) {
			WebSite.PathSep=require("path").sep;
			WebSite.cwd=P.directorify(process.cwd().replace(/\\/g,"/"));
			//WebSite.exeDir=WebSite.execDir=P.up(P.fixSep(process.execPath)); not suitable when mac
			if (process.env.TONYU_HOME) {
				WebSite.tonyuHome=P.directorify(process.env.TONYU_HOME);
			} else {
				WebSite.tonyuHome=P.rel(WebSite.cwd,"fs/Tonyu/");
			}
			WebSite.logdir=process.env.TONYU_LOGDIR;//"C:/var/log/Tonyu/";
			WebSite.wwwDir=P.rel(WebSite.cwd,"www/");
			WebSite.platform=process.platform;
			WebSite.ffmpeg=P.rel(WebSite.cwd,(WebSite.platform=="win32"?
					"ffmpeg/bin/ffmpeg.exe":"ffmpeg/bin/ffmpeg"));
			WebSite.pkgInfo=require(P.rel(WebSite.cwd, "package.json"));
			if (process.env.TONYU_PROJECTS) {
				WebSite.projects=process.env.TONYU_PROJECTS.replace(/\\/g,"/").split(require('path').delimiter);
			} else if ( WebSite.pkgInfo && WebSite.pkgInfo.config && WebSite.pkgInfo.config.prjDirs ){
				WebSite.projects=WebSite.pkgInfo.config.prjDirs.map(function (d) {
					d=P.directorify(d);
					if (P.isAbsolute(d)) return d;
					return P.rel(WebSite.cwd,d);
				});
			} else {
				WebSite.projects=[P.rel(WebSite.cwd,"Projects/"),
					P.rel(WebSite.tonyuHome,"Projects/")];
			}
			WebSite.kernelDir=P.rel(WebSite.wwwDir,"Kernel/");
		} else {
			if (loc.match(/edit\.tonyu\.jp\/n\//)) {
				WebSite.wwwDir=prot+"//"+location.host+"/n/";
			} else {
				// Why?
				WebSite.wwwDir=prot+"//"+location.host+"/";
			}
			WebSite.projects=[P.rel(WebSite.tonyuHome,"Projects/")];
		}
		//WebSite.kernelDir=WebSite.top+"/Kernel/";
		// kernelDir must be absolute
		WebSite.kernelDir=P.rel(WebSite.wwwDir,"Kernel/");
		// compiledKernel is URL , not file path.
		// It is correct as long as the html pages in www/ (not html/build|dev )
		WebSite.compiledKernel="Kernel/js/concat.js";   //P.rel(WebSite.kernelDir,"js/concat.js");
		WebSite.compiledTools={
			mapEditor2: "Tools/MapEditor2/js/concat.js",
		};
		setNS2DepSpec();
		if (loc.match(/localhost\/tonyu2/)) {
			WebSite.wwwDir=prot+"//"+location.host+"/tonyu2/";
			WebSite.kernelDir=WebSite.wwwDir+"Kernel/";
			WebSite.compiledKernel=WebSite.kernelDir+"js/concat.js";
			WebSite.uploadTmpUrl=prot+"//localhost/tsite/tonyu/e/cgi-bin/uploadTmp.cgi";
			WebSite.newVersionUrl=prot+"//localhost/tsite/tonyu/project/newVersion.cgi";
			WebSite.quickUploadURL=prot+"//localhost/tsite/tonyu/project/quickDone.cgi";
			WebSite.scriptServer="https://localhost/tonyu2/";
		} else {
			WebSite.uploadTmpUrl=prot+"//edit.tonyu.jp/cgi-bin/uploadTmp.cgi";
			WebSite.newVersionUrl=prot+"//www.tonyu.jp/project/newVersion.cgi";
			WebSite.quickUploadURL=prot+"//www.tonyu.jp/project/quickDone.cgi";
			WebSite.scriptServer="https://edit.tonyu.jp/";
		}
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		WebSite.version=2;
		WebSite.projectEditorURL="project2.html";
		setDefaultResource(WebSite);
		return WebSite;
	case "singleHTML":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		if (typeof BuiltinAssets==="object") {
			for (k in BuiltinAssets) {
				WebSite.urlAliases[k]=BuiltinAssets[k];
			}
		}

		WebSite.tonyuHome="/Tonyu/";
		WebSite.projects=[P.rel(WebSite.tonyuHome,"Projects/")];
		if (loc.match(/localhost\/tonyu2/)) {
			WebSite.scriptServer="http://localhost/tonyu2/";
		} else {
			WebSite.scriptServer="https://edit.tonyu.jp/";
		}
		WebSite.pluginTop=WebSite.scriptServer+"js/plugins";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.PathSep="/";
		WebSite.compiledKernel=WebSite.scriptServer+"Kernel/js/concat.js";
		WebSite.compiledTools={
			mapEditor2: `${WebSite.scriptServer}Tools/MapEditor2/js/concat.js`,
		};
		setNS2DepSpec();
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		setDefaultResource(WebSite);
		return WebSite;
	case "multiHTML":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		WebSite.tonyuHome="/Tonyu/";
		WebSite.pluginTop=WebSite.top+"/js/plugins";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.PathSep="/";
		WebSite.mp4Disabled=WebSite.isNW;
		if (WebSite.isNW) {
			WebSite.PathSep=getPathSep();
			WebSite.cwd=P.directorify(process.cwd().replace(/\\/g,"/"));
			WebSite.platform=process.platform;
		}
		// this sets at runScript2.js
		//WebSite.compiledKernel=WebSite.top+"/js/kernel.js";
		//-------------
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		return WebSite;
	case "manual":// for BitArrow
		return WebSite;
	default:
		throw new Error("WebSite.runType is not set");
	}
	function setNS2DepSpec() {
		WebSite.ns2depspec=[
	        {namespace:"kernel", url: WebSite.compiledKernel},
	        {namespace:"mapEditor2", url: WebSite.compiledTools.mapEditor2},
	    ];
	}
	function setDefaultResource(WebSite) {
		WebSite.defaultResource={
	       images:[
	          {name:"$pat_base", url: "images/base.png", pwidth:32, pheight:32},
	          {name:"$pat_sample", url: "images/Sample.png"},
	          {name:"$pat_neko", url: "images/neko.png", pwidth:32, pheight:32},
	          {name:"$pat_mapchip", url: "images/mapchip.png", pwidth:32, pheight:32}
	       ],
	       sounds:[]
	    };
	}
	//WebSite.blobPath=WebSite.serverTop+"/serveBlob";        //TODO: urlchange!
	/*WebSite.url={
		getDirInfo:WebSite.serverTop+"/getDirInfo",
		getFiles:WebSite.serverTop+"/File2LSSync",
		putFiles:WebSite.serverTop+"/LS2FileSync"
	};*/
	function getPathSep() {
		const requireTries=[
			()=>require("path"),
			()=>requirejs.nodeRequire("path"),
			()=>global.require("path")
		];
		for (let fsf of requireTries) {
			try {
				const path=fsf();
				if (typeof path.sep==="string") return path.sep;
			} catch(e){
			}
		}
		return "/";
	}
});
<commit_msg>build<commit_after>/*global process, require, BuiltinAssets, requirejs, global */
define(["FS","Platform","root"], function (FS,Platform,root) {
	var P=FS.PathUtil;
	var loc=document.location.href;
	const WebSite=root.WebSite||{};
	root.WebSite=WebSite;
	WebSite.runType=WebSite.runType||root.WebSite_runType;
	var prot=location.protocol;
	var k;

	var VER=1631944109376;
	if (!prot.match(/^http/)) prot="https:";
	switch(WebSite.runType) {
	case "IDE":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		WebSite.builtinAssetNames={
			"images/Ball.png":{name:"$pat_ball", url: "images/Ball.png"},
			"images/base.png":{name:"$pat_base", url: "images/base.png", pwidth:32, pheight:32},
			"images/Sample.png":{name:"$pat_sample", url: "images/Sample.png"},
			"images/inputPad.png":{name:"$pat_inputPad", url: "images/inputPad.png"},
			"images/neko.png":{name:"$pat_neko", url: "images/neko.png", pwidth:32, pheight:32},
			"images/mapchip.png":{name:"$pat_mapchip", url: "images/mapchip.png", pwidth:32, pheight:32}
		};
		if (!WebSite.pluginTop) {
			WebSite.pluginTop=WebSite.top+"/js/plugins";
		}
		WebSite.sampleImg=WebSite.top+"/images";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.mp4Disabled=WebSite.isNW;
		WebSite.tonyuHome="/Tonyu/";
		WebSite.PathSep="/";
		if (WebSite.isNW) {
			WebSite.PathSep=require("path").sep;
			WebSite.cwd=P.directorify(process.cwd().replace(/\\/g,"/"));
			//WebSite.exeDir=WebSite.execDir=P.up(P.fixSep(process.execPath)); not suitable when mac
			if (process.env.TONYU_HOME) {
				WebSite.tonyuHome=P.directorify(process.env.TONYU_HOME);
			} else {
				WebSite.tonyuHome=P.rel(WebSite.cwd,"fs/Tonyu/");
			}
			WebSite.logdir=process.env.TONYU_LOGDIR;//"C:/var/log/Tonyu/";
			WebSite.wwwDir=P.rel(WebSite.cwd,"www/");
			WebSite.platform=process.platform;
			WebSite.ffmpeg=P.rel(WebSite.cwd,(WebSite.platform=="win32"?
					"ffmpeg/bin/ffmpeg.exe":"ffmpeg/bin/ffmpeg"));
			WebSite.pkgInfo=require(P.rel(WebSite.cwd, "package.json"));
			if (process.env.TONYU_PROJECTS) {
				WebSite.projects=process.env.TONYU_PROJECTS.replace(/\\/g,"/").split(require('path').delimiter);
			} else if ( WebSite.pkgInfo && WebSite.pkgInfo.config && WebSite.pkgInfo.config.prjDirs ){
				WebSite.projects=WebSite.pkgInfo.config.prjDirs.map(function (d) {
					d=P.directorify(d);
					if (P.isAbsolute(d)) return d;
					return P.rel(WebSite.cwd,d);
				});
			} else {
				WebSite.projects=[P.rel(WebSite.cwd,"Projects/"),
					P.rel(WebSite.tonyuHome,"Projects/")];
			}
			WebSite.kernelDir=P.rel(WebSite.wwwDir,"Kernel/");
		} else {
			if (loc.match(/edit\.tonyu\.jp\/n\//)) {
				WebSite.wwwDir=prot+"//"+location.host+"/n/";
			} else {
				// Why?
				WebSite.wwwDir=prot+"//"+location.host+"/";
			}
			WebSite.projects=[P.rel(WebSite.tonyuHome,"Projects/")];
		}
		//WebSite.kernelDir=WebSite.top+"/Kernel/";
		// kernelDir must be absolute
		WebSite.kernelDir=P.rel(WebSite.wwwDir,"Kernel/");
		// compiledKernel is URL , not file path.
		// It is correct as long as the html pages in www/ (not html/build|dev )
		WebSite.compiledKernel="Kernel/js/concat.js";   //P.rel(WebSite.kernelDir,"js/concat.js");
		WebSite.compiledTools={
			mapEditor2: "Tools/MapEditor2/js/concat.js",
		};
		setNS2DepSpec();
		if (loc.match(/localhost\/tonyu2/)) {
			WebSite.wwwDir=prot+"//"+location.host+"/tonyu2/";
			WebSite.kernelDir=WebSite.wwwDir+"Kernel/";
			WebSite.compiledKernel=WebSite.kernelDir+"js/concat.js";
			WebSite.uploadTmpUrl=prot+"//localhost/tsite/tonyu/e/cgi-bin/uploadTmp.cgi";
			WebSite.newVersionUrl=prot+"//localhost/tsite/tonyu/project/newVersion.cgi";
			WebSite.quickUploadURL=prot+"//localhost/tsite/tonyu/project/quickDone.cgi";
			WebSite.scriptServer="https://localhost/tonyu2/";
		} else {
			WebSite.uploadTmpUrl=prot+"//edit.tonyu.jp/cgi-bin/uploadTmp.cgi";
			WebSite.newVersionUrl=prot+"//www.tonyu.jp/project/newVersion.cgi";
			WebSite.quickUploadURL=prot+"//www.tonyu.jp/project/quickDone.cgi";
			WebSite.scriptServer="https://edit.tonyu.jp/";
		}
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		WebSite.version=2;
		WebSite.projectEditorURL="project2.html";
		setDefaultResource(WebSite);
		return WebSite;
	case "singleHTML":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		if (typeof BuiltinAssets==="object") {
			for (k in BuiltinAssets) {
				WebSite.urlAliases[k]=BuiltinAssets[k];
			}
		}

		WebSite.tonyuHome="/Tonyu/";
		WebSite.projects=[P.rel(WebSite.tonyuHome,"Projects/")];
		if (loc.match(/localhost\/tonyu2/)) {
			WebSite.scriptServer="http://localhost/tonyu2/";
		} else {
			WebSite.scriptServer="https://edit.tonyu.jp/";
		}
		WebSite.pluginTop=WebSite.scriptServer+"js/plugins";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.PathSep="/";
		WebSite.compiledKernel=WebSite.scriptServer+"Kernel/js/concat.js";
		WebSite.compiledTools={
			mapEditor2: `${WebSite.scriptServer}Tools/MapEditor2/js/concat.js`,
		};
		setNS2DepSpec();
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		setDefaultResource(WebSite);
		return WebSite;
	case "multiHTML":
		Object.assign(WebSite,{
			urlAliases: WebSite.urlAliases||{}, top: ".",
			tablet:Platform.tablet,
			mobile:Platform.mobile
		});
		WebSite.tonyuHome="/Tonyu/";
		WebSite.pluginTop=WebSite.top+"/js/plugins";
		WebSite.isNW=(typeof process=="object" && (process.__node_webkit||process.__nwjs));
		WebSite.PathSep="/";
		WebSite.mp4Disabled=WebSite.isNW;
		if (WebSite.isNW) {
			WebSite.PathSep=getPathSep();
			WebSite.cwd=P.directorify(process.cwd().replace(/\\/g,"/"));
			WebSite.platform=process.platform;
		}
		// this sets at runScript2.js
		//WebSite.compiledKernel=WebSite.top+"/js/kernel.js";
		//-------------
		FS.setEnvProvider(new FS.Env(WebSite));
		WebSite.sysVersion=VER;
		return WebSite;
	case "manual":// for BitArrow
		return WebSite;
	default:
		throw new Error("WebSite.runType is not set");
	}
	function setNS2DepSpec() {
		WebSite.ns2depspec=[
	        {namespace:"kernel", url: WebSite.compiledKernel},
	        {namespace:"mapEditor2", url: WebSite.compiledTools.mapEditor2},
	    ];
	}
	function setDefaultResource(WebSite) {
		WebSite.defaultResource={
	       images:[
	          {name:"$pat_base", url: "images/base.png", pwidth:32, pheight:32},
	          {name:"$pat_sample", url: "images/Sample.png"},
	          {name:"$pat_neko", url: "images/neko.png", pwidth:32, pheight:32},
	          {name:"$pat_mapchip", url: "images/mapchip.png", pwidth:32, pheight:32}
	       ],
	       sounds:[]
	    };
	}
	//WebSite.blobPath=WebSite.serverTop+"/serveBlob";        //TODO: urlchange!
	/*WebSite.url={
		getDirInfo:WebSite.serverTop+"/getDirInfo",
		getFiles:WebSite.serverTop+"/File2LSSync",
		putFiles:WebSite.serverTop+"/LS2FileSync"
	};*/
	function getPathSep() {
		const requireTries=[
			()=>require("path"),
			()=>requirejs.nodeRequire("path"),
			()=>global.require("path")
		];
		for (let fsf of requireTries) {
			try {
				const path=fsf();
				if (typeof path.sep==="string") return path.sep;
			} catch(e){
			}
		}
		return "/";
	}
});
<|endoftext|>


<commit_before>// We store messages as code instead of as JSON because JSON sucks.
// - We can use comments, they are useful for translations.
// - Multiline strings ftw.
// - Translations are eslinted.
export function messagesToCode(messages) {
  messages.sort((a, b) => a.id.localeCompare(b.id));
  return `/* eslint-disable max-len, quote-props, quotes */
export default ${JSON.stringify(messages, null, 2)};
`;
}

export const diff = (a, b) => a.filter(item => b.indexOf(item) === -1);
<commit_msg>Generate messages with trailing commas<commit_after>// We store messages as code instead of as JSON because JSON sucks.
// - We can use comments, they are useful for translations.
// - Multiline strings ftw.
// - Translations are eslinted.
export function messagesToCode(messages) {
  messages.sort((a, b) => a.id.localeCompare(b.id));
  const messagesString = JSON
    .stringify(messages, null, 2)
    // Add trailing commas.
    .replace(/\n {2}\}/g, ',\n  }')
    .replace(/\}\n\]/g, '},\n]');

  return `/* eslint-disable max-len, quote-props, quotes */
export default ${messagesString};
`;
}

export const diff = (a, b) => a.filter(item => b.indexOf(item) === -1);
<|endoftext|>


<commit_before>'use strict';

import path from 'path';
import glob from 'glob';
import browserify from 'browserify';
import watchify from 'watchify';
import envify from 'envify';
import babelify from 'babelify';
import _ from 'lodash';
import vsource from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import gulpif from 'gulp-if';
import notifier from 'node-notifier';

import { jsWatch, notification_icon_location} from '../config/shared-vars';

export default function(gulp, plugins, args, config, taskTarget, browserSync) {
  let dirs = config.directories;
  let entries = config.entries;

  let browserifyTask = (done, files) => {
    files.map((entry) => {
      let dest = path.resolve(taskTarget, dirs.assets);

      // Options
      let customOpts = {
        entries: [entry],
        debug: true,
        paths: [
          './src/_modules',
          './src/_scripts'
        ],
        transform: [
          babelify, // Enable ES6 features
          envify // Sets NODE_ENV for better optimization of npm packages
        ]
      };

      let bundler = browserify(customOpts);

      if (jsWatch.isEnabled) {
        // Setup Watchify for faster builds
        let opts = _.assign({}, watchify.args, customOpts);
        bundler = watchify(browserify(opts));

      }

      const jsErrorNotification = {title:'JS Error', message: 'Error running JS browserify'};

      let rebundle = function() {
        let startTime = new Date().getTime();
        bundler.bundle()
          .on('error', function(err) {
            notifier.notify({title: 'JS Error', message: err.loc ? `${path.basename(error.filename)} line ${error.loc.line}` : 'JS failed to compile', icon: notification_icon_location+'gulp-error.png'});
            plugins.util.log(
              plugins.util.colors.red.bold('Browserify compile error:'),
              '\n',
              plugins.util.colors.yellow(err.stack),
              '\n'
            );
            this.emit('end');
          })
          .pipe(vsource(entry))
          .pipe(buffer())
          .pipe(plugins.sourcemaps.init({loadMaps: true}))
            .pipe(gulpif(args.production, plugins.uglify()))
          .pipe(plugins.rename(function(filepath) {
            // Remove 'source' directory as well as prefixed folder underscores
            // Ex: 'src/_scripts' --> '/scripts'
            filepath.dirname = filepath.dirname.replace(dirs.source, '').replace('_', '');
          }))
          .pipe(plugins.sourcemaps.write('./'))
          .pipe(gulp.dest(dest))
          // Show which file was bundled and how long it took
          .on('end', function() {
            let time = (new Date().getTime() - startTime) / 1000;
            console.log(
              plugins.util.colors.cyan(entry)
              + ' was browserified: '
              + plugins.util.colors.magenta(time + 's'));
            browserSync.reload('*.js');

            done();
          });
      };

      if (!args.production) {
        bundler.on('update', rebundle); // on any dep update, runs the bundler
        bundler.on('log', plugins.util.log); // output build logs to terminal
      }
      return rebundle();
    });
  };

  // Browserify Task
  gulp.task('browserify', (done) => {
    return glob('./' + path.join(dirs.source, dirs.scripts, entries.js), function(err, files) {
      if (err) {
        done(err);
      }

      return browserifyTask(done, files);
    });
  });
}
<commit_msg>Fixing browserify error message logging<commit_after>'use strict';

import path from 'path';
import glob from 'glob';
import browserify from 'browserify';
import watchify from 'watchify';
import envify from 'envify';
import babelify from 'babelify';
import _ from 'lodash';
import vsource from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import gulpif from 'gulp-if';
import notifier from 'node-notifier';

import { jsWatch, notification_icon_location} from '../config/shared-vars';

export default function(gulp, plugins, args, config, taskTarget, browserSync) {
  let dirs = config.directories;
  let entries = config.entries;

  let browserifyTask = (done, files) => {
    files.map((entry) => {
      let dest = path.resolve(taskTarget, dirs.assets);

      // Options
      let customOpts = {
        entries: [entry],
        debug: true,
        paths: [
          './src/_modules',
          './src/_scripts'
        ],
        transform: [
          babelify, // Enable ES6 features
          envify // Sets NODE_ENV for better optimization of npm packages
        ]
      };

      let bundler = browserify(customOpts);

      if (jsWatch.isEnabled) {
        // Setup Watchify for faster builds
        let opts = _.assign({}, watchify.args, customOpts);
        bundler = watchify(browserify(opts));

      }

      const jsErrorNotification = {title:'JS Error', message: 'Error running JS browserify'};

      let rebundle = function() {
        let startTime = new Date().getTime();
        bundler.bundle()
          .on('error', function(err) {
            notifier.notify({title: 'JS Error', message: err.loc ? `${path.basename(err.filename)} line ${err.loc.line}` : 'JS failed to compile', icon: notification_icon_location+'gulp-error.png'});
            plugins.util.log(
              plugins.util.colors.red.bold('Browserify compile error:'),
              '\n',
              plugins.util.colors.yellow(err.stack),
              '\n'
            );
            this.emit('end');
          })
          .pipe(vsource(entry))
          .pipe(buffer())
          .pipe(plugins.sourcemaps.init({loadMaps: true}))
            .pipe(gulpif(args.production, plugins.uglify()))
          .pipe(plugins.rename(function(filepath) {
            // Remove 'source' directory as well as prefixed folder underscores
            // Ex: 'src/_scripts' --> '/scripts'
            filepath.dirname = filepath.dirname.replace(dirs.source, '').replace('_', '');
          }))
          .pipe(plugins.sourcemaps.write('./'))
          .pipe(gulp.dest(dest))
          // Show which file was bundled and how long it took
          .on('end', function() {
            let time = (new Date().getTime() - startTime) / 1000;
            console.log(
              plugins.util.colors.cyan(entry)
              + ' was browserified: '
              + plugins.util.colors.magenta(time + 's'));
            browserSync.reload('*.js');

            done();
          });
      };

      if (!args.production) {
        bundler.on('update', rebundle); // on any dep update, runs the bundler
        bundler.on('log', plugins.util.log); // output build logs to terminal
      }
      return rebundle();
    });
  };

  // Browserify Task
  gulp.task('browserify', (done) => {
    return glob('./' + path.join(dirs.source, dirs.scripts, entries.js), function(err, files) {
      if (err) {
        done(err);
      }

      return browserifyTask(done, files);
    });
  });
}
<|endoftext|>


<commit_before>/**
 * Created by daniel on 9/07/15.
 */
$(document).ready(function () {
    $(window).load(function () {
        addBudget();
        datepickersBudgets();
        toggleSubcategory();
        addBudgetVariable();

    });
});

function addBudget() {
    var wrapper = $(".input_fields_wrap"); //Fields wrapper
    var add_button = $(".add_field_button"); //Add button ID

    var insert = "";
    var x = 0; //initlal text box count
    $(add_button).click(function (e) { //on add input button click
        e.preventDefault();

        x++; //text box increment
        insert = '

' +
            '<select class="form-control" id="form-' + x + '-category" name="form-' + x + '-category">';
        $("#form-0-category option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });
        insert = insert + '</select>' +
            '
' +
            '
' +
            '<input type="number" id="form-' + x + '-amount" name="form-' + x + '-amount" class="form-control amount-offset" placeholder="Amount">' +
            '
' +
            '
' +
            '<select class="form-control currency-offset" name="form-' + x + '-currency" id="form-' + x + '-currency">';
        $("#form-0-currency option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });

        insert = insert + '</select>' +
            '
' +
            '
' +
            '' +
            '' +
            '
' +
            '
';

        $(wrapper).append(insert);

    });

    $(wrapper).on("click", ".remove_field", function (e) { //user click on remove text
        divName = '#extra' + $(this).attr('name');
        e.preventDefault();
        console.log($('#form-'+$(this).attr('name')+'-category').val());
        console.log($('#form-'+$(this).attr('name')+'-amount').val());
        console.log($('#form-'+$(this).attr('name')+'-currency').val());
        $(divName).remove();

    })
}

function addBudgetVariable() {
    var wrapper = $(".input_fields_wrap"); //Fields wrapper
    var add_button = $(".add_field_button_variable"); //Add button ID

    var insert = "";
    var x = 1; //initlal text box count
    $(add_button).click(function (e) { //on add input button click
        e.preventDefault();

        x++; //text box increment
        insert = '

' +
            '<select class="form-control" id="form-' + x + '-category" name="form-' + x + '-category">';
        $("#form-0-category option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });
        insert = insert + '</select>' +
            '
' +
            '
' +
            '<input type="number" id="form-' + x + '-amount" name="form-' + x + '-amount" class="form-control amount-offset" placeholder="Amount">' +
            '
' +
            '
' +
            '<select class="form-control currency-offset" name="form-' + x + '-currency" id="form-' + x + '-currency">';
        $("#form-0-currency option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });

        insert = insert + '</select>' +
            '
' +
            '
' +
            '
' +
            '<input type="checkbox">' +
            '
' +
            '
' +
            '
' +
            '' +
            '' +
            '
' +
            '
';

        $(wrapper).append(insert);

    });

    $(wrapper).on("click", ".remove_field_variable", function (e) { //user click on remove text
        divName = '#extra' + $(this).attr('name');
        e.preventDefault();
        $(divName).remove();
    })
}

function datepickersBudgets() {
    $('.datepick').datetimepicker({
        viewMode: 'years',
        format: 'YYYY-MM-DD',
        pickTime: false,
        defaultDate: new Date()
    })
        .change(dateChangedBudget)
        .on('changeDate', dateChangedBudget);
}

function toggleSubcategory() {
    var wrapper = $(".budgets_wrap"); //Fields wrapper

    $(wrapper).on("click", ".toggle_sub", function (e) { //user click on remove text
        divName = '#'+$(this).attr('name')+'sub';
        $(divName).toggle(500);
    })
}

function dateChangedBudget(ev) {
    var fromDate = $('#newBudgetFromDate').val();
    var toDate = $('#newBudgetToDate').val();

    console.log(fromDate+' '+toDate);

    fromDate = fromDate.split("-");
    toDate = toDate.split("-");

    if(fromDate[0] > toDate[0]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);

    }
    else if (fromDate[0] == toDate[0] && fromDate[1] > toDate[1]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);
    }
    else if (fromDate[0] == toDate[0] && fromDate[1] == toDate[1] && fromDate[2] > toDate[2]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);
    }
    else{
        $('#budgetSave').prop('disabled', false);
        $("#dateError").hide(500);
    }

}<commit_msg>Removes console.log when removing lines<commit_after>/**
 * Created by daniel on 9/07/15.
 */
$(document).ready(function () {
    $(window).load(function () {
        addBudget();
        datepickersBudgets();
        toggleSubcategory();
        addBudgetVariable();

    });
});

function addBudget() {
    var wrapper = $(".input_fields_wrap"); //Fields wrapper
    var add_button = $(".add_field_button"); //Add button ID

    var insert = "";
    var x = 0; //initlal text box count
    $(add_button).click(function (e) { //on add input button click
        e.preventDefault();

        x++; //text box increment
        insert = '

' +
            '<select class="form-control" id="form-' + x + '-category" name="form-' + x + '-category">';
        $("#form-0-category option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });
        insert = insert + '</select>' +
            '
' +
            '
' +
            '<input type="number" id="form-' + x + '-amount" name="form-' + x + '-amount" class="form-control amount-offset" placeholder="Amount">' +
            '
' +
            '
' +
            '<select class="form-control currency-offset" name="form-' + x + '-currency" id="form-' + x + '-currency">';
        $("#form-0-currency option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });

        insert = insert + '</select>' +
            '
' +
            '
' +
            '' +
            '' +
            '
' +
            '
';

        $(wrapper).append(insert);

    });

    $(wrapper).on("click", ".remove_field", function (e) { //user click on remove text
        divName = '#extra' + $(this).attr('name');
        e.preventDefault();
        $(divName).remove();

    })
}

function addBudgetVariable() {
    var wrapper = $(".input_fields_wrap"); //Fields wrapper
    var add_button = $(".add_field_button_variable"); //Add button ID

    var insert = "";
    var x = 1; //initlal text box count
    $(add_button).click(function (e) { //on add input button click
        e.preventDefault();

        x++; //text box increment
        insert = '

' +
            '<select class="form-control" id="form-' + x + '-category" name="form-' + x + '-category">';
        $("#form-0-category option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });
        insert = insert + '</select>' +
            '
' +
            '
' +
            '<input type="number" id="form-' + x + '-amount" name="form-' + x + '-amount" class="form-control amount-offset" placeholder="Amount">' +
            '
' +
            '
' +
            '<select class="form-control currency-offset" name="form-' + x + '-currency" id="form-' + x + '-currency">';
        $("#form-0-currency option").each(function () {
            insert = insert + '<option>' + $(this).val() + '</option>';
        });

        insert = insert + '</select>' +
            '
' +
            '
' +
            '
' +
            '<input type="checkbox">' +
            '
' +
            '
' +
            '
' +
            '' +
            '' +
            '
' +
            '
';

        $(wrapper).append(insert);

    });

    $(wrapper).on("click", ".remove_field_variable", function (e) { //user click on remove text
        divName = '#extra' + $(this).attr('name');
        e.preventDefault();
        $(divName).remove();
    })
}

function datepickersBudgets() {
    $('.datepick').datetimepicker({
        viewMode: 'years',
        format: 'YYYY-MM-DD',
        pickTime: false,
        defaultDate: new Date()
    })
        .change(dateChangedBudget)
        .on('changeDate', dateChangedBudget);
}

function toggleSubcategory() {
    var wrapper = $(".budgets_wrap"); //Fields wrapper

    $(wrapper).on("click", ".toggle_sub", function (e) { //user click on remove text
        divName = '#'+$(this).attr('name')+'sub';
        $(divName).toggle(500);
    })
}

function dateChangedBudget(ev) {
    var fromDate = $('#newBudgetFromDate').val();
    var toDate = $('#newBudgetToDate').val();

    console.log(fromDate+' '+toDate);

    fromDate = fromDate.split("-");
    toDate = toDate.split("-");

    if(fromDate[0] > toDate[0]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);

    }
    else if (fromDate[0] == toDate[0] && fromDate[1] > toDate[1]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);
    }
    else if (fromDate[0] == toDate[0] && fromDate[1] == toDate[1] && fromDate[2] > toDate[2]){
        $('#budgetSave').prop('disabled', true);
        $("#dateError").show(500);
    }
    else{
        $('#budgetSave').prop('disabled', false);
        $("#dateError").hide(500);
    }

}<|endoftext|>