<commit_before>var parentController = {

       update: function(id,data,success){
            new Parent(data).update(id,"POST",success);
       },
       prefix:"parent",
       formulary : $("#parent-form"),
       rulesFormulary:{
           rules:{
                email:{
                    required:true,
                    email:true
                },
                username:{
                  required:true,
                  maxlength:40,
                  remote:{
                    "url":"/remote-username",
                    "type":"POST",
                    "username":function(){
                      return $("input[name='username']").val();
                    }
                  }
                },
                nombre:{
                    required:true
                },
                apellidos:{
                    required:true
                },
                sexo:{
                    required:true
                },
                password:{
                    required:true,
                    minlength:8
                },
                cpassword:{
                  required: true,
                  minlength:8,
                  equalTo:function(){
                    return $("input[name='password']");
                  }
                },
                telefono:{
                    required:true,
                    digits:true,
                    minlength:7,
                    maxlength:13
                }
           },messages:{
              cpassword:{equalTo:"Las contraseñas son diferentes"},
              username:{remote:"Nombre de usuario no disponible"}
           }
       },
       data:function(){
            return {
                'email':$("#email").val(),
                'nombre':$("#nombre").val(),
                'apellidos':$("#apellidos").val(),
                'sexo':$("#sexo").val(),
                'password':$("#password").val(),
                'telefono':$("#telefono").val(),
                'username':$("#username").val(),
                'cpassword':$("#cpassword").val()
            }
       },
       id : null,
       itemSon:function(id,name,nivel_id,infoActivities,topicLow){
           return ""+
              "
"+
                 ""+
                 "
"+name+"
"
              "
"+
           "";
       },
       createChartActivities:function(id,nivelId,data){
            if(data.length != 0){
                var iSstorage = localStorage.getItem('intelligencesSon');
                var intelligences = (iSstorage != null) ? null : JSON.parse(iSstorage);
                $.each(intelligences,function(i,intelligence){
                    if(i == 0){
                        $("#materias").append("<fieldset class='form-group'><input value="+intelligence.id+" name='materia' type='radio'  checked='checked'>"+intelligence.nombre+"</fieldset>");
                    }
                    else{
                        $("#materias").append("<fieldset class='form-group'><input val='"+intelligence.id+"' name='materia' type='radio'>"+intelligence.nombre+"</fieldset>");
                    }
               });
                var ctx = document.getElementById("myChart").getContext("2d");
                var materiaID = $("input[name='materia']:checked").val();
                var materia,numRand,chartActivity;
                var dataValues=[];
                var data = {
                    labels: [],
                    datasets: []
                };
                $.each(data,function(i,activity){
                    numRand = Math.random()*(Curiosity.colors.length-1);
                    if(activity.idMateria == materiaID){
                        if(activity.id == id){
                            data.labels.push(activity.nombre_tema);
                            dataValues.push(activity.promedio);
                        }
                    }
                    materia = activity.Materia;
                });
            }

            if(data.length == 0){
                $("#dadNotice").show();
            }else if(data.length < 5){
                $("#materias").show();
                data.datasets.push({
                            label: materia,
                            fill: false,
                            lineTension: 0.1,
                           backgroundColor: [
                                'rgba(255, 99, 132, 0.2)',
                                'rgba(54, 162, 235, 0.2)',
                                'rgba(255, 206, 86, 0.2)',
                                'rgba(75, 192, 192, 0.2)',
                                'rgba(153, 102, 255, 0.2)',
                                'rgba(255, 159, 64, 0.2)'
                            ],
                            borderColor: [
                                'rgba(255,99,132,1)',
                                'rgba(54, 162, 235, 1)',
                                'rgba(255, 206, 86, 1)',
                                'rgba(75, 192, 192, 1)',
                                'rgba(153, 102, 255, 1)',
                                'rgba(255, 159, 64, 1)'
                            ],
                            borderCapStyle: 'butt',
                            borderDash: [],
                            borderDashOffset: 0.0,
                            borderJoinStyle: 'miter',
                            pointBorderColor: "rgba(75,192,192,1)",
                            pointBackgroundColor: "#fff",
                            pointBorderWidth: 1,
                            pointHoverRadius: 5,
                            pointHoverBackgroundColor: "rgba(75,192,192,1)",
                            pointHoverBorderColor: "rgba(220,220,220,1)",
                            pointHoverBorderWidth: 2,
                            pointRadius: 1,
                            pointHitRadius: 10,
                            data: dataValues,
                            spanGaps: false,
                });
                chartActivity = new Chart(ctx, {
                    type: 'bar',
                    data: data
                });

            }else{
                $("#materias").show();
                data.datasets.push({
                    label:materia,
                    backgroundColor: Curiosity.colorsTransparent(.4)[numRand],
                    borderColor: Curiosity.colors()[numRand],
                    pointBackgroundColor: Curiosity.colors()[numRand],
                    pointBorderColor: "#fff",
                    pointHoverBackgroundColor: "#fff",
                    pointHoverBorderColor: Curiosity.colors()[numRand],
                    data:dataValues
                });
                var options ={
                        scale: {
                            reverse: false,
                            ticks: {
                                beginAtZero: true
                            }
                        }
                }
                chartActivity = new Chart(ctx, {
                    type: 'radar',
                    data: data,
                    options: options
                });
            }
       },
       autoSelectedUser:function(){
             $(".hm-carousel").children('.carousel-item').each(function(i,item){
                if(i == 0){
                    $(this).trigger('click');
                    console.log($(this));
                }
             });
       },
       createCarousel:function(response){
           if(response.sons.length > 0){
                $.each(response.sons,function(id,son){
                    var dataActivitiesSon = parentController.createArrayDataSon(son.id,response.sonMakeActivities);
                    var dataTopicLow = parentController.createArrayDataTopicLowSon(son.id,response.temasLow);
                    $(".hm-carousel").append(parentController.itemSon(son.id,son.nombre_completo,son.nivel_id,JSON.stringify(dataActivitiesSon),JSON.stringify(dataTopicLow)));
                });
                $(".carousel").carousel();
            }
       },
       createArrayDataSon:function(id,activities){
            var dataset=[];
            if($.isArray(activities)){
                if(activities.length > 0){
                    $.each(activities,function(i,activity){
                        if(activity.id = id){
                            dataset.push(activity);
                        }
                    });
                }
            }

           return dataset;

       },
        createArrayDataTopicLowSon:function(id,topics){
            var dataset=[];
            if($.isArray(topics)){
                if(topics.length > 0){
                    $.each(topics,function(i,topic){
                        if(topics.id = id){
                            dataset.push(topic);
                        }
                    });
                }
            }

           return dataset;

       },
       getSons:function(){

           Parent.any({},Curiosity.methodSend.POST,function(response){
                parentController.createCarousel(response);
                if(response.sonMakeActivities.length != null){
                    var intelligences = [];
                    $.each(response.sonMakeActivities,function(i,object){
                        intelligences.push({id:object.idMateria,nombre:object.Materia});
                    });
                    localStorage.setItem('intelligencesSon',JSON.stringify(intelligences));
                }

           },'get-sons');
           parentController.autoSelectedUser();
       },
       getPlan:function(id){
           CORM.any({id:id},Curiosity.methodSend.POST,function(response){
               if(response != null && response != '')
                    $("#pay-button").text("Pagar plan "+response.name);
                    return response;
           },'/plans','get');
       },
       save : function(){
            parentController.formulary.validate(parentController.rulesFormulary);
            if (parentController.formulary.valid()){
               if($("#accept_conditions").is(':checked')){
                   var parent = new Parent(this.data());
                   Curiosity.toastLoading.show();
                   parent.save(Curiosity.methodSend.POST, this.addSuccess);
               }
                else{
                    Curiosity.noty.warning("Acepta primero los términos y codiciones.","¡OJO!");
                }
            }
       },

       addSuccess : function(response){
          Curiosity.toastLoading.hide();
          switch (response.status) {
             case 200:
                console.log(response);
                $.ajax({
                    url: 'logIn',
                    type: 'POST',
                    dataType: 'JSON',
                    data: response.data
                 })
                 .done(function(response) {
                    console.log(response);
                    switch (response.status) {
                       case 200:
                          Curiosity.noty.success("Bien echo!!, Regiostro exitoso.");
                          window.location.href = response.data;
                          break;
                       case "CU-105":
                          Curiosity.noty.info("Lo sentimos tu cuenta a expirado. Renueva cuanto antes y sigue disfrutando de nuestro contenido.");
                          break;
                       case "CU-106":
                          Curiosity.noty.warning("Los datos de accesso que ingresaste son incorrectos, intenta nuevamente", "Datos Erróneos");
                          break;
                       default:
                          Curiosity.noty.error("Contactate con nostros por favor", "Error desconocido");
                          break;
                    }
                 })
                 .fail(function(error) {
                    Curiosity.noty.error("Contactate con nostros por favor", "Error desconocido");
                    console.log(error);
                 });
                break;
             case "CU-104":
                $.each(response.data, function(index, value){
                  $.each(value, function(i, message){
                      Curiosity.noty.warning(message, "Algo va mal");
                  });
                });
                break;
             default:
                Curiosity.noty.error("Consulta con el administrador", "Error desconocido");
                break;
          }
       },

       clearInputs : function(){
          $("."+parentController.prefix+"Inp").val("");
       },

       payment:function($data){
           Conekta.setPublicKey("key_CmADz585Gq19Aqt1xpLWppg");
            var tokenParams = {
              "card": {
                "number": document.getElementById('card_number').value,
                "name": document.getElementById('name').value,
                "exp_year": document.getElementById('exp_year').value,
                "exp_month": document.getElementById('exp_month').value,
                "cvc": document.getElementById('cvv').value
              }
            };

            var successResponseHandler = function(token) {
                var datos={
                    nombre:document.getElementById("name").value,
                    conektaTokenId:token.id,
                    plan_id:localStorage.getItem('plan-user-selected')
                }
                return Parent.any(datos,Curiosity.methodSend.POST,parentController.paymentSuccess,'payment-suscription');
            };

            var errorResponseHandler = function(error) {
              $("#pay-button").prop("disabled",false);
              return Curiosity.noty.warning(error.message_to_purchaser);

            };
            Conekta.Token.create(tokenParams, successResponseHandler, errorResponseHandler);
       },

        paymentSuccess:function(response){
            $("#pay-button").prop("disabled",false);
            console.log(response);
            switch(response.status){
                case 200:
                    localStorage.setItem('plan-user-selected',null);
                    Curiosity.noty.success("Se ha realizado el cobró con exito.");
                    window.location = '/view-parent.registry_firstchild';
                    break;
                default:
                    Curiosity.noty.error("Ups algo ha salido mal reportelo con el administrador.");
            }
        },

        validPlanSelected:function(){
            var exist=0;
            if(localStorage.getItem('plan-user-selected') != null && localStorage.getItem('plan-user-selected') != "null" ){
                exist = 1;
            }
            return exist;
        }

}
<commit_msg>Resolvi el problema de carga de materias<commit_after>var parentController = {

       update: function(id,data,success){
            new Parent(data).update(id,"POST",success);
       },
       prefix:"parent",
       formulary : $("#parent-form"),
       rulesFormulary:{
           rules:{
                email:{
                    required:true,
                    email:true
                },
                username:{
                  required:true,
                  maxlength:40,
                  remote:{
                    "url":"/remote-username",
                    "type":"POST",
                    "username":function(){
                      return $("input[name='username']").val();
                    }
                  }
                },
                nombre:{
                    required:true
                },
                apellidos:{
                    required:true
                },
                sexo:{
                    required:true
                },
                password:{
                    required:true,
                    minlength:8
                },
                cpassword:{
                  required: true,
                  minlength:8,
                  equalTo:function(){
                    return $("input[name='password']");
                  }
                },
                telefono:{
                    required:true,
                    digits:true,
                    minlength:7,
                    maxlength:13
                }
           },messages:{
              cpassword:{equalTo:"Las contraseñas son diferentes"},
              username:{remote:"Nombre de usuario no disponible"}
           }
       },
       data:function(){
            return {
                'email':$("#email").val(),
                'nombre':$("#nombre").val(),
                'apellidos':$("#apellidos").val(),
                'sexo':$("#sexo").val(),
                'password':$("#password").val(),
                'telefono':$("#telefono").val(),
                'username':$("#username").val(),
                'cpassword':$("#cpassword").val()
            }
       },
       id : null,
       itemSon:function(id,name,nivel_id,infoActivities,topicLow){
           return ""+
              "
"+
                 ""+
                 "
"+name+"
"
              "
"+
           "";
       },
       createChartActivities:function(id,nivelId,data){
            if(data.length != 0){
                var iSstorage = localStorage.getItem('intelligencesSon');
                var intelligences = (iSstorage == null) ? null : JSON.parse(iSstorage);
                $.each(intelligences,function(i,intelligence){
                    if(i == 0){
                        $("#materias").append("<fieldset class='form-group'><input value="+intelligence.id+" name='materia' type='radio'  checked='checked'>"+intelligence.nombre+"</fieldset>");
                    }
                    else{
                        $("#materias").append("<fieldset class='form-group'><input val='"+intelligence.id+"' name='materia' type='radio'>"+intelligence.nombre+"</fieldset>");
                    }
                });
                var ctx = document.getElementById("myChart").getContext("2d");
                var materiaID = $("input[name='materia']:checked").val();
                var materia,numRand,chartActivity;
                var dataValues=[];
                var data = {
                    labels: [],
                    datasets: []
                };
                $.each(data,function(i,activity){
                    numRand = Math.random()*(Curiosity.colors.length-1);
                    if(activity.idMateria == materiaID){
                        if(activity.id == id){
                            data.labels.push(activity.nombre_tema);
                            dataValues.push(activity.promedio);
                        }
                    }
                    materia = activity.Materia;
                });
            }

            if(data.length == 0){
                $("#dadNotice").show();
            }else if(data.length < 5){
                $("#materias").show();
                data.datasets.push({
                            label: materia,
                            fill: false,
                            lineTension: 0.1,
                           backgroundColor: [
                                'rgba(255, 99, 132, 0.2)',
                                'rgba(54, 162, 235, 0.2)',
                                'rgba(255, 206, 86, 0.2)',
                                'rgba(75, 192, 192, 0.2)',
                                'rgba(153, 102, 255, 0.2)',
                                'rgba(255, 159, 64, 0.2)'
                            ],
                            borderColor: [
                                'rgba(255,99,132,1)',
                                'rgba(54, 162, 235, 1)',
                                'rgba(255, 206, 86, 1)',
                                'rgba(75, 192, 192, 1)',
                                'rgba(153, 102, 255, 1)',
                                'rgba(255, 159, 64, 1)'
                            ],
                            borderCapStyle: 'butt',
                            borderDash: [],
                            borderDashOffset: 0.0,
                            borderJoinStyle: 'miter',
                            pointBorderColor: "rgba(75,192,192,1)",
                            pointBackgroundColor: "#fff",
                            pointBorderWidth: 1,
                            pointHoverRadius: 5,
                            pointHoverBackgroundColor: "rgba(75,192,192,1)",
                            pointHoverBorderColor: "rgba(220,220,220,1)",
                            pointHoverBorderWidth: 2,
                            pointRadius: 1,
                            pointHitRadius: 10,
                            data: dataValues,
                            spanGaps: false,
                });
                chartActivity = new Chart(ctx, {
                    type: 'bar',
                    data: data
                });

            }else{
                $("#materias").show();
                data.datasets.push({
                    label:materia,
                    backgroundColor: Curiosity.colorsTransparent(.4)[numRand],
                    borderColor: Curiosity.colors()[numRand],
                    pointBackgroundColor: Curiosity.colors()[numRand],
                    pointBorderColor: "#fff",
                    pointHoverBackgroundColor: "#fff",
                    pointHoverBorderColor: Curiosity.colors()[numRand],
                    data:dataValues
                });
                var options ={
                        scale: {
                            reverse: false,
                            ticks: {
                                beginAtZero: true
                            }
                        }
                }
                chartActivity = new Chart(ctx, {
                    type: 'radar',
                    data: data,
                    options: options
                });
            }
       },
       autoSelectedUser:function(){
             $(".hm-carousel").children('.carousel-item').each(function(i,item){
                if(i == 0){
                    $(this).trigger('click');
                    console.log($(this));
                }
             });
       },
       createCarousel:function(response){
           if(response.sons.length > 0){
                $.each(response.sons,function(id,son){
                    var dataActivitiesSon = parentController.createArrayDataSon(son.id,response.sonMakeActivities);
                    var dataTopicLow = parentController.createArrayDataTopicLowSon(son.id,response.temasLow);
                    $(".hm-carousel").append(parentController.itemSon(son.id,son.nombre_completo,son.nivel_id,JSON.stringify(dataActivitiesSon),JSON.stringify(dataTopicLow)));
                });
                $(".carousel").carousel();
            }
       },
       createArrayDataSon:function(id,activities){
            var dataset=[];
            if($.isArray(activities)){
                if(activities.length > 0){
                    $.each(activities,function(i,activity){
                        if(activity.id = id){
                            dataset.push(activity);
                        }
                    });
                }
            }

           return dataset;

       },
        createArrayDataTopicLowSon:function(id,topics){
            var dataset=[];
            if($.isArray(topics)){
                if(topics.length > 0){
                    $.each(topics,function(i,topic){
                        if(topics.id = id){
                            dataset.push(topic);
                        }
                    });
                }
            }

           return dataset;

       },
       getSons:function(){

           Parent.any({},Curiosity.methodSend.POST,function(response){
                parentController.createCarousel(response);
                if(response.sonMakeActivities.length != null){
                    var intelligences = [];
                    $.each(response.sonMakeActivities,function(i,object){
                        intelligences.push({id:object.idMateria,nombre:object.Materia});
                    });
                    localStorage.setItem('intelligencesSon',JSON.stringify(intelligences));
                }

           },'get-sons');
           parentController.autoSelectedUser();
       },
       getPlan:function(id){
           CORM.any({id:id},Curiosity.methodSend.POST,function(response){
               if(response != null && response != '')
                    $("#pay-button").text("Pagar plan "+response.name);
                    return response;
           },'/plans','get');
       },
       save : function(){
            parentController.formulary.validate(parentController.rulesFormulary);
            if (parentController.formulary.valid()){
               if($("#accept_conditions").is(':checked')){
                   var parent = new Parent(this.data());
                   Curiosity.toastLoading.show();
                   parent.save(Curiosity.methodSend.POST, this.addSuccess);
               }
                else{
                    Curiosity.noty.warning("Acepta primero los términos y codiciones.","¡OJO!");
                }
            }
       },

       addSuccess : function(response){
          Curiosity.toastLoading.hide();
          switch (response.status) {
             case 200:
                console.log(response);
                $.ajax({
                    url: 'logIn',
                    type: 'POST',
                    dataType: 'JSON',
                    data: response.data
                 })
                 .done(function(response) {
                    console.log(response);
                    switch (response.status) {
                       case 200:
                          Curiosity.noty.success("Bien echo!!, Regiostro exitoso.");
                          window.location.href = response.data;
                          break;
                       case "CU-105":
                          Curiosity.noty.info("Lo sentimos tu cuenta a expirado. Renueva cuanto antes y sigue disfrutando de nuestro contenido.");
                          break;
                       case "CU-106":
                          Curiosity.noty.warning("Los datos de accesso que ingresaste son incorrectos, intenta nuevamente", "Datos Erróneos");
                          break;
                       default:
                          Curiosity.noty.error("Contactate con nostros por favor", "Error desconocido");
                          break;
                    }
                 })
                 .fail(function(error) {
                    Curiosity.noty.error("Contactate con nostros por favor", "Error desconocido");
                    console.log(error);
                 });
                break;
             case "CU-104":
                $.each(response.data, function(index, value){
                  $.each(value, function(i, message){
                      Curiosity.noty.warning(message, "Algo va mal");
                  });
                });
                break;
             default:
                Curiosity.noty.error("Consulta con el administrador", "Error desconocido");
                break;
          }
       },

       clearInputs : function(){
          $("."+parentController.prefix+"Inp").val("");
       },

       payment:function($data){
           Conekta.setPublicKey("key_CmADz585Gq19Aqt1xpLWppg");
            var tokenParams = {
              "card": {
                "number": document.getElementById('card_number').value,
                "name": document.getElementById('name').value,
                "exp_year": document.getElementById('exp_year').value,
                "exp_month": document.getElementById('exp_month').value,
                "cvc": document.getElementById('cvv').value
              }
            };

            var successResponseHandler = function(token) {
                var datos={
                    nombre:document.getElementById("name").value,
                    conektaTokenId:token.id,
                    plan_id:localStorage.getItem('plan-user-selected')
                }
                return Parent.any(datos,Curiosity.methodSend.POST,parentController.paymentSuccess,'payment-suscription');
            };

            var errorResponseHandler = function(error) {
              $("#pay-button").prop("disabled",false);
              return Curiosity.noty.warning(error.message_to_purchaser);

            };
            Conekta.Token.create(tokenParams, successResponseHandler, errorResponseHandler);
       },

        paymentSuccess:function(response){
            $("#pay-button").prop("disabled",false);
            console.log(response);
            switch(response.status){
                case 200:
                    localStorage.setItem('plan-user-selected',null);
                    Curiosity.noty.success("Se ha realizado el cobró con exito.");
                    window.location = '/view-parent.registry_firstchild';
                    break;
                default:
                    Curiosity.noty.error("Ups algo ha salido mal reportelo con el administrador.");
            }
        },

        validPlanSelected:function(){
            var exist=0;
            if(localStorage.getItem('plan-user-selected') != null && localStorage.getItem('plan-user-selected') != "null" ){
                exist = 1;
            }
            return exist;
        }

}
<|endoftext|>


<commit_before>import Player from '../../../sprites/character/Player';
import {
  findObjByKey,
  centerOfObject,
} from '../../../utils';
import frames from '../../../sprite-frames';

export default function addPlayer() {
  const playerStartObj = findObjByKey(this.map.objects.objects, 'name', 'playerStart');

  const playerStart = centerOfObject(playerStartObj, this.map);

  this.player = new Player({
    game: this.game,
    x: playerStart.x,
    y: playerStart.y,
  });

  this.game.camera.follow(this.player);
}
<commit_msg>Remove frames import<commit_after>import Player from '../../../sprites/character/Player';
import {
  findObjByKey,
  centerOfObject,
} from '../../../utils';

export default function addPlayer() {
  const playerStartObj = findObjByKey(this.map.objects.objects, 'name', 'playerStart');

  const playerStart = centerOfObject(playerStartObj, this.map);

  this.player = new Player({
    game: this.game,
    x: playerStart.x,
    y: playerStart.y,
  });

  this.game.camera.follow(this.player);
}
<|endoftext|>


<commit_before>function makeData() {
  "use strict";
  return [{name: "Frodo", y: 3}, {name: "Sam", y: 2}, {name: "Gollum", y: 4}];
}

function run(svg, data, Plottable) {
  "use strict";

  var xScale = new Plottable.Scales.Category();
  var yScale = new Plottable.Scales.Linear();
  var xAxis = new Plottable.Axes.Category(xScale, "bottom");
  var yAxis = new Plottable.Axes.Numeric(yScale, "left");
  var title = new Plottable.Components.Label("Hover over bars").classed("title-label", true);
  var colorScale = new Plottable.Scales.Color();

  var ds = new Plottable.Dataset(data, { foo: "!" });

  var plot = new Plottable.Plots.Bar(xScale, yScale, true)
    .addDataset(ds)
    .x(function (d, i, dataset) { return d.name + dataset.metadata().foo; }, xScale)
    .y(function(d) { return d.y; }, yScale)
    .attr("fill", function(d) { return d.name; }, colorScale);

  var chart = new Plottable.Components.Table([
      [null, title],
      [yAxis, plot],
      [null, xAxis]]);

  chart.renderTo(svg);

  var pointer = new Plottable.Interactions.Pointer();
  pointer.onPointerMove(function(p) {
    var cpd = plot.getClosestPlotData(p);
    if (cpd.data.length > 0) {
      title.text(cpd.data[0].name);
    } else {
      title.text("Who?");
    }
  });
  pointer.onPointerExit(function(p) { title.text("Who?"); });
  pointer.attachTo(plot);
}
<commit_msg>[2014fix] Fixed test issue<commit_after>function makeData() {
  "use strict";
  return [{name: "Frodo", y: 3}, {name: "Sam", y: 2}, {name: "Gollum", y: 4}];
}

function run(svg, data, Plottable) {
  "use strict";

  var xScale = new Plottable.Scales.Category();
  var yScale = new Plottable.Scales.Linear();
  var xAxis = new Plottable.Axes.Category(xScale, "bottom");
  var yAxis = new Plottable.Axes.Numeric(yScale, "left");
  var title = new Plottable.Components.Label("Hover over bars").classed("title-label", true);
  var colorScale = new Plottable.Scales.Color();

  var ds = new Plottable.Dataset(data, { foo: "!" });

  var plot = new Plottable.Plots.Bar(xScale, yScale, true)
    .addDataset(ds)
    .x(function (d, i, dataset) { return d.name + dataset.metadata().foo; }, xScale)
    .y(function(d) { return d.y; }, yScale)
    .attr("fill", function(d) { return d.name; }, colorScale);

  var chart = new Plottable.Components.Table([
      [null, title],
      [yAxis, plot],
      [null, xAxis]]);

  chart.renderTo(svg);

  var pointer = new Plottable.Interactions.Pointer();
  pointer.onPointerMove(function(p) {
    var cpd = plot.getClosestPlotData(p);
    if (cpd.data.length > 0) {
      title.text("" + cpd.data[0].name);
    } else {
      title.text("Who?");
    }
  });
  pointer.onPointerExit(function(p) { title.text("Who?"); });
  pointer.attachTo(plot);
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { graphql } from 'react-apollo';

import Styles from 'react/styles';

import OptionLink, { optionLinkPadding } from 'react/components/UI/OptionLink';

import deleteChannelMutation from 'react/components/ManageChannel/components/DeleteChannel/mutations/deleteChannel';

const Alert = styled.div`
  color: ${Styles.Colors.state.alert};
`;

const Message = styled.div`
  padding: ${optionLinkPadding};
  font-size: ${Styles.Type.size.xs};
  text-align: left;
`;

class DeleteChannel extends Component {
  static propTypes = {
    id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
    deleteChannel: PropTypes.func.isRequired,
  }

  state = {
    mode: 'resting',
  }

  pendDeleteChannel = () => {
    this.setState({ mode: 'pending' });
  }

  deleteChannel = () => {
    const { mode } = this.state;

    if (mode !== 'pending') return null;

    const { id, deleteChannel } = this.props;

    this.setState({ mode: 'deleting' });

    return deleteChannel({
      variables: { id },
    })
      .then(() => {
        window.location = '/';
      })
      .catch((err) => {
        console.error(err);
        // TODO: Better error handling
        this.setState({ mode: 'error' });
      });
  }

  cancelDeleteChannel = () => {
    this.setState({ mode: 'resting' });
  }

  render() {
    const { mode } = this.state;

    return (

        <OptionLink size="xs" onClick={this.pendDeleteChannel}>
          Delete channel
        </OptionLink>

        {mode === 'error' &&
          <Alert>
            <Message>
              An error has occurred. Try again.
            </Message>
          </Alert>
        }

        {mode === 'deleting' &&
          <Alert>
            <Message>
              Deleting...
            </Message>
          </Alert>
        }

        {mode === 'pending' &&
          <Alert>
            <Message>
              Are you sure? This action cannot be undone.
            </Message>

            <OptionLink size="xs" onClick={this.deleteChannel}>
              Yes
            </OptionLink>

            <OptionLink size="xs" onClick={this.cancelDeleteChannel}>
              No
            </OptionLink>
          </Alert>
        }

    );
  }
}

export default graphql(deleteChannelMutation, {
  name: 'deleteChannel',
})(DeleteChannel);
<commit_msg>Button-ify delete channel options<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { graphql } from 'react-apollo';

import Styles from 'react/styles';

import OptionLink, { optionLinkPadding } from 'react/components/UI/OptionLink';
import GenericButton from 'react/components/UI/GenericButton';

import deleteChannelMutation from 'react/components/ManageChannel/components/DeleteChannel/mutations/deleteChannel';

const Alert = styled.div`
  color: ${Styles.Colors.state.alert};
`;

const Message = styled.div`
  padding: ${optionLinkPadding};
  font-size: ${Styles.Type.size.xs};
  text-align: left;
`;

const Options = styled.div`
  margin: 0.5em 0;
  padding: ${optionLinkPadding};
`;

const Option = styled(GenericButton).attrs({
  minWidth: '6em',
  size: 'xs',
  color: 'state.alert',
})`
`;

class DeleteChannel extends Component {
  static propTypes = {
    id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
    deleteChannel: PropTypes.func.isRequired,
  }

  state = {
    mode: 'resting',
  }

  pendDeleteChannel = () => {
    this.setState({ mode: 'pending' });
  }

  deleteChannel = () => {
    const { mode } = this.state;

    if (mode !== 'pending') return null;

    const { id, deleteChannel } = this.props;

    this.setState({ mode: 'deleting' });

    return deleteChannel({
      variables: { id },
    })
      .then(() => {
        window.location = '/';
      })
      .catch((err) => {
        console.error(err);
        // TODO: Better error handling
        this.setState({ mode: 'error' });
      });
  }

  cancelDeleteChannel = () => {
    this.setState({ mode: 'resting' });
  }

  render() {
    const { mode } = this.state;

    return (

        <OptionLink size="xs" onClick={this.pendDeleteChannel}>
          Delete channel
        </OptionLink>

        {mode === 'error' &&
          <Alert>
            <Message>
              An error has occurred. Try again.
            </Message>
          </Alert>
        }

        {mode === 'deleting' &&
          <Alert>
            <Message>
              Deleting...
            </Message>
          </Alert>
        }

        {mode === 'pending' &&
          <Alert>
            <Message>
              Are you sure? This action cannot be undone.
            </Message>

            <Options>
              <Option onClick={this.deleteChannel}>
                Delete
              </Option>

              {' '}

              <Option onClick={this.cancelDeleteChannel}>
                Cancel
              </Option>
            </Options>
          </Alert>
        }

    );
  }
}

export default graphql(deleteChannelMutation, {
  name: 'deleteChannel',
})(DeleteChannel);
<|endoftext|>


<commit_before>"use strict";
var async=require('async');

var Git=require('git-wrapper2'),
	ss=require('simple-statistics'),
	Q=require('q');

function GitShow(options) {
	var debug=require('debug')('git:GitShow'),
		git=new Git(), gitExecPromise=Q.defer();

	debug("showing commit %j", (options && options.commit) || "HEAD");
	git.exec("show", [(options && options.commit) || "HEAD"], function results(err, show_out) {
		debug=require('debug')('git:GitShow:results');
		debug("err %j out %j", err, show_out);
		if(err) {
			debug("err: %j", err);
			return gitExecPromise.reject(err);
		}
		if( show_out==undefined ) {
			return gitExecPromise.resolve(null);
		}
		//debug("show output: %s", show_out);
		var out=show_out.split('\n'), currentDiff, allDiffs=[], showPromise=Q.defer(),
			commit={
				hash: undefined,
				author: undefined,
				date: undefined,
				message: undefined
			};
		debug("out %j", out);

		async.eachSeries( out, function forEachLine(line, nextLine) {
			var commitMatch, authorMatch, dateMatch, mergeMatch, diffMatch;
			debug=require('debug')('git:GitShow:results:forEachLine');
			debug("line %s", line);
			//debug("allDiffs %j", allDiffs);
			debug("commit %j", commit);
			commit.message="";
			if( undefined===currentDiff ) {
				commitMatch=line.match(/.*commit ([0123456789abcdef]+)/);
				if( commitMatch ) {
					commit.hash=commitMatch[1];
					debug("setting hash %s", commit.hash);
					return nextLine();
				}
				mergeMatch=line.match(/Merge: ([^ ]+) ([^ ]+)^/);
				if(mergeMatch) {
					debug("setting merge");
					commits.merge={
						a: mergeMatch[1],
						b: mergeMatch[2]
					};
					return nextLine();
				}
				authorMatch=line.match(/Author: ([^ ]+) <([^>]+)>/);
				if( authorMatch ) {
					debug("setting author %s", line);
					commit.author={
						name: authorMatch[1],
						email: authorMatch[2]
					};
					return nextLine();
				}
				dateMatch=line.match(/Date:\s+(.+)$/);
				if( dateMatch ) {
					debug("setting date");
					commit.date=dateMatch[1];
					return nextLine();
				}
				if(line.match(/^$/)) {
					if(commit.message) {
						debug("adding blank line");
						commit.message+="\n";
						return nextLine();
					}
				}
				diffMatch=line.match(/^diff --git a\/([^ ]+) b\/(.+)/);
				if(diffMatch) {
					debug("new diff %s %s", diffMatch[1], diffMatch[2]);
					currentDiff={
						linesAdded: 0,
						linesDeleted: 0,
						deltas: 0,
						fileOne: diffMatch[1],
						fileTwo: diffMatch[2]
					};
					return nextLine();
				}
				debug("setting message");
				commit.message+=line;
				return nextLine();
			}
			debug("currentDiff %j", currentDiff);
			//look for new file line
			debug("looking for new file");
			var newFileLineMatch=line.match(/new file mode ([a-zA-Z0-9]{6})/);
			if( newFileLineMatch ){
				return nextLine();
			}
			//look for index line
			var indexLineMatch=line.match(/^index ([a-zA-Z0-9]+)\.\.([a-zA-Z0-9]+) ([0-7]{6})/),
				plusLine, minusLine, newDiffMatch;
			debug("looking for index");
			if( indexLineMatch ) {
				debug("index line: %s %s %s", indexLineMatch[1], indexLineMatch[2], indexLineMatch[3]);
				currentDiff.startingHash=indexLineMatch[1];
				currentDiff.endingHash=indexLineMatch[2];
				currentDiff.mode=indexLineMatch[3];
				return nextLine();
			}
			//look for +++ line in a
			plusLine=line.match(/^\+{3} a\/.+/);
			debug("looking for +++");
			if( plusLine ) {
				debug("+++");
				return nextLine();
			}
			//look for +++ line in b
			plusLine=line.match(/^\+{3} b\/.+/);
			debug("looking for +++");
			if( plusLine ) {
				debug("+++");
				return nextLine();
			}
			//look for --- line in a
			minusLine=line.match(/^-{3} a\/.+/);
			debug("looking for ---");
			if( minusLine ) {
				debug("---");
				return nextLine();
			}
			//look for --- line in b
			minusLine=line.match(/^-{3} b\/.+/);
			debug("looking for ---");
			if( minusLine ) {
				debug("---");
				return nextLine();
			}
			debug("look for @@ line in %s", line);
			if( line.match(/^@@.+@@$/) ) {
				debug("@@");
				return nextLine();
			}
			//look for the line
			debug("looking for + or - in %s", line);
			if(line.match(/^-/)) {
				currentDiff.linesDeleted++;
				debug("one more line deleted %d", currentDiff.linesDeleted);
			}
			if(line.match(/^\+/)) {
				currentDiff.linesAdded++;
				debug("one more line added %d", currentDiff.linesAdded);
			}
			newDiffMatch=line.match(/^diff --git a\/([^ ]+) b\/(.+)/);
			debug("looking for new diff in %s", line);
			if(newDiffMatch) {
				currentDiff.deltas=currentDiff.linesAdded-currentDiff.linesDeleted;
				allDiffs.push(currentDiff);
				currentDiff={
					linesAdded: 0,
					linesDeleted: 0,
					deltas: 0,
					fileOne: newDiffMatch[1],
					fileTwo: newDiffMatch[2]
				};
				return nextLine();
			}
			nextLine();
		}, function afterEveryLineIsProcessed(err) {
			//add the last diff
			if( currentDiff ) {
				currentDiff.deltas=currentDiff.linesAdded-currentDiff.linesDeleted;
				allDiffs.push(currentDiff);
			}
			debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed');
			debug("allDiffs %j", allDiffs);
			var numDiffs=allDiffs.length, allDeltas=[], allAdditions=[], allDeletions=[],
				totalLinesChanged=0, averageLinesChanged=0, varianceLinesChanged=0, standardDeviationLinesChanged=0,
				averageLinesAdded=0, varianceLinesAdded=0, standardDeviationLinesAdded=0,
				averageLinesDeleted=0, varianceLinesDeleted=0, standardDeviationLinesDeleted=0;

			debug("all lines processed");
			async.each( allDiffs, function eachDiff(d, done) {
				debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed:eachDiff');
				debug("adding diff %d", d.deltas);
				totalLinesChanged+=d.deltas;
				allDeltas.push(d.deltas);
				allAdditions.push(d.linesAdded);
				allDeletions.push(d.linesDeleted);
				done();
			}, function afterTotalLinesCalculated(err) {
				debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed:afterTotalLinesCalculated');
				if(err) {
					debug("err: %j", err);
					return gitExecPromise.reject(err);
				}
				averageLinesChanged=ss.mean(allDeltas);
				varianceLinesChanged=ss.variance(allDeltas);
				standardDeviationLinesChanged=ss.standard_deviation(allDeltas);

				averageLinesAdded=ss.mean(allAdditions);
				varianceLinesAdded=ss.variance(allAdditions);
				standardDeviationLinesAdded=ss.standard_deviation(allAdditions);

				averageLinesDeleted=ss.mean(allDeletions);
				varianceLinesDeleted=ss.variance(allDeletions);
				standardDeviationLinesDeleted=ss.standard_deviation(allDeletions);
				debug("resolving promise %j %d %d %d", allDeltas, averageLinesChanged, varianceLinesChanged, standardDeviationLinesChanged );

				gitExecPromise.resolve({
					averageLinesChanged: averageLinesChanged,
					varianceLinesChanged: varianceLinesChanged,
					standardDeviationLinesChanged: standardDeviationLinesChanged,
					averageLinesAdded: averageLinesAdded,
					varianceLinesAdded: varianceLinesAdded,
					standardDeviationLinesAdded: standardDeviationLinesAdded,
					averageLinesDeleted: averageLinesDeleted,
					varianceLinesDeleted: varianceLinesDeleted,
					standardDeviationLinesDeleted: standardDeviationLinesDeleted,
					diffs: allDiffs
				});
			});
		});
	});
	return gitExecPromise.promise;
}

module.exports=GitShow;<commit_msg>added debug lines, set null statistics to 0<commit_after>"use strict";
var async=require('async');

var Git=require('git-wrapper2'),
	ss=require('simple-statistics'),
	Q=require('q');

function GitShow(options) {
	var debug=require('debug')('git:GitShow'),
		git=new Git(), gitExecPromise=Q.defer();

	debug("showing commit %j", (options && options.commit) || "HEAD");
	git.exec("show", [(options && options.commit) || "HEAD"], function results(err, show_out) {
		debug=require('debug')('git:GitShow:results');
		debug("err %j out %j", err, show_out);
		if(err) {
			debug("err: %j", err);
			return gitExecPromise.reject(err);
		}
		if( show_out==undefined ) {
			return gitExecPromise.resolve(null);
		}
		//debug("show output: %s", show_out);
		var out=show_out.split('\n'), currentDiff, allDiffs=[], showPromise=Q.defer(),
			commit={
				hash: undefined,
				author: undefined,
				date: undefined,
				message: undefined
			};
		debug("out %j", out);

		async.eachSeries( out, function forEachLine(line, nextLine) {
			var commitMatch, authorMatch, dateMatch, mergeMatch, diffMatch;
			debug=require('debug')('git:GitShow:results:forEachLine');
			debug("line %s", line);
			//debug("allDiffs %j", allDiffs);
			debug("commit %j %j", commit, currentDiff);
			commit.message="";
			if( undefined===currentDiff ) {
				debug("looking for commit");
				commitMatch=line.match(/.*commit ([0123456789abcdef]+)/);
				if( commitMatch ) {
					commit.hash=commitMatch[1];
					debug("setting hash %s", commit.hash);
					return nextLine();
				}
				debug("looking for merge");
				mergeMatch=line.match(/Merge: ([^ ]+) ([^ ]+)^/);
				if(mergeMatch) {
					debug("setting merge");
					commits.merge={
						a: mergeMatch[1],
						b: mergeMatch[2]
					};
					return nextLine();
				}
				debug("looking for author");
				authorMatch=line.match(/Author: ([^ ]+) <([^>]+)>/);
				if( authorMatch ) {
					debug("setting author %s", line);
					commit.author={
						name: authorMatch[1],
						email: authorMatch[2]
					};
					return nextLine();
				}
				debug("looking for date");
				dateMatch=line.match(/Date:\s+(.+)$/);
				if( dateMatch ) {
					debug("setting date");
					commit.date=dateMatch[1];
					return nextLine();
				}
				debug("looking for blank line");
				if(line.match(/^$/)) {
					if(commit.message) {
						debug("adding blank line");
						commit.message+="\n";
						return nextLine();
					}
				}
				debug("looking for new diff");
				diffMatch=line.match(/^diff --git a\/([^ ]+) b\/(.+)/);
				if(diffMatch) {
					debug("new diff %s %s", diffMatch[1], diffMatch[2]);
					currentDiff={
						linesAdded: 0,
						linesDeleted: 0,
						deltas: 0,
						fileOne: diffMatch[1],
						fileTwo: diffMatch[2]
					};
					return nextLine();
				}
				debug("setting message");
				commit.message+=line;
				return nextLine();
			}
			debug("currentDiff %j", currentDiff);
			//look for new file line
			debug("looking for new file");
			var newFileLineMatch=line.match(/new file mode ([a-zA-Z0-9]{6})/);
			if( newFileLineMatch ){
				return nextLine();
			}
			//look for index line
			var indexLineMatch=line.match(/^index ([a-zA-Z0-9]+)\.\.([a-zA-Z0-9]+) ([0-7]{6})/),
				plusLine, minusLine, newDiffMatch;
			debug("looking for index");
			if( indexLineMatch ) {
				debug("index line: %s %s %s", indexLineMatch[1], indexLineMatch[2], indexLineMatch[3]);
				currentDiff.startingHash=indexLineMatch[1];
				currentDiff.endingHash=indexLineMatch[2];
				currentDiff.mode=indexLineMatch[3];
				return nextLine();
			}
			//look for +++ line in a
			plusLine=line.match(/^\+{3} a\/.+/);
			debug("looking for +++");
			if( plusLine ) {
				debug("+++");
				return nextLine();
			}
			//look for +++ line in b
			plusLine=line.match(/^\+{3} b\/.+/);
			debug("looking for +++");
			if( plusLine ) {
				debug("+++");
				return nextLine();
			}
			//look for --- line in a
			minusLine=line.match(/^-{3} a\/.+/);
			debug("looking for ---");
			if( minusLine ) {
				debug("---");
				return nextLine();
			}
			//look for --- line in b
			minusLine=line.match(/^-{3} b\/.+/);
			debug("looking for ---");
			if( minusLine ) {
				debug("---");
				return nextLine();
			}
			debug("look for @@ line in %s", line);
			if( line.match(/^@@.+@@$/) ) {
				debug("@@");
				return nextLine();
			}
			//look for the line
			debug("looking for + or - in %s", line);
			if(line.match(/^-/)) {
				currentDiff.linesDeleted++;
				debug("one more line deleted %d", currentDiff.linesDeleted);
			}
			if(line.match(/^\+/)) {
				currentDiff.linesAdded++;
				debug("one more line added %d", currentDiff.linesAdded);
			}
			newDiffMatch=line.match(/^diff --git a\/([^ ]+) b\/(.+)/);
			debug("looking for new diff in %s", line);
			if(newDiffMatch) {
				currentDiff.deltas=currentDiff.linesAdded-currentDiff.linesDeleted;
				allDiffs.push(currentDiff);
				currentDiff={
					linesAdded: 0,
					linesDeleted: 0,
					deltas: 0,
					fileOne: newDiffMatch[1],
					fileTwo: newDiffMatch[2]
				};
				return nextLine();
			}
			nextLine();
		}, function afterEveryLineIsProcessed(err) {
			//add the last diff
			if( currentDiff ) {
				currentDiff.deltas=currentDiff.linesAdded-currentDiff.linesDeleted;
				allDiffs.push(currentDiff);
			}
			debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed');
			debug("allDiffs %j", allDiffs);
			var numDiffs=allDiffs.length, allDeltas=[], allAdditions=[], allDeletions=[],
				totalLinesChanged=0, averageLinesChanged=0, varianceLinesChanged=0, standardDeviationLinesChanged=0,
				averageLinesAdded=0, varianceLinesAdded=0, standardDeviationLinesAdded=0,
				averageLinesDeleted=0, varianceLinesDeleted=0, standardDeviationLinesDeleted=0;

			debug("all lines processed");
			async.each( allDiffs, function eachDiff(d, done) {
				debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed:eachDiff');
				debug("adding diff %d", d.deltas);
				totalLinesChanged+=d.deltas;
				allDeltas.push(d.deltas);
				allAdditions.push(d.linesAdded);
				allDeletions.push(d.linesDeleted);
				done();
			}, function afterTotalLinesCalculated(err) {
				debug=require('debug')('git:GitShow:results:afterEveryLineIsProcessed:afterTotalLinesCalculated');
				if(err) {
					debug("err: %j", err);
					return gitExecPromise.reject(err);
				}
				averageLinesChanged=ss.mean(allDeltas);
				varianceLinesChanged=ss.variance(allDeltas);
				standardDeviationLinesChanged=ss.standard_deviation(allDeltas);

				averageLinesAdded=ss.mean(allAdditions);
				varianceLinesAdded=ss.variance(allAdditions);
				standardDeviationLinesAdded=ss.standard_deviation(allAdditions);

				averageLinesDeleted=ss.mean(allDeletions);
				varianceLinesDeleted=ss.variance(allDeletions);
				standardDeviationLinesDeleted=ss.standard_deviation(allDeletions);
				debug("resolving promise %j %d %d %d", allDeltas, averageLinesChanged, varianceLinesChanged, standardDeviationLinesChanged );

				gitExecPromise.resolve({
					averageLinesChanged: averageLinesChanged || 0,
					varianceLinesChanged: varianceLinesChanged || 0,
					standardDeviationLinesChanged: standardDeviationLinesChanged || 0,
					averageLinesAdded: averageLinesAdded || 0,
					varianceLinesAdded: varianceLinesAdded || 0,
					standardDeviationLinesAdded: standardDeviationLinesAdded || 0,
					averageLinesDeleted: averageLinesDeleted || 0,
					varianceLinesDeleted: varianceLinesDeleted || 0,
					standardDeviationLinesDeleted: standardDeviationLinesDeleted || 0,
					diffs: allDiffs
				});
			});
		});
	});
	return gitExecPromise.promise;
}

module.exports=GitShow;<|endoftext|>


<commit_before>(function() {
  // cached super methods
  var _route = Backbone.History.prototype.route;
  var _getFragment = Backbone.History.prototype.getFragment;
  var _start = Backbone.History.prototype.start;
  var _checkUrl = Backbone.History.prototype.checkUrl;
  var _navigate = Backbone.History.prototype.navigate;
  var _extractParameters = Backbone.Router.prototype._extractParameters;

  // If we are in hash mode figure out if we are on a browser that is hit by 63777 and 85881
  //     https://bugs.webkit.org/show_bug.cgi?id=63777
  var _useReplaceState = /WebKit\/([\d.]+)/.exec(navigator.userAgent) && window.history.replaceState,

      // Some variants of android will not replace the location history properly, causing issues
      // on back navigation. Hack around the replace API making it two step for these cases.
      //
      // This is likely tied to a specific Webkit version but sticking to the environments that we
      // know this occurs in rather than trying to track down the webkit version that this might
      // be impacting and possibly getting it wrong.
      //    https://bugs.webkit.org/show_bug.cgi?id=85881
      _fakeReplace = /Android\s+([\d.]+)/.exec(navigator.userAgent) && (parseFloat(RegExp.$1) < 4.2);

  // pattern to recognize state index in hash
  var hashStrip = /^(?:#|%23)*\d*(?:#|%23)*/;
  // Cached regex for index extraction from the hash
  var indexMatch = /^(?:#|%23)*(\d+)(?:#|%23)/;

  _.extend(Backbone.Router.prototype, {
    // the direction index will be exposed on the parameters as 'direction'
    _extractParameters: function() {
      var params = _extractParameters.apply(this, arguments);
      params = params || [];
      var history = Backbone.history;
      if (history._trackDirection) {
        var oldIndex = history._directionIndex;
        history._directionIndex = history.loadIndex();
        params.direction = history._directionIndex - oldIndex;
      }
      return params;
    }
  });

  _.extend(Backbone.History.prototype, {
    // Get the location of the current route within the backbone history.
    // This should be considered a hint
    // Returns -1 if history is unknown or disabled
    getIndex : function() {
      return this._directionIndex;
    },

    getFragment : function(/* fragment, forcePushState */) {
      var rtn = _getFragment.apply(this, arguments);
      return rtn && rtn.replace(hashStrip, '');
    },

    start: function(/* options */) {
      var rtn = _start.apply(this, arguments);

      this._fakeReplace = _fakeReplace && !this.options.noReplaceHack;

      // Direction tracking setup
      this._trackDirection  = !!this.options.trackDirection;
      if (this._trackDirection) {
        var loadedIndex = this.loadIndex();
        this._directionIndex  = loadedIndex || window.history.length;
        this._state = {index: this._directionIndex};

        // If we are tracking direction ensure that we have a direction field to play with
        if (!loadedIndex) {
          var loc = window.location;
          if (!this._hasPushState) {
            loc.replace(loc.pathname + (loc.search || '') + '#' + this._directionIndex + '#' + this.fragment);
          } else {
            window.history.replaceState({index: this._directionIndex}, document.title, loc);
          }
        }
      }
      return rtn;
    },

    checkUrl : function(e) {
      var fromIframe = this.getFragment() == this.fragment && this.iframe;
      var loadedIndex = this.loadIndex(fromIframe && this.iframe.location.hash);
      var navigateOptions = {
        trigger: false,
        replace: !loadedIndex,
        forceIndex: loadedIndex || this._directionIndex + 1
      };
      _checkUrl.call(this, e, navigateOptions);
    },

    // The options object can contain `trigger: true` if you wish to have the
    // route callback be fired (not usually desirable), or `replace: true`, if
    // you wish to modify the current URL without adding an entry to the history.
    navigate: function(fragment, options) {
      if (this._ignoreChange) {
        this._pendingNavigate = _.bind(this.navigate, this, fragment, options);
        return;
      } else if (options && options.replace && this._fakeReplace) {
        // Under older Android environment we have to back out and then trigger a route in two
        // operations rather than an automic replace operation. Without this flow does not operate
        // correctly:
        //  1. Trigger #foo
        //  2. Replace #bar
        //  3. Trigger #baz
        //
        // This will trigger all of the proper routes but the history for this case will actually
        // be #foo, #baz rather than the desired #bar, #baz, causing unexpected navigation.
        options = _.omit(options, 'replace');
        options._replace = true;
        this._pendingNavigate = _.bind(this.navigate, this, fragment, options);
        this.back();
        return;
      }

      if (!options || options === true) {
        options = {trigger: options};
      }
      var newIndex;
      if (this._trackDirection) {
        newIndex = options.forceIndex || (this._directionIndex + (options.replace ? 0 : 1));

        if (options._replace) {
          // The step back mucked with our direction tracker. Update.
          this._directionIndex++;
        }
      }
      if (this._hasPushState) {
        options.state = {index: newIndex};
      } else {
        if (this._trackDirection) {
          fragment = newIndex + '#' + fragment;
        }
      }
      _navigate.call(this, fragment, options);
    },

    _updateHash: function(location, frag, replace) {
      var base = location.toString().replace(/(javascript:|#).*$/, '') + '#';
      if (replace) {
        if (_useReplaceState) {
          window.history.replaceState({}, document.title, base + frag);
        } else {
          location.replace(base + frag);
        }
      } else {
        location.hash = frag;
      }
    },

    // Pulls the direction index out of the state or hash
    loadIndex : function(fragmentOverride) {
      if (!this._trackDirection) {
        return;
      }
      if (!fragmentOverride && this._hasPushState) {
        return (this._state && this._state.index) || 0;
      } else {
        var match = indexMatch.exec(fragmentOverride || window.location.hash);
        return (match && parseInt(match[1], 10)) || 0;
      }
    },

    route: function (route, callback) {
      return _route.call(this, route, _.bind(function(fragment) {
        var ignore = this._ignoreChange;
        if (_.isFunction(ignore)) {
          ignore = !this._ignoreChange(fragment, route);
        }

        this._ignoreChange = false;

        if (ignore) {
          this._directionIndex = Backbone.history.loadIndex();
          var pendingNavigate = this._pendingNavigate;
          if (pendingNavigate) {
              var self = this;
            _.defer(function() {
              // back() was called before pendingNavigate and it could have updated
              // this.fragment to the same as pending navigate fragment. This will make
              // navigate a NOP. Hence resetting the fragment to make sure navigate will
              // do its job.
              self.fragment = undefined;
              pendingNavigate();
            });
          }
          this._pendingNavigate = undefined;
        } else {
          callback && callback.apply(this, arguments);
        }
      }, this));
    },

    back : function(triggerRoute) {
      this.go(-1, triggerRoute);
    },

    forward : function(triggerRoute) {
      this.go(1, triggerRoute);
    },

    go : function(count, triggerRoute) {
      this._ignoreChange = _.isFunction(triggerRoute) ? triggerRoute : !triggerRoute;

      // Explicitly use `back()` and `forward()` methods since `go(1)` and `go(-1)` may behave
      // unexpectedly in different browsers, although their behavior should be equivalent; see
      // the Chromium bugs https://code.google.com/p/chromium/issues/detail?id=241888 and
      // https://code.google.com/p/chromium/issues/detail?id=244434
      switch (count) {
        case -1:
          window.history.back();
          break;
        case 1:
          window.history.forward();
          break;
        default:
          window.history.go(count);
      }
    },

    /**
     * Hack to work around iframes that make have screwed with our history state.
     * Really one should choose not to use iframes but sometimes you must, even in 2013....
     */
    stepOut: function(options) {
      options = options || {};

      var routeLimit,
          desiredRoute,
          timeout;

      if (options.view) {
        options.view.$('iframe').remove();
      }

      if (_.isString(options.trigger)) {
        // If a string is passed then we will ensure that they land on the desired route one way
        // or the other
        desiredRoute = options.trigger;
        routeLimit = options.routeLimit || 1;

        options.trigger = function(fragment) {
          routeLimit--;

          if (fragment === desiredRoute) {
            return true;
          } else if (routeLimit <= 0) {
            Backbone.history.navigate(desiredRoute, {replace: true, trigger: true});
            _.defer(function() {
              options.callback && options.callback(desiredRoute, false);
            });
          } else {
            _.defer(step);
          }
        };
      }

      // General flow here is to try to do a back navigation and wait for a backbone event to trigger
      // If one does not within a given timeout then repeat.
      function step() {

        Backbone.history.back(function(fragment) {
          clearTimeout(timeout);

          var trigger = _.isFunction(options.trigger) ? options.trigger.apply(this, arguments) : options.trigger;
          if (trigger || !desiredRoute) {
            options.callback && _.defer(function() { options.callback(fragment, !!trigger); });
          }
          return trigger;
        });
      }

      step();
    }
  });

}());
<commit_msg>Put timeout back<commit_after>(function() {
  // cached super methods
  var _route = Backbone.History.prototype.route;
  var _getFragment = Backbone.History.prototype.getFragment;
  var _start = Backbone.History.prototype.start;
  var _checkUrl = Backbone.History.prototype.checkUrl;
  var _navigate = Backbone.History.prototype.navigate;
  var _extractParameters = Backbone.Router.prototype._extractParameters;

  // If we are in hash mode figure out if we are on a browser that is hit by 63777 and 85881
  //     https://bugs.webkit.org/show_bug.cgi?id=63777
  var _useReplaceState = /WebKit\/([\d.]+)/.exec(navigator.userAgent) && window.history.replaceState,

      // Some variants of android will not replace the location history properly, causing issues
      // on back navigation. Hack around the replace API making it two step for these cases.
      //
      // This is likely tied to a specific Webkit version but sticking to the environments that we
      // know this occurs in rather than trying to track down the webkit version that this might
      // be impacting and possibly getting it wrong.
      //    https://bugs.webkit.org/show_bug.cgi?id=85881
      _fakeReplace = /Android\s+([\d.]+)/.exec(navigator.userAgent) && (parseFloat(RegExp.$1) < 4.2);

  // pattern to recognize state index in hash
  var hashStrip = /^(?:#|%23)*\d*(?:#|%23)*/;
  // Cached regex for index extraction from the hash
  var indexMatch = /^(?:#|%23)*(\d+)(?:#|%23)/;

  _.extend(Backbone.Router.prototype, {
    // the direction index will be exposed on the parameters as 'direction'
    _extractParameters: function() {
      var params = _extractParameters.apply(this, arguments);
      params = params || [];
      var history = Backbone.history;
      if (history._trackDirection) {
        var oldIndex = history._directionIndex;
        history._directionIndex = history.loadIndex();
        params.direction = history._directionIndex - oldIndex;
      }
      return params;
    }
  });

  _.extend(Backbone.History.prototype, {
    // Get the location of the current route within the backbone history.
    // This should be considered a hint
    // Returns -1 if history is unknown or disabled
    getIndex : function() {
      return this._directionIndex;
    },

    getFragment : function(/* fragment, forcePushState */) {
      var rtn = _getFragment.apply(this, arguments);
      return rtn && rtn.replace(hashStrip, '');
    },

    start: function(/* options */) {
      var rtn = _start.apply(this, arguments);

      this._fakeReplace = _fakeReplace && !this.options.noReplaceHack;

      // Direction tracking setup
      this._trackDirection  = !!this.options.trackDirection;
      if (this._trackDirection) {
        var loadedIndex = this.loadIndex();
        this._directionIndex  = loadedIndex || window.history.length;
        this._state = {index: this._directionIndex};

        // If we are tracking direction ensure that we have a direction field to play with
        if (!loadedIndex) {
          var loc = window.location;
          if (!this._hasPushState) {
            loc.replace(loc.pathname + (loc.search || '') + '#' + this._directionIndex + '#' + this.fragment);
          } else {
            window.history.replaceState({index: this._directionIndex}, document.title, loc);
          }
        }
      }
      return rtn;
    },

    checkUrl : function(e) {
      var fromIframe = this.getFragment() == this.fragment && this.iframe;
      var loadedIndex = this.loadIndex(fromIframe && this.iframe.location.hash);
      var navigateOptions = {
        trigger: false,
        replace: !loadedIndex,
        forceIndex: loadedIndex || this._directionIndex + 1
      };
      _checkUrl.call(this, e, navigateOptions);
    },

    // The options object can contain `trigger: true` if you wish to have the
    // route callback be fired (not usually desirable), or `replace: true`, if
    // you wish to modify the current URL without adding an entry to the history.
    navigate: function(fragment, options) {
      if (this._ignoreChange) {
        this._pendingNavigate = _.bind(this.navigate, this, fragment, options);
        return;
      } else if (options && options.replace && this._fakeReplace) {
        // Under older Android environment we have to back out and then trigger a route in two
        // operations rather than an automic replace operation. Without this flow does not operate
        // correctly:
        //  1. Trigger #foo
        //  2. Replace #bar
        //  3. Trigger #baz
        //
        // This will trigger all of the proper routes but the history for this case will actually
        // be #foo, #baz rather than the desired #bar, #baz, causing unexpected navigation.
        options = _.omit(options, 'replace');
        options._replace = true;
        this._pendingNavigate = _.bind(this.navigate, this, fragment, options);
        this.back();
        return;
      }

      if (!options || options === true) {
        options = {trigger: options};
      }
      var newIndex;
      if (this._trackDirection) {
        newIndex = options.forceIndex || (this._directionIndex + (options.replace ? 0 : 1));

        if (options._replace) {
          // The step back mucked with our direction tracker. Update.
          this._directionIndex++;
        }
      }
      if (this._hasPushState) {
        options.state = {index: newIndex};
      } else {
        if (this._trackDirection) {
          fragment = newIndex + '#' + fragment;
        }
      }
      _navigate.call(this, fragment, options);
    },

    _updateHash: function(location, frag, replace) {
      var base = location.toString().replace(/(javascript:|#).*$/, '') + '#';
      if (replace) {
        if (_useReplaceState) {
          window.history.replaceState({}, document.title, base + frag);
        } else {
          location.replace(base + frag);
        }
      } else {
        location.hash = frag;
      }
    },

    // Pulls the direction index out of the state or hash
    loadIndex : function(fragmentOverride) {
      if (!this._trackDirection) {
        return;
      }
      if (!fragmentOverride && this._hasPushState) {
        return (this._state && this._state.index) || 0;
      } else {
        var match = indexMatch.exec(fragmentOverride || window.location.hash);
        return (match && parseInt(match[1], 10)) || 0;
      }
    },

    route: function (route, callback) {
      return _route.call(this, route, _.bind(function(fragment) {
        var ignore = this._ignoreChange;
        if (_.isFunction(ignore)) {
          ignore = !this._ignoreChange(fragment, route);
        }

        this._ignoreChange = false;

        if (ignore) {
          this._directionIndex = Backbone.history.loadIndex();
          var pendingNavigate = this._pendingNavigate;
          if (pendingNavigate) {
              var self = this;
            _.defer(function() {
              // back() was called before pendingNavigate and it could have updated
              // this.fragment to the same as pending navigate fragment. This will make
              // navigate a NOP. Hence resetting the fragment to make sure navigate will
              // do its job.
              self.fragment = undefined;
              pendingNavigate();
            });
          }
          this._pendingNavigate = undefined;
        } else {
          callback && callback.apply(this, arguments);
        }
      }, this));
    },

    back : function(triggerRoute) {
      this.go(-1, triggerRoute);
    },

    forward : function(triggerRoute) {
      this.go(1, triggerRoute);
    },

    go : function(count, triggerRoute) {
      this._ignoreChange = _.isFunction(triggerRoute) ? triggerRoute : !triggerRoute;

      // Explicitly use `back()` and `forward()` methods since `go(1)` and `go(-1)` may behave
      // unexpectedly in different browsers, although their behavior should be equivalent; see
      // the Chromium bugs https://code.google.com/p/chromium/issues/detail?id=241888 and
      // https://code.google.com/p/chromium/issues/detail?id=244434
      switch (count) {
        case -1:
          window.history.back();
          break;
        case 1:
          window.history.forward();
          break;
        default:
          window.history.go(count);
      }
    },

    /**
     * Hack to work around iframes that make have screwed with our history state.
     * Really one should choose not to use iframes but sometimes you must, even in 2013....
     */
    stepOut: function(options) {
      options = options || {};

      var stepLimit = options.stepLimit || 10,
          routeLimit,
          desiredRoute,
          iter = 0,
          timeout;

      if (options.view) {
        options.view.$('iframe').remove();
      }

      if (_.isString(options.trigger)) {
        // If a string is passed then we will ensure that they land on the desired route one way
        // or the other
        desiredRoute = options.trigger;
        routeLimit = options.routeLimit || 1;

        options.trigger = function(fragment) {
          routeLimit--;

          if (fragment === desiredRoute) {
            return true;
          } else if (routeLimit <= 0) {
            Backbone.history.navigate(desiredRoute, {replace: true, trigger: true});
            _.defer(function() {
              options.callback && options.callback(desiredRoute, false);
            });
          } else {
            _.defer(step);
          }
        };
      }

      // General flow here is to try to do a back navigation and wait for a backbone event to trigger
      // If one does not within a given timeout then repeat.
      function step() {
        iter++;

        // Timeout before as some envs actually have a sync callback for back. (Android 2.x notably)
        timeout = setTimeout(function() {
          if (iter > stepLimit) {
            options.callback && options.callback(false);
          } else {
            step();
          }
        }, 100);

        Backbone.history.back(function(fragment) {
          clearTimeout(timeout);

          var trigger = _.isFunction(options.trigger) ? options.trigger.apply(this, arguments) : options.trigger;
          if (trigger || !desiredRoute) {
            options.callback && _.defer(function() { options.callback(fragment, !!trigger); });
          }
          return trigger;
        });
      }

      step();
    }
  });

}());
<|endoftext|>


<commit_before>// Backbone.Validation v0.5.2
//
// Copyright (C)2011-2012 Thomas Pedersen
// Distributed under MIT License
//
// Documentation and full license available at:
// http://thedersen.github.com/backbone.validation
Backbone.Validation=function(a,b,c){var d={forceUpdate:!1,selector:"name"},e=function(a){return b.reduce(b.keys(a.validation),function(a,b){return a[b]=c,a},{})},f=function(c,d,e){var f=d[e]||{};return b.isFunction(f)?f:b.isString(f)?c[f]:(b.isArray(f)||(f=[f]),b.reduce(f,function(c,d){return b.each(b.without(b.keys(d),"msg"),function(b){c.push({fn:a.Validation.validators[b],val:d[b],msg:d.msg})}),c},[]))},g=function(a,c){return b.isObject(a)&&b.isObject(a[c])&&b.isObject(a[c].validation)},h=function(c,d,e,g,h){var i=f(c,d,e);return b.isFunction(i)?i.call(c,g,e,h):b.reduce(i,function(b,d){var f=d.fn.call(a.Validation.validators,g,e,d.val,c,h);return f===!1||b===!1?!1:f&&!b?d.msg||f:b},"")},i=function(a,c,d,e,f,j){if(!d)return!1;var k=!0,l;for(var m in c){l=h(a,c,m,a.get(m),e);if(b.isUndefined(d[m])&&l){k=!1;break}!l&&f&&j.valid(f,m,j.selector),l!==!1&&g(c,m)&&(k=i(a,c[m].validation,d[m],e))}return k},j=function(a,c,d,e,f,k){k=k||"";var l,m,n,o=[],p=[],q=!0,r=b.extend(c.toJSON(),e);for(n in e)m=h(c,d,n,e[n],r),m?(o.push(m),p.push(k+n),q=!1,a&&f.invalid(a,n,m,f.selector)):a&&f.valid(a,n,f.selector),m!==!1&&g(d,n)&&(l=j(a,c,d[n].validation,e[n],f,k+n+"."),Array.prototype.push.apply(o,l.errorMessages),Array.prototype.push.apply(p,l.invalidAttrs),q=q&&l.isValid);return q&&(q=i(c,d,e,r,a,f)),{errorMessages:o,invalidAttrs:p,isValid:q}},k=function(a,c){return{isValid:function(a){if(b.isString(a))return!h(this,this.validation,a,this.get(a),this.toJSON());if(b.isArray(a)){for(var c=0;c<a.length;c++)if(h(this,this.validation,a[c],this.get(a[c]),this.toJSON()))return!1;return!0}return a===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(d,f){var g=this,h=b.extend({},c,f);if(!d)return g.validate.call(g,b.extend(e(g),g.toJSON()));var i=j(a,g,g.validation,d,h);g._isValid=i.isValid,b.defer(function(){g.trigger("validated",g._isValid,g,i.invalidAttrs),g.trigger("validated:"+(g._isValid?"valid":"invalid"),g,i.invalidAttrs)});if(!h.forceUpdate&&i.errorMessages.length>0)return i.errorMessages}}},l=function(a,c,d){b.extend(c,k(a,d))},m=function(a){delete a.validate,delete a.isValid},n=function(a){l(this.view,a,this.options)},o=function(a){m(a)};return{version:"0.5.2",configure:function(a){b.extend(d,a)},bind:function(c,e){var f=c.model,g=c.collection,h=b.extend({},d,a.Validation.callbacks,e);f&&l(c,f,h),g&&(g.each(function(a){l(c,a,h)}),g.bind("add",n,{view:c,options:h}),g.bind("remove",o))},unbind:function(a){var b=a.model,c=a.collection;b&&m(a.model),c&&(c.each(function(a){m(a)}),c.unbind("add",n),c.unbind("remove",o))},mixin:k(null,d)}}(Backbone,_),Backbone.Validation.callbacks={valid:function(a,b,c){a.$("["+c+"~="+b+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(a,b,c,d){a.$("["+d+"~="+b+"]").addClass("invalid").attr("data-error",c)}},Backbone.Validation.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},Backbone.Validation.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be grater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}",object:"{0} must be an object"},Backbone.Validation.validators=function(a,b,c){var d=String.prototype.trim?function(a){return a===null?"":String.prototype.trim.call(a)}:function(a){var b=/^\s+/,c=/\s+$/;return a===null?"":a.toString().replace(b,"").replace(c,"")},e=function(){var a=Array.prototype.slice.call(arguments),b=a.shift();return b.replace(/\{(\d+)\}/g,function(b,c){return typeof a[c]!="undefined"?a[c]:b})},f=function(b){return c.isNumber(b)||c.isString(b)&&b.match(a.number)},g=function(a){return!(c.isNull(a)||c.isUndefined(a)||c.isString(a)&&d(a)==="")};return{fn:function(a,b,d,e,f){return c.isString(d)&&(d=e[d]),d.call(e,a,b,f)},required:function(a,d,f,h){var i=c.isFunction(f)?f.call(h):f;if(!i&&!g(a))return!1;if(i&&!g(a))return e(b.required,d)},acceptance:function(a,d){if(a!=="true"&&(!c.isBoolean(a)||a===!1))return e(b.acceptance,d)},min:function(a,c,d){if(!f(a)||a<d)return e(b.min,c,d)},max:function(a,c,d){if(!f(a)||a>d)return e(b.max,c,d)},range:function(a,c,d){if(!f(a)||a<d[0]||a>d[1])return e(b.range,c,d[0],d[1])},length:function(a,c,f){if(!g(a)||d(a).length!==f)return e(b.length,c,f)},minLength:function(a,c,f){if(!g(a)||d(a).length<f)return e(b.minLength,c,f)},maxLength:function(a,c,f){if(!g(a)||d(a).length>f)return e(b.maxLength,c,f)},rangeLength:function(a,c,f){if(!g(a)||d(a).length<f[0]||d(a).length>f[1])return e(b.rangeLength,c,f[0],f[1])},oneOf:function(a,d,f){if(!c.include(f,a))return e(b.oneOf,d,f.join(", "))},equalTo:function(a,c,d,f,g){if(a!==g[d])return e(b.equalTo,c,d)},pattern:function(c,d,f){if(!g(c)||!c.toString().match(a[f]||f))return e(b.pattern,d,f)},validation:function(a,d,f){if(!c.isObject(a))return e(b.object,d)}}}(Backbone.Validation.patterns,Backbone.Validation.messages,_);<commit_msg>Updated the minified version<commit_after>// Backbone.Validation v0.6.0
//
// Copyright (C)2011-2012 Thomas Pedersen
// Distributed under MIT License
//
// Documentation and full license available at:
// http://thedersen.com/projects/backbone-validation
(function(e,t){var n={forceUpdate:!1,selector:"name",labelFormatter:"sentenceCase",valid:Function.prototype,invalid:Function.prototype};e.Validation=function(){var e=function(e){return t.reduce(t.keys(e.validation||{}),function(e,t){return e[t]=void 0,e},{})},i=function(e,n){var r=e.validation?e.validation[n]||{}:{};return t.isFunction(r)?r:t.isString(r)?e[r]:(t.isArray(r)||(r=[r]),t.reduce(r,function(e,n){return t.each(t.without(t.keys(n),"msg"),function(t){e.push({fn:u[t],val:n[t],msg:n.msg})}),e},[]))},s=function(e,n,r,s){var o=i(e,n);return t.isFunction(o)?o.call(e,r,n,s):t.reduce(o,function(t,i){var o=i.fn.call(u,r,n,i.val,e,s);return o===!1||t===!1?!1:o&&!t?i.msg||o:t},"")},o=function(e,n){var r,i,o,u={},a=!0,f=t.clone(n);for(o in n)i=s(e,o,n[o],f),i&&(u[o]=i,a=!1);return{invalidAttrs:u,isValid:a}},a=function(n,r){return{preValidate:function(e,n){return s(this,e,n,t.extend({},this.attributes))},isValid:function(e){if(t.isString(e))return!s(this,e,this.get(e),t.extend({},this.attributes));if(t.isArray(e)){for(var n=0;n<e.length;n++)if(s(this,e[n],this.get(e[n]),t.extend({},this.attributes)))return!1;return!0}return e===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(i,s){var u=this,a=!i,f=t.extend({},r,s),l=t.extend(e(u),u.attributes,i),c=i||l,h=o(u,l);u._isValid=h.isValid;for(var p in l){var d=h.invalidAttrs.hasOwnProperty(p),v=c.hasOwnProperty(p);d&&(v||a)&&f.invalid(n,p,h.invalidAttrs[p],f.selector),d||f.valid(n,p,f.selector)}t.defer(function(){u.trigger("validated",u._isValid,u,h.invalidAttrs),u.trigger("validated:"+(u._isValid?"valid":"invalid"),u,h.invalidAttrs)});if(!f.forceUpdate&&t.intersection(t.keys(h.invalidAttrs),t.keys(c)).length>0)return h.invalidAttrs}}},f=function(e,n,r){t.extend(n,a(e,r))},l=function(e){delete e.validate,delete e.preValidate,delete e.isValid},c=function(e){f(this.view,e,this.options)},h=function(e){l(e)};return{version:"0.6.0",configure:function(e){t.extend(n,e)},bind:function(e,i){var s=e.model,o=e.collection;i=t.extend({},n,r,i),s&&f(e,s,i),o&&(o.each(function(t){f(e,t,i)}),o.bind("add",c,{view:e,options:i}),o.bind("remove",h))},unbind:function(e){var t=e.model,n=e.collection;t&&l(e.model),n&&(n.each(function(e){l(e)}),n.unbind("add",c),n.unbind("remove",h))},mixin:a(null,n)}}();var r=e.Validation.callbacks={valid:function(e,t,n){e.$("["+n+"~="+t+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(e,t,n,r){e.$("["+r+"~="+t+"]").addClass("invalid").attr("data-error",n)}},i=e.Validation.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},s=e.Validation.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be greater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}"},o=e.Validation.labelFormatters={none:function(e){return e},sentenceCase:function(e){return e.replace(/(?:^\w|[A-Z]|\b\w)/g,function(e,t){return t===0?e.toUpperCase():" "+e.toLowerCase()}).replace("_"," ")},label:function(e,t){return t.labels[e]||o.sentenceCase(e,t)}},u=e.Validation.validators=function(){var e=String.prototype.trim?function(e){return e===null?"":String.prototype.trim.call(e)}:function(e){var t=/^\s+/,n=/\s+$/;return e===null?"":e.toString().replace(t,"").replace(n,"")},r=function(e,t){return o[n.labelFormatter](e,t)},u=function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return t.replace(/\{(\d+)\}/g,function(t,n){return typeof e[n]!="undefined"?e[n]:t})},a=function(e){return t.isNumber(e)||t.isString(e)&&e.match(i.number)},f=function(n){return!(t.isNull(n)||t.isUndefined(n)||t.isString(n)&&e(n)==="")};return{fn:function(e,n,r,i,s){return t.isString(r)&&(r=i[r]),r.call(i,e,n,s)},required:function(e,n,i,o,a){var l=t.isFunction(i)?i.call(o,e,n,a):i;if(!l&&!f(e))return!1;if(l&&!f(e))return u(s.required,r(n,o))},acceptance:function(e,n,i,o){if(e!=="true"&&(!t.isBoolean(e)||e===!1))return u(s.acceptance,r(n,o))},min:function(e,t,n,i){if(!a(e)||e<n)return u(s.min,r(t,i),n)},max:function(e,t,n,i){if(!a(e)||e>n)return u(s.max,r(t,i),n)},range:function(e,t,n,i){if(!a(e)||e<n[0]||e>n[1])return u(s.range,r(t,i),n[0],n[1])},length:function(t,n,i,o){if(!f(t)||e(t).length!==i)return u(s.length,r(n,o),i)},minLength:function(t,n,i,o){if(!f(t)||e(t).length<i)return u(s.minLength,r(n,o),i)},maxLength:function(t,n,i,o){if(!f(t)||e(t).length>i)return u(s.maxLength,r(n,o),i)},rangeLength:function(t,n,i,o){if(!f(t)||e(t).length<i[0]||e(t).length>i[1])return u(s.rangeLength,r(n,o),i[0],i[1])},oneOf:function(e,n,i,o){if(!t.include(i,e))return u(s.oneOf,r(n,o),i.join(", "))},equalTo:function(e,t,n,i,o){if(e!==o[n])return u(s.equalTo,r(t,i),r(n,i))},pattern:function(e,t,n,o){if(!f(e)||!e.toString().match(i[n]||n))return u(s.pattern,r(t,o),n)}}}()})(Backbone,_);<|endoftext|>


<commit_before>/**
 * Created by ariela.ben.shalom on 1/20/2017.
 */

///////////////////////////////////////////

var Agent = function (game, x, y, speed, directionX, directionY) {

    ImageEntity.call(this, game, x, y, "agent_front");
    this.speed = speed;  // measured in pixels per tick
    this.directionX = directionX;
    this.directionY = directionY;
    this.currCell = Utils.locToTile(this.x, this.y);
    this.updateCounter = 0;
    this.converted = false;
}

Agent.prototype = Object.create(ImageEntity.prototype);
Agent.prototype.constructor = Agent;

////////////////// Mocks ///////////////////

Agent.prototype.GetCurrentStrategy = function(x, y, mosque) {
    var roads = Utils.getAdjacentRoads(Utils.locToTile(x, y));
    var directionX = 0;
    var directionY = 0;
    var target;
    if (roads.length) {

        target = roads[roads.length - 1];

    }
    if (mosque) {
        target = mosque;
    }

    if (target.x > x) {
        directionX = 1;
    }
    if (target.x < x) {
        directionX = -1;
    }
    if (target.y < y) {
        directionY = -1;
    }
    if (target.y > y) {
        directionY = 1;
    }

    return [directionX, directionY];

};

Agent.prototype.getNextCell = function(){
    if (this.directionY == 1){
       return {row: this.currCell.row+1, col:this.currCell.col}
    }

    if (this.directionY == -1){
        return {row: this.currCell.row-1, col:this.currCell.col}
    }
};

Agent.prototype.getCell = function () {
    return this.currCell
};

Agent.prototype.doTick = function (time) {
    this.updateCounter++;
    if (this.startedAnimation) {
        return;
    }

    if (this.died) {
        return;
    }
    var target;
    if (isInRange(this)) {
        target = isInRange(this);

        if (!this.added){
            this.added = true;
            this.addChild(game.make.sprite(-17, -28, "aura"));
        }
        this.converted = true;
        this.walkingTarget = target;
    }
    // Calc the new position

    var cellAfterMove = Utils.locToTile(this.x, this.y, true);

    if (cellAfterMove == null) {
        this.alpha = 0;
        this.died = true;
        this.game.levelState.lostAgents++;
        var sound = game.add.audio('giggle');
        sound.play();
        return;
    }

    cellAfterMove.row = Math.floor(cellAfterMove.row);
    cellAfterMove.col = Math.floor(cellAfterMove.col);

    if (((cellAfterMove.row != this.currCell.row) || (cellAfterMove.col != this.currCell.col) || this.updateCounter==1) && !this.converted) {
        // update cell
        var a = Utils.getRoadPossibilities({row:cellAfterMove.row, col:cellAfterMove.col});
        var b = this.getRealPossibilities(a, this.directionX, this.directionY);
        var dir = this.possibilitiesToDirection(b);
        if (dir){
            var agent = this;
            window.setTimeout(function(){
                agent.directionX = dir[0];
                agent.directionY = dir[1];
            }, 250);

        }

        this.currCell = cellAfterMove;

        // Change properties according to the forces of the new cell

    }
    if (this.converted){
        this.directionX = this.GetCurrentStrategy(this.x, this.y,target)[0];
        this.directionY = this.GetCurrentStrategy(this.x, this.y,target)[1];
    }

    if (this.converted){
        this.speed = 0.3;
    }

    this.x = this.x + (this.speed * this.directionX);
    this.y = this.y + (this.speed * this.directionY);

    if (this.converted && this.walkingTarget && this.getDistance(this.walkingTarget) < 30) {
        this.game.levelState.convertedAgents++;
        this.alpha = 0;
        var sound = game.add.audio('holy_sound');
        sound.play();
        this.died = true;
        // this.kill();
    }
};

Agent.prototype.getDistance = function(otherEntity) {
    return Math.sqrt(Math.pow(otherEntity.x - this.x, 2) + Math.pow(otherEntity.y - this.y, 2));
}

Agent.prototype.getRealPossibilities = function(myArray, directionX, directionY) {
    var possibilities = myArray.slice(0);
    if (directionX == -1){
        possibilities[1] = 7;
    }
    if (directionX == 1){
        possibilities[3] = 7;

    }

    if (directionY == -1){
        possibilities[2] = 7;
    }
    if (directionY == 1){
        possibilities[0] = 7;

    }
    return possibilities;
};

Agent.prototype.possibilitiesToDirection = function(possibilities){
    var allPossibilities = [];
    for (var i=0; i<possibilities.length; i++){
        if (possibilities[i]==7 || possibilities[i]==0){
            continue;
        }
        allPossibilities.push(i);
    }
    var i = allPossibilities[Math.floor(Math.random()*allPossibilities.length)];
    if (i==0){
        return [0,-1];
    }
    if (i==1){
        return [1,0];
    }
    if (i==2){
        return [0,1]
    }
    if (i==3){
        return [-1,0];
    }
};

<commit_msg>add direction resource to agent<commit_after>/**
 * Created by ariela.ben.shalom on 1/20/2017.
 */

///////////////////////////////////////////

var Agent = function (game, x, y, speed, directionX, directionY) {
    ImageEntity.call(this, game, x, y, "agent_front");
    this.speed = speed;  // measured in pixels per tick
    this.directionX = directionX;
    this.directionY = directionY;
    this.currCell = Utils.locToTile(this.x, this.y);
    this.updateCounter = 0;
    this.converted = false;
}

Agent.prototype = Object.create(ImageEntity.prototype);
Agent.prototype.constructor = Agent;

////////////////// Mocks ///////////////////

Agent.prototype.GetCurrentStrategy = function(x, y, mosque) {
    var roads = Utils.getAdjacentRoads(Utils.locToTile(x, y));
    var directionX = 0;
    var directionY = 0;
    var target;
    if (roads.length) {

        target = roads[roads.length - 1];

    }
    if (mosque) {
        target = mosque;
    }

    if (target.x > x) {
        directionX = 1;
    }
    if (target.x < x) {
        directionX = -1;
    }
    if (target.y < y) {
        directionY = -1;
    }
    if (target.y > y) {
        directionY = 1;
    }

    return [directionX, directionY];

};

Agent.prototype.getNextCell = function(){
    if (this.directionY == 1){
       return {row: this.currCell.row+1, col:this.currCell.col}
    }

    if (this.directionY == -1){
        return {row: this.currCell.row-1, col:this.currCell.col}
    }
};

Agent.prototype.getCell = function () {
    return this.currCell
};

Agent.prototype.doTick = function (time) {
    this.updateCounter++;
    if (this.startedAnimation) {
        return;
    }

    if (this.died) {
        return;
    }
    var target;
    if (isInRange(this)) {
        target = isInRange(this);

        if (!this.added){
            this.added = true;
            this.addChild(game.make.sprite(-17, -28, "aura"));
        }
        this.converted = true;
        this.walkingTarget = target;
    }
    // Calc the new position

    var cellAfterMove = Utils.locToTile(this.x, this.y, true);

    if (cellAfterMove == null) {
        this.alpha = 0;
        this.died = true;
        this.game.levelState.lostAgents++;
        var sound = game.add.audio('giggle');
        sound.play();
        return;
    }

    cellAfterMove.row = Math.floor(cellAfterMove.row);
    cellAfterMove.col = Math.floor(cellAfterMove.col);

    if (((cellAfterMove.row != this.currCell.row) || (cellAfterMove.col != this.currCell.col) || this.updateCounter==1) && !this.converted) {
        // update cell
        var a = Utils.getRoadPossibilities({row:cellAfterMove.row, col:cellAfterMove.col});
        var b = this.getRealPossibilities(a, this.directionX, this.directionY);
        var dir = this.possibilitiesToDirection(b);
        if (dir){
            var agent = this;
            window.setTimeout(function(){
                agent.directionX = dir[0];
                agent.directionY = dir[1];
            }, 250);

        }

        this.currCell = cellAfterMove;

        // Change properties according to the forces of the new cell

    }
    if (this.converted){
        this.directionX = this.GetCurrentStrategy(this.x, this.y,target)[0];
        this.directionY = this.GetCurrentStrategy(this.x, this.y,target)[1];
    }

    if (this.converted){
        this.speed = 0.3;
    }

    if (this.directionX == 1) {
        this.loadTexture('agent_right', 0);
    }
    if (this.directionX == -1) {
        this.loadTexture('agent_left', 0);
    }
    if (this.directionY == 1) {
        this.loadTexture('agent_front', 0);
    }
    if (this.directionY == -1){
        this.loadTexture('agent_back', 0);
    }

    this.x = this.x + (this.speed * this.directionX);
    this.y = this.y + (this.speed * this.directionY);

    if (this.converted && this.walkingTarget && this.getDistance(this.walkingTarget) < 30) {
        this.game.levelState.convertedAgents++;
        this.alpha = 0;
        var sound = game.add.audio('holy_sound');
        sound.play();
        this.died = true;
        // this.kill();
    }
};

Agent.prototype.getDistance = function(otherEntity) {
    return Math.sqrt(Math.pow(otherEntity.x - this.x, 2) + Math.pow(otherEntity.y - this.y, 2));
}

Agent.prototype.getRealPossibilities = function(myArray, directionX, directionY) {
    var possibilities = myArray.slice(0);
    if (directionX == -1){
        possibilities[1] = 7;
    }
    if (directionX == 1){
        possibilities[3] = 7;

    }

    if (directionY == -1){
        possibilities[2] = 7;
    }
    if (directionY == 1){
        possibilities[0] = 7;

    }
    return possibilities;
};

Agent.prototype.possibilitiesToDirection = function(possibilities){
    var allPossibilities = [];
    for (var i=0; i<possibilities.length; i++){
        if (possibilities[i]==7 || possibilities[i]==0){
            continue;
        }
        allPossibilities.push(i);
    }
    var i = allPossibilities[Math.floor(Math.random()*allPossibilities.length)];
    if (i==0){
        return [0,-1];
    }
    if (i==1){
        return [1,0];
    }
    if (i==2){
        return [0,1]
    }
    if (i==3){
        return [-1,0];
    }
};

<|endoftext|>