<commit_before>OMAR.models.CqlColumnDef = Backbone.Model.extend({
    idAttribute:"name",
    defaults:{
        name:"",
        label:"",
        type:"" // string, date, numeric, geom
    },
    initialize:function(params){

    }
});

OMAR.models.CqlRasterColumnDefCollection = Backbone.Collection.extend({
    model:OMAR.models.CqlColumnDef,
    initialize:function(params){
        this.add([
            {name:"be_number", label:"BE Number", type:"string"}
           ,{name:"class_name", label:"Class Name", type:"string"}
           ,{name:"country_code", label:"Country Code", type:"string"}
           ,{name:"file_type", label:"Class Name", type:"string"}
           ,{name:"filename", label:"Filename", type:"string"}
           ,{name:"image_id", label:"Image Id", type:"string"}
           ,{name:"mission", label:"Mission", type:"string"}
           ,{name:"niirs", label:"NIIRS", type:"numeric"}
           ,{name:"sensor_id", label:"Sensor Id", type:"string"}
           ,{name:"target_id", label:"Target Id", type:"string"}
           ,{name:"entry_id", label:"Entry Id", type:"string"}
           ,{name:"exclude_policy", label:"Exclude Policy", type:"string"}
           ,{name:"width", label:"Width", type:"numeric"}
           ,{name:"height", label:"Height", type:"numeric"}
           ,{name:"number_of_bands", label:"Number of Bands", type:"numeric"}
           ,{name:"number_of_res_levels", label:"Number of Res Levels", type:"numeric"}
           ,{name:"gsd_unit", label:"GSD Unit", type:"numeric"}
           ,{name:"gsd_x", label:"GSD X", type:"numeric"}
           ,{name:"gsd_y", label:"GSD Y", type:"numeric"}
           ,{name:"bit_depth", label:"Bit Depth", type:"numeric"}
           ,{name:"data_type", label:"Data Type", type:"string"}
           ,{name:"index_id", label:"Index Id", type:"string"}
           ,{name:"height", label:"Height", type:"numeric"}
           ,{name:"product_id", label:"Product Id", type:"string"}
           ,{name:"image_category", label:"Image Category", type:"string"}
           ,{name:"image_representation", label:"Image Representation", type:"string"}
           ,{name:"azimuth_angle", label:"Azimuth Angle", type:"numeric"}
           ,{name:"grazing_angle", label:"Grazing Angle", type:"numeric"}
           ,{name:"security_classification", label:"Security Classification", type:"string"}
           ,{name:"security_code", label:"Security Code", type:"string"}
           ,{name:"title", label:"Title", type:"string"}
           ,{name:"isorce", label:"Isource", type:"string"}
           ,{name:"organization", label:"Organization", type:"string"}
           ,{name:"description", label:"Description", type:"string"}
           ,{name:"organization", label:"Organization", type:"string"}
           ,{name:"wac_code", label:"Wac Code", type:"string"}
           ,{name:"sun_elevation", label:"Sun Elevation", type:"numeric"}
           ,{name:"sun_azimuth", label:"Sun Azimuth", type:"numeric"}
           ,{name:"cloud_cover", label:"Cloud Cover", type:"numeric"}
           ,{name:"style_id", label:"Style Id", type:"numeric"}
           ,{name:"keep_forever", label:"Keep Forever", type:"numeric"}
           ,{name:"ground_geom", label:"Ground Geom", type:"string"}
           ,{name:"acquisition_date", label:"Acquisition Date", type:"string"}
           ,{name:"valid_model", label:"Valid Model", type:"string"}
           ,{name:"access_date", label:"Access Date", type:"string"}
           ,{name:"ingest_date", label:"Ingest Date", type:"string"}
           ,{name:"receive_date", label:"Recieve Date", type:"string"}
           ,{name:"file_type", label:"File Type", type:"string"}
           ,{name:"other_tags_xml", label:"Other Tags XML", type:"string"}
        ]);
    }
});

OMAR.models.CqlModel = Backbone.Model.extend({
    idAttribute:"id",
    defaults:{
        id:"",
        name:"",
        cql:"",
        cqlState:""
    }
});

OMAR.models.CqlCollectionModel = Backbone.Collection.extend({
    url:"",
    model:OMAR.models.CqlModel,
    initialize:function(params){
    }
});

OMAR.views.CqlView = Backbone.View.extend({
    el:"#cqlId",
    initialize:function(params){
        this.setElement(this.el);
        this.idIncrement = 0;
        this.cqlBtnConditionEl = $(this.el).find("#cqlBtnCondition");
        this.cqlBtnQueryEl = $(this.el).find("#cqlBtnQuery");
        this.columnDefs = new OMAR.models.CqlRasterColumnDefCollection();

        $(this.cqlBtnConditionEl).click(this.cqlBtnConditionClicked.bind(this));
        $(this.cqlBtnQueryEl).click(this.cqlBtnQueryClicked.bind(this));

        this.rootCondition = '

<select><option value="and">And</option><option value="or">Or</option></select>	';
        this.rootCondition += '

 <button class="addroot">+()</button>
';
        this.rootCondition += '

';

        this.statement = '
'
    },
    getStatement:function(colId, opId){
        var idx    = 0;
        var result = "<select id='"+colId+"' class='col'>";

        for(idx = 0; idx < this.columnDefs.size();++idx)
        {
            var name  = this.columnDefs.at(idx).get("name");
            var label = this.columnDefs.at(idx).get("label");
            var html = "<option value='"+name+"'>"+label+"</option>";
            result += html;
        }
        result+="</select>";
        result+= "<select class='op' id='"+opId+"'>";
 //       result+= "<option value='<' >Less Than</option>";
        result+= "</select>";
        return (this.statement+result+"<input type='text'/>");
    },
    getTypesForColumn : function(col){

    },
    getCondition: function (rootsel) {
        //Get the columns from table (to find a clean way to do it later) //tbody>tr>td
        var elem = $(rootsel).children().children().children();
        //elem 0 is for operator, elem 1 is for expressions

        var q = {};
        var expressions = [];
        var nestedexpressions = [];

        var operator = $(elem[0]).find(':selected').val();
        q.operator = operator;

        // Get all the expressions in a condition
        var expressionelem = $(elem[1]).find('> .querystmts div');
        for (var i = 0; i < expressionelem.length; i++) {
            expressions[i] = {};
            var col = $(expressionelem[i]).find('.col :selected');
            var op = $(expressionelem[i]).find('.op :selected');
            expressions[i].colval = col.val();
            expressions[i].coldisp = col.text();
            expressions[i].opval = op.val();
            expressions[i].opdisp = op.text();
            expressions[i].val = $(expressionelem[i]).find(':text').val();
        }
        q.expressions = expressions;

        // Get all the nested expressions
        if ($(elem[1]).find('table').length != 0) {
            var len = $(elem[1]).find('table').length;

            for (var k = 0; k < len; k++) {
                nestedexpressions[k] = this.getCondition($(elem[1]).find('table')[k]);
            }
        }
        q.nestedexpressions = nestedexpressions;

        return q;
    },
    getQuery:function (condition)
    {
        var op = [' ', condition.operator, ' '].join('');

        var e = [];
        var elen = condition.expressions.length;
        for (var i = 0; i < elen; i++) {
            var expr = condition.expressions[i];

           // alert("WE CAN FORMAT AND VALIDATE HERE!" + this.columnDefs.get(expr.colval));
            // add tests for ops HERE!!
            //

            e.push(expr.colval + " " + expr.opval + " " + expr.val);
        }

        var n = [];
        var nlen = condition.nestedexpressions.length;
        for (var k = 0; k < nlen; k++) {
            var nestexpr = condition.nestedexpressions[k];
            var result = this.getQuery(nestexpr);
            n.push(result);
        }

        var q = [];
        if (e.length > 0)
            q.push(e.join(op));
        if (n.length > 0)
            q.push(n.join(op));

        return ['(', q.join(op), ')'].join(' ');
    },
    addQueryRoot:function (sel, isroot)
    {
        var thisPtr = this;

        $(sel).append(thisPtr.rootCondition);
        var q = $(sel).find('table');
        var l = q.length;
        var elem = q;
        if (l > 1) {
            elem = $(q[l - 1]);
        }

        //If root element remove the close image
        if (isroot) {
            elem.find('td >.remove').detach();
        }
        else {
            elem.find('td >.remove').click(function () {
                // td>tr>tbody>table
                $(this).parent().parent().parent().parent().detach();
            });
        }
        ++thisPtr.idIncrement;
        var opId = "op"+thisPtr.idIncrement;
        var colId = "col"+thisPtr.idIncrement;

        // Add the default staement segment to the root condition
        var appendedStatement = elem.find('td >.querystmts').append(this.getStatement(colId, opId));
        $(appendedStatement).find("#"+colId).change($.proxy(thisPtr.columnSelectorChanged, thisPtr, colId, opId)) ;
        // Add the head class to the first statement
        this.columnSelectorChanged(colId, opId);
        elem.find('td >.querystmts div >.remove').addClass('head');

        // Handle click for adding new statement segment
        // When a new statement is added add a condition to handle remove click.
        elem.find('td div >.add').click(function () {
            ++thisPtr.idIncrement;
            var opId2    = "op"+thisPtr.idIncrement;
            var colId2   = "col"+thisPtr.idIncrement;
            var appendedStatement = $(this).parent().siblings('.querystmts').append(thisPtr.getStatement(colId2, opId2));
            var colEl = $(appendedStatement).find("#"+colId2);
            this.columnSelectorChanged(colId2, opId2);
            $(colEl).change($.proxy(thisPtr.columnSelectorChanged, thisPtr, colId2, opId2)) ;

            var stmts = $(this).parent().siblings('.querystmts').find('div >.remove').filter(':not(.head)');
            stmts.unbind('click');
            stmts.click(function () {
                $(this).parent().detach();
            });
        });

        // Handle click to add new root condition
        elem.find('td div > .addroot').click(function () {
            thisPtr.addQueryRoot($(this).parent(), false);
        });
    },
    columnSelectorChanged:function(col, op){
       //alert($("#"+col)[0]);
        var columnName = $("#"+col).val();
        var op = $("#"+op);
        var row = this.columnDefs.get(columnName);
        if(row)
        {
            switch(row.get("type"))
            {
                case "string":
                    $(op).empty();
                    $(op).append("<option value='<' >Less Than</option>");
                    $(op).append("<option value='>' >Greater Than</option>");
                    $(op).append("<option value='=' >Equal</option>");
                    $(op).append("<option value='like' >Like</option>");
                    break;
                case "numeric":
                    $(op).empty();
                    $(op).append("<option value='<' >Less Than</option>");
                    $(op).append("<option value='>' >Greater Than</option>");
                    $(op).append("<option value='=' >Equal</option>");
                    break;
            }
        }
//        var op = $(this.el).find("#"+op);
//        $(op).empty();
    },
    cqlBtnConditionClicked:function(){
        var query = {};
        query = this.getCondition('.cqlQuery > table');
        //var l = JSON.stringify(query,null,4);
        var l = JSON.stringify(query);
        alert(l);

    },
    cqlBtnQueryClicked:function(){
        var con = this.getCondition('.cqlQuery >table');
        var k = this.getQuery(con);
        alert(k);
    },
    render:function(){
        this.addQueryRoot('.cqlQuery', true);
    }
});<commit_msg>Fixed the bug with initializing op drop down<commit_after>OMAR.models.CqlColumnDef = Backbone.Model.extend({
    idAttribute:"name",
    defaults:{
        name:"",
        label:"",
        type:"" // string, date, numeric, geom
    },
    initialize:function(params){

    }
});

OMAR.models.CqlRasterColumnDefCollection = Backbone.Collection.extend({
    model:OMAR.models.CqlColumnDef,
    initialize:function(params){
        this.add([
            {name:"be_number", label:"BE Number", type:"string"}
           ,{name:"class_name", label:"Class Name", type:"string"}
           ,{name:"country_code", label:"Country Code", type:"string"}
           ,{name:"file_type", label:"Class Name", type:"string"}
           ,{name:"filename", label:"Filename", type:"string"}
           ,{name:"image_id", label:"Image Id", type:"string"}
           ,{name:"mission", label:"Mission", type:"string"}
           ,{name:"niirs", label:"NIIRS", type:"numeric"}
           ,{name:"sensor_id", label:"Sensor Id", type:"string"}
           ,{name:"target_id", label:"Target Id", type:"string"}
           ,{name:"entry_id", label:"Entry Id", type:"string"}
           ,{name:"exclude_policy", label:"Exclude Policy", type:"string"}
           ,{name:"width", label:"Width", type:"numeric"}
           ,{name:"height", label:"Height", type:"numeric"}
           ,{name:"number_of_bands", label:"Number of Bands", type:"numeric"}
           ,{name:"number_of_res_levels", label:"Number of Res Levels", type:"numeric"}
           ,{name:"gsd_unit", label:"GSD Unit", type:"numeric"}
           ,{name:"gsd_x", label:"GSD X", type:"numeric"}
           ,{name:"gsd_y", label:"GSD Y", type:"numeric"}
           ,{name:"bit_depth", label:"Bit Depth", type:"numeric"}
           ,{name:"data_type", label:"Data Type", type:"string"}
           ,{name:"index_id", label:"Index Id", type:"string"}
           ,{name:"height", label:"Height", type:"numeric"}
           ,{name:"product_id", label:"Product Id", type:"string"}
           ,{name:"image_category", label:"Image Category", type:"string"}
           ,{name:"image_representation", label:"Image Representation", type:"string"}
           ,{name:"azimuth_angle", label:"Azimuth Angle", type:"numeric"}
           ,{name:"grazing_angle", label:"Grazing Angle", type:"numeric"}
           ,{name:"security_classification", label:"Security Classification", type:"string"}
           ,{name:"security_code", label:"Security Code", type:"string"}
           ,{name:"title", label:"Title", type:"string"}
           ,{name:"isorce", label:"Isource", type:"string"}
           ,{name:"organization", label:"Organization", type:"string"}
           ,{name:"description", label:"Description", type:"string"}
           ,{name:"organization", label:"Organization", type:"string"}
           ,{name:"wac_code", label:"Wac Code", type:"string"}
           ,{name:"sun_elevation", label:"Sun Elevation", type:"numeric"}
           ,{name:"sun_azimuth", label:"Sun Azimuth", type:"numeric"}
           ,{name:"cloud_cover", label:"Cloud Cover", type:"numeric"}
           ,{name:"style_id", label:"Style Id", type:"numeric"}
           ,{name:"keep_forever", label:"Keep Forever", type:"numeric"}
           ,{name:"ground_geom", label:"Ground Geom", type:"string"}
           ,{name:"acquisition_date", label:"Acquisition Date", type:"string"}
           ,{name:"valid_model", label:"Valid Model", type:"string"}
           ,{name:"access_date", label:"Access Date", type:"string"}
           ,{name:"ingest_date", label:"Ingest Date", type:"string"}
           ,{name:"receive_date", label:"Recieve Date", type:"string"}
           ,{name:"file_type", label:"File Type", type:"string"}
           ,{name:"other_tags_xml", label:"Other Tags XML", type:"string"}
        ]);
    }
});

OMAR.models.CqlModel = Backbone.Model.extend({
    idAttribute:"id",
    defaults:{
        id:"",
        name:"",
        cql:"",
        cqlState:""
    }
});

OMAR.models.CqlCollectionModel = Backbone.Collection.extend({
    url:"",
    model:OMAR.models.CqlModel,
    initialize:function(params){
    }
});

OMAR.views.CqlView = Backbone.View.extend({
    el:"#cqlId",
    initialize:function(params){
        this.setElement(this.el);
        this.idIncrement = 0;
        this.cqlBtnConditionEl = $(this.el).find("#cqlBtnCondition");
        this.cqlBtnQueryEl = $(this.el).find("#cqlBtnQuery");
        this.columnDefs = new OMAR.models.CqlRasterColumnDefCollection();

        $(this.cqlBtnConditionEl).click(this.cqlBtnConditionClicked.bind(this));
        $(this.cqlBtnQueryEl).click(this.cqlBtnQueryClicked.bind(this));

        this.rootCondition = '

<select><option value="and">And</option><option value="or">Or</option></select>	';
        this.rootCondition += '

 <button class="addroot">+()</button>
';
        this.rootCondition += '

';

        this.statement = '
'
    },
    getStatement:function(colId, opId){
        var idx    = 0;
        var result = "<select id='"+colId+"' class='col'>";

        for(idx = 0; idx < this.columnDefs.size();++idx)
        {
            var name  = this.columnDefs.at(idx).get("name");
            var label = this.columnDefs.at(idx).get("label");
            var html = "<option value='"+name+"'>"+label+"</option>";
            result += html;
        }
        result+="</select>";
        result+= "<select class='op' id='"+opId+"'>";
 //       result+= "<option value='<' >Less Than</option>";
        result+= "</select>";
        return (this.statement+result+"<input type='text'/>");
    },
    getTypesForColumn : function(col){

    },
    getCondition: function (rootsel) {
        //Get the columns from table (to find a clean way to do it later) //tbody>tr>td
        var elem = $(rootsel).children().children().children();
        //elem 0 is for operator, elem 1 is for expressions

        var q = {};
        var expressions = [];
        var nestedexpressions = [];

        var operator = $(elem[0]).find(':selected').val();
        q.operator = operator;

        // Get all the expressions in a condition
        var expressionelem = $(elem[1]).find('> .querystmts div');
        for (var i = 0; i < expressionelem.length; i++) {
            expressions[i] = {};
            var col = $(expressionelem[i]).find('.col :selected');
            var op = $(expressionelem[i]).find('.op :selected');
            expressions[i].colval = col.val();
            expressions[i].coldisp = col.text();
            expressions[i].opval = op.val();
            expressions[i].opdisp = op.text();
            expressions[i].val = $(expressionelem[i]).find(':text').val();
        }
        q.expressions = expressions;

        // Get all the nested expressions
        if ($(elem[1]).find('table').length != 0) {
            var len = $(elem[1]).find('table').length;

            for (var k = 0; k < len; k++) {
                nestedexpressions[k] = this.getCondition($(elem[1]).find('table')[k]);
            }
        }
        q.nestedexpressions = nestedexpressions;

        return q;
    },
    getQuery:function (condition)
    {
        var op = [' ', condition.operator, ' '].join('');

        var e = [];
        var elen = condition.expressions.length;
        for (var i = 0; i < elen; i++) {
            var expr = condition.expressions[i];

           // alert("WE CAN FORMAT AND VALIDATE HERE!" + this.columnDefs.get(expr.colval));
            // add tests for ops HERE!!
            //
            if(!expr.val) alert("NO VALUE");
            e.push(expr.colval + " " + expr.opval + " " + expr.val);
        }

        var n = [];
        var nlen = condition.nestedexpressions.length;
        for (var k = 0; k < nlen; k++) {
            var nestexpr = condition.nestedexpressions[k];
            var result = this.getQuery(nestexpr);
            n.push(result);
        }

        var q = [];
        if (e.length > 0)
            q.push(e.join(op));
        if (n.length > 0)
            q.push(n.join(op));

        return ['(', q.join(op), ')'].join(' ');
    },
    addQueryRoot:function (sel, isroot)
    {
        var thisPtr = this;

        $(sel).append(thisPtr.rootCondition);
        var q = $(sel).find('table');
        var l = q.length;
        var elem = q;
        if (l > 1) {
            elem = $(q[l - 1]);
        }

        //If root element remove the close image
        if (isroot) {
            elem.find('td >.remove').detach();
        }
        else {
            elem.find('td >.remove').click(function () {
                // td>tr>tbody>table
                $(this).parent().parent().parent().parent().detach();
            });
        }
        ++thisPtr.idIncrement;
        var opId = "op"+thisPtr.idIncrement;
        var colId = "col"+thisPtr.idIncrement;

        // Add the default staement segment to the root condition
        var appendedStatement = elem.find('td >.querystmts').append(this.getStatement(colId, opId));
        $(appendedStatement).find("#"+colId).change($.proxy(thisPtr.columnSelectorChanged, thisPtr, colId, opId)) ;
        // Add the head class to the first statement
        this.columnSelectorChanged(colId, opId);
        elem.find('td >.querystmts div >.remove').addClass('head');

        // Handle click for adding new statement segment
        // When a new statement is added add a condition to handle remove click.
        elem.find('td div >.add').click(function () {
            ++thisPtr.idIncrement;
            var opId2    = "op"+thisPtr.idIncrement;
            var colId2   = "col"+thisPtr.idIncrement;
            var appendedStatement = $(this).parent().siblings('.querystmts').append(thisPtr.getStatement(colId2, opId2));
            var colEl = $(appendedStatement).find("#"+colId2);
            thisPtr.columnSelectorChanged(colId2, opId2);
            $(colEl).change($.proxy(thisPtr.columnSelectorChanged, thisPtr, colId2, opId2)) ;

            var stmts = $(this).parent().siblings('.querystmts').find('div >.remove').filter(':not(.head)');
            stmts.unbind('click');
            stmts.click(function () {
                $(this).parent().detach();
            });
        });

        // Handle click to add new root condition
        elem.find('td div > .addroot').click(function () {
            thisPtr.addQueryRoot($(this).parent(), false);
        });
    },
    columnSelectorChanged:function(col, op){
       //alert($("#"+col)[0]);
        var columnName = $("#"+col).val();
        var op = $("#"+op);
        var row = this.columnDefs.get(columnName);
        if(row)
        {
            switch(row.get("type"))
            {
                case "string":
                    $(op).empty();
                    $(op).append("<option value='<' >Less Than</option>");
                    $(op).append("<option value='>' >Greater Than</option>");
                    $(op).append("<option value='=' >Equal</option>");
                    $(op).append("<option value='like' >Like</option>");
                    break;
                case "numeric":
                    $(op).empty();
                    $(op).append("<option value='<' >Less Than</option>");
                    $(op).append("<option value='>' >Greater Than</option>");
                    $(op).append("<option value='=' >Equal</option>");
                    break;
            }
        }
//        var op = $(this.el).find("#"+op);
//        $(op).empty();
    },
    cqlBtnConditionClicked:function(){
        var query = {};
        query = this.getCondition('.cqlQuery > table');
        //var l = JSON.stringify(query,null,4);
        var l = JSON.stringify(query);
        alert(l);

    },
    cqlBtnQueryClicked:function(){
        var con = this.getCondition('.cqlQuery >table');
        var k = this.getQuery(con);
        alert(k);
    },
    render:function(){
        this.addQueryRoot('.cqlQuery', true);
    }
});<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');

var formstream = require('formstream');
var util = require('./util');
var wrapper = util.wrapper;
var postJSON = util.postJSON;
var make = util.make;

/**
 * 上传Logo
 * Examples:
 * ```
 * api.uploadLogo('filepath', callback);
 * ```
 * Callback:
 *
 * - `err`, 调用失败时得到的异常
 * - `result`, 调用正常时得到的对象
 *
 * Result:
 * ```
 * {
 *  "errcode":0,
 *  "errmsg":"ok",
 *  "url":"http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0"
 * }
 * ```
 *
 * @name uploadLogo
 * @param {String} filepath 文件路径
 * @param {Function} callback 回调函数
 */
make(exports, 'uploadLogo', function (filepath, callback) {
  var that = this;
  fs.stat(filepath, function (err, stat) {
    if (err) {
      return callback(err);
    }
    var form = formstream();
    form.file('buffer', filepath, path.basename(filepath), stat.size);
    var url = that.fileServerPrefix + 'media/uploadimg?access_token=' + that.token.accessToken;
    var opts = {
      dataType: 'json',
      type: 'POST',
      timeout: 60000, // 60秒超时
      headers: form.headers(),
      stream: form
    };
    that.request(url, opts, wrapper(callback));
  });
});

/**
 * @name addLocations
 * @param {Array} locations 位置
 * @param {Function} callback 回调函数
 */
make(exports, 'addLocations', function (locations, callback) {
  var data = {
    location_list: locations
  };
  var url = 'https://api.weixin.qq.com/card/location/batchadd?access_token=' + this.token.accessToken;
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getLocations', function (offset, count, callback) {
  var data = {
    offset: offset,
    count: count
  };
  var url = 'https://api.weixin.qq.com/card/location/batchget?access_token=' + this.token.accessToken;
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getColors', function (callback) {
  var url = 'https://api.weixin.qq.com/card/getcolors?access_token=' + this.token.accessToken;
  this.request(url, {dataType: 'json'}, wrapper(callback));
});

make(exports, 'createCard', function (card, callback) {
  var url = 'https://api.weixin.qq.com/card/create?access_token=' + this.token.accessToken;
  var data = {card: card};
  this.request(url, postJSON(data), wrapper(callback));
});

exports.getRedirectUrl = function (url, encryptCode, cardId) {
  // TODO
};

make(exports, 'createQRCode', function (card, callback) {
  var url = 'https://api.weixin.qq.com/card/qrcode/create?access_token=' + this.token.accessToken;
  var data = {
    action_name: 'QR_CARD',
    action_info: {
      card: card
    }
  };
  this.request(url, postJSON(data), wrapper(callback));
});

/**
 * 创建用于投放的卡卷二维码，支持投放单张卡卷和多张卡卷
 * Examples:
 * ```
 * api.createCardQRCode('info', 'expire_seconds', callback);
 * ```
 * Callback:
 *
 * - `err`, 调用失败时得到的异常
 * - `result`, 调用正常时得到的对象
 *
 * Result:
 * ```
 * {
 *  "errcode": 0,
 *  "errmsg": "ok",
 *  "ticket":      "gQHB8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0JIV3lhX3psZmlvSDZmWGVMMTZvAAIEsNnKVQMEIAMAAA==",//获取ticket后需调用换取二维码接口获取二维码图片，详情见字段说明。
 *  "expire_seconds": 1800,
 *  "url": "http://weixin.qq.com/q/BHWya_zlfioH6fXeL16o ",
 *  "show_qrcode_url": " https://mp.weixin.qq.com/cgi-bin/showqrcode?  ticket=gQH98DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0czVzRlSWpsamlyM2plWTNKVktvAAIE6SfgVQMEgDPhAQ%3D%3D"
 *  }
 * ```
 *
 * @name createCardQRCode
 * @param {Object} info 卡卷信息，支持单张和多张模式
 * 二维码投放单张卡卷
 * ```
 * {
 *   "expire_seconds": 1800,
 *    "card": {
 *       "card_id": "pAtUNs1c3cBtMs5KeL8FP1f3fOaE"
 *     }
 * }
 * ```
 * ```
 * 二维码投放多张卡卷
 * {
 *   "expire_seconds": 1800,
 *    "multiple_card": {
 *       "card_list": [
 *           {
 *             "card_id": "pAtUNs-HV0evhGTWbU3ohp99tW7k"
 *           },
 *           {
 *             "card_id": "pAtUNs1c3cBtMs5KeL8FP1f3fOaE"
 *           }
 *       ]
 *   }
 * }
 * @param {number} expire_seconds 二维码的有效时间，范围是60 ~ 1800秒。不填默认为永久有效。
 * @param {Function} callback 回调函数
 */
make(exports, 'createCardQRCode', function (info, expire_seconds, callback) {
  if(typeof expire_seconds === 'function') {
    callback = expire_seconds;
    expire_seconds = null;
  }
  var url = 'https://api.weixin.qq.com/card/qrcode/create?access_token=' + this.token.accessToken;
  var data = {
    action_name: 'QR_'+Object.keys(info)[0].toUpperCase(),
    expire_seconds: expire_seconds,
    action_info: info
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'consumeCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/consume?access_token=' + this.token.accessToken;
  var data = {
    code: code,
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'decryptCode', function (encryptCode, callback) {
  var url = 'https://api.weixin.qq.com/card/code/decrypt?access_token=' + this.token.accessToken;
  var data = {
    encrypt_code: encryptCode
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'deleteCard', function (cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/delete?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/get?access_token=' + this.token.accessToken;
  var data = {
    code: code
  };
  if (typeof cardId !== 'function') {
    data.card_id = cardId;
  } else {
    callback = cardId;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCards', function (offset, count, status_list, callback) {
  var url = 'https://api.weixin.qq.com/card/batchget?access_token=' + this.token.accessToken;
  var data = {
    offset: offset,
    count: count
  };
  if (typeof status_list !== 'function') {
    data.status_list = status_list;
  } else {
    callback = status_list;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCard', function (cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/get?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCode', function (code, cardId, newcode, callback) {
  var url = 'https://api.weixin.qq.com/card/code/update?access_token=' + this.token.accessToken;
  var data = {
    code: code,
    card_id: cardId,
    newcode: newcode
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'unavailableCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/unavailable?access_token=' + this.token.accessToken;
  var data = {
    code: code
  };
  if (typeof cardId !== 'function') {
    data.card_id = cardId;
  } else {
    callback = cardId;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCard', function (cardId, cardInfo, callback) {
  var url = 'https://api.weixin.qq.com/card/update?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId,
    member_card: cardInfo
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCardStock', function (cardId, num, callback) {
  var url = 'https://api.weixin.qq.com/card/modifystock?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  if (num > 0) {
    data.increase_stock_value = Math.abs(num);
  } else {
    data.reduce_stock_value = Math.abs(num);
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'activateMembercard', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/membercard/activate?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateMembercard', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/membercard/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateMovieTicket', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/movieticket/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'checkInBoardingPass', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/boardingpass/checkin?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateLuckyMonkeyBalance', function (code, cardId, balance, callback) {
  var url = 'https://api.weixin.qq.com/card/luckymonkey/updateuserbalance?access_token=' + this.token.accessToken;
  var data = {
    "code": code,
    "card_id": cardId,
    "balance": balance
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateMeetingTicket', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/meetingticket/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'setTestWhitelist', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/testwhitelist/set?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});
<commit_msg>Customized codes<commit_after>var path = require('path');
var fs = require('fs');

var formstream = require('formstream');
var util = require('./util');
var wrapper = util.wrapper;
var postJSON = util.postJSON;
var make = util.make;

/**
 * 上传Logo
 * Examples:
 * ```
 * api.uploadLogo('filepath', callback);
 * ```
 * Callback:
 *
 * - `err`, 调用失败时得到的异常
 * - `result`, 调用正常时得到的对象
 *
 * Result:
 * ```
 * {
 *  "errcode":0,
 *  "errmsg":"ok",
 *  "url":"http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0"
 * }
 * ```
 *
 * @name uploadLogo
 * @param {String} filepath 文件路径
 * @param {Function} callback 回调函数
 */
make(exports, 'uploadLogo', function (filepath, callback) {
  var that = this;
  fs.stat(filepath, function (err, stat) {
    if (err) {
      return callback(err);
    }
    var form = formstream();
    form.file('buffer', filepath, path.basename(filepath), stat.size);
    var url = that.fileServerPrefix + 'media/uploadimg?access_token=' + that.token.accessToken;
    var opts = {
      dataType: 'json',
      type: 'POST',
      timeout: 60000, // 60秒超时
      headers: form.headers(),
      stream: form
    };
    that.request(url, opts, wrapper(callback));
  });
});

/**
 * @name addLocations
 * @param {Array} locations 位置
 * @param {Function} callback 回调函数
 */
make(exports, 'addLocations', function (locations, callback) {
  var data = {
    location_list: locations
  };
  var url = 'https://api.weixin.qq.com/card/location/batchadd?access_token=' + this.token.accessToken;
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getLocations', function (offset, count, callback) {
  var data = {
    offset: offset,
    count: count
  };
  var url = 'https://api.weixin.qq.com/card/location/batchget?access_token=' + this.token.accessToken;
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getColors', function (callback) {
  var url = 'https://api.weixin.qq.com/card/getcolors?access_token=' + this.token.accessToken;
  this.request(url, {dataType: 'json'}, wrapper(callback));
});

make(exports, 'createCard', function (card, callback) {
  var url = 'https://api.weixin.qq.com/card/create?access_token=' + this.token.accessToken;
  var data = {card: card};
  this.request(url, postJSON(data), wrapper(callback));
});

exports.getRedirectUrl = function (url, encryptCode, cardId) {
  // TODO
};

make(exports, 'createQRCode', function (card, callback) {
  var url = 'https://api.weixin.qq.com/card/qrcode/create?access_token=' + this.token.accessToken;
  var data = {
    action_name: 'QR_CARD',
    action_info: {
      card: card
    }
  };
  this.request(url, postJSON(data), wrapper(callback));
});

/**
 * 创建用于投放的卡卷二维码，支持投放单张卡卷和多张卡卷
 * Examples:
 * ```
 * api.createCardQRCode('info', 'expire_seconds', callback);
 * ```
 * Callback:
 *
 * - `err`, 调用失败时得到的异常
 * - `result`, 调用正常时得到的对象
 *
 * Result:
 * ```
 * {
 *  "errcode": 0,
 *  "errmsg": "ok",
 *  "ticket":      "gQHB8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0JIV3lhX3psZmlvSDZmWGVMMTZvAAIEsNnKVQMEIAMAAA==",//获取ticket后需调用换取二维码接口获取二维码图片，详情见字段说明。
 *  "expire_seconds": 1800,
 *  "url": "http://weixin.qq.com/q/BHWya_zlfioH6fXeL16o ",
 *  "show_qrcode_url": " https://mp.weixin.qq.com/cgi-bin/showqrcode?  ticket=gQH98DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0czVzRlSWpsamlyM2plWTNKVktvAAIE6SfgVQMEgDPhAQ%3D%3D"
 *  }
 * ```
 *
 * @name createCardQRCode
 * @param {Object} info 卡卷信息，支持单张和多张模式
 * 二维码投放单张卡卷
 * ```
 * {
 *   "expire_seconds": 1800,
 *    "card": {
 *       "card_id": "pAtUNs1c3cBtMs5KeL8FP1f3fOaE"
 *     }
 * }
 * ```
 * ```
 * 二维码投放多张卡卷
 * {
 *   "expire_seconds": 1800,
 *    "multiple_card": {
 *       "card_list": [
 *           {
 *             "card_id": "pAtUNs-HV0evhGTWbU3ohp99tW7k"
 *           },
 *           {
 *             "card_id": "pAtUNs1c3cBtMs5KeL8FP1f3fOaE"
 *           }
 *       ]
 *   }
 * }
 * @param {number} expire_seconds 二维码的有效时间，范围是60 ~ 1800秒。不填默认为永久有效。
 * @param {Function} callback 回调函数
 */
make(exports, 'createCardQRCode', function (info, expire_seconds, callback) {
  if(typeof expire_seconds === 'function') {
    callback = expire_seconds;
    expire_seconds = null;
  }
  var url = 'https://api.weixin.qq.com/card/qrcode/create?access_token=' + this.token.accessToken;
  var data = {
    action_name: 'QR_'+Object.keys(info)[0].toUpperCase(),
    expire_seconds: expire_seconds,
    action_info: info
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'consumeCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/consume?access_token=' + this.token.accessToken;
  var data = {
    code: code,
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'decryptCode', function (encryptCode, callback) {
  var url = 'https://api.weixin.qq.com/card/code/decrypt?access_token=' + this.token.accessToken;
  var data = {
    encrypt_code: encryptCode
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'deleteCard', function (cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/delete?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/get?access_token=' + this.token.accessToken;
  var data = {
    code: code
  };
  if (typeof cardId !== 'function') {
    data.card_id = cardId;
  } else {
    callback = cardId;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCards', function (offset, count, status_list, callback) {
  var url = 'https://api.weixin.qq.com/card/batchget?access_token=' + this.token.accessToken;
  var data = {
    offset: offset,
    count: count
  };
  if (typeof status_list !== 'function') {
    data.status_list = status_list;
  } else {
    callback = status_list;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'getCard', function (cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/get?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCode', function (code, cardId, newcode, callback) {
  var url = 'https://api.weixin.qq.com/card/code/update?access_token=' + this.token.accessToken;
  var data = {
    code: code,
    card_id: cardId,
    newcode: newcode
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'unavailableCode', function (code, cardId, callback) {
  var url = 'https://api.weixin.qq.com/card/code/unavailable?access_token=' + this.token.accessToken;
  var data = {
    code: code
  };
  if (typeof cardId !== 'function') {
    data.card_id = cardId;
  } else {
    callback = cardId;
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCard', function (cardId, cardInfo, callback) {
  var url = 'https://api.weixin.qq.com/card/update?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId,
    member_card: cardInfo
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateCardStock', function (cardId, num, callback) {
  var url = 'https://api.weixin.qq.com/card/modifystock?access_token=' + this.token.accessToken;
  var data = {
    card_id: cardId
  };
  if (num > 0) {
    data.increase_stock_value = Math.abs(num);
  } else {
    data.reduce_stock_value = Math.abs(num);
  }
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'activateMembercard', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/membercard/activate?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateMembercard', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/membercard/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateMovieTicket', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/movieticket/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'checkInBoardingPass', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/boardingpass/checkin?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'updateLuckyMonkeyBalance', function (code, cardId, balance, callback) {
  var url = 'https://api.weixin.qq.com/card/luckymonkey/updateuserbalance?access_token=' + this.token.accessToken;
  var data = {
    "code": code,
    "card_id": cardId,
    "balance": balance
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'updateMeetingTicket', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/meetingticket/updateuser?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'setTestWhitelist', function (info, callback) {
  var url = 'https://api.weixin.qq.com/card/testwhitelist/set?access_token=' + this.token.accessToken;
  this.request(url, postJSON(info), wrapper(callback));
});

make(exports, 'importCustomizedCodes', function (cardId, code, callback) {
  var url = 'https://api.weixin.qq.com/card/code/deposit?access_token=' + this.token.accessToken;
  var data = {
    "card_id": cardId,
    "code": code
  };
  this.request(url, postJSON(data), wrapper(callback));
});

make(exports, 'checkCustomizedCodes', function (cardId, code, callback) {
  var url = 'http://api.weixin.qq.com/card/code/checkcode?access_token=' + this.token.accessToken;
  var data = {
    "card_id": cardId,
    "code": code
  };
  this.request(url, postJSON(data), wrapper(callback));
});
<|endoftext|>


<commit_before>'use strict';

angular
  .module('fireideaz')
  .service('FirebaseService', ['$firebaseArray', function ($firebaseArray) {
    var firebaseUrl = 'https://blinding-torch-6662.firebaseio.com';

    function newFirebaseArray(messagesRef) {
      return $firebaseArray(messagesRef);
    }

    function getServerTimestamp() {
      return Firebase.ServerValue.TIMESTAMP;
    }

    function getMessagesRef(userId) {
      return new Firebase(firebaseUrl + '/messages/' + userId);
    }

    function getMessageRef(userId, messageId) {
      return new Firebase(firebaseUrl + '/messages/' + userId + '/' + messageId);
    }

    function getBoardRef(userId) {
      return new Firebase(firebaseUrl + '/boards/' + userId);
    }

    function getBoardColumns(userId) {
      return new Firebase(firebaseUrl + '/boards/' + userId + '/columns');
    }

    return {
      newFirebaseArray: newFirebaseArray,
      getServerTimestamp: getServerTimestamp,
      getMessagesRef: getMessagesRef,
      getMessageRef: getMessageRef,
      getBoardRef: getBoardRef,
      getBoardColumns: getBoardColumns
    };
  }]);
<commit_msg>Firebase stuff<commit_after>'use strict';

angular
  .module('fireideaz')
  .service('FirebaseService', ['$firebaseArray', function ($firebaseArray) {
    var firebaseUrl = 'https://funretro-20519.firebaseio.com/';

    function newFirebaseArray(messagesRef) {
      return $firebaseArray(messagesRef);
    }

    function getServerTimestamp() {
      return Firebase.ServerValue.TIMESTAMP;
    }

    function getMessagesRef(userId) {
      return new Firebase(firebaseUrl + '/messages/' + userId);
    }

    function getMessageRef(userId, messageId) {
      return new Firebase(firebaseUrl + '/messages/' + userId + '/' + messageId);
    }

    function getBoardRef(userId) {
      return new Firebase(firebaseUrl + '/boards/' + userId);
    }

    function getBoardColumns(userId) {
      return new Firebase(firebaseUrl + '/boards/' + userId + '/columns');
    }

    return {
      newFirebaseArray: newFirebaseArray,
      getServerTimestamp: getServerTimestamp,
      getMessagesRef: getMessagesRef,
      getMessageRef: getMessageRef,
      getBoardRef: getBoardRef,
      getBoardColumns: getBoardColumns
    };
  }]);
<|endoftext|>


<commit_before>import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import ReactDOM from 'react-dom';

import Button from './../../src/components/Button';
import { BUTTON_WARNING_LABEL_MISSING } from './../../src/components/Button';

describe('<Button>', () => {
  it('Should be element type button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    let el = ReactDOM.findDOMNode(instance);
    expect(el.nodeName).equal('A');
  });

  it('Should default prop type be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.type).equal(Button.DEFAULT);
  });

  it('Should default prop title be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.title).equal(BUTTON_WARNING_LABEL_MISSING);
  });

    it('Should default prop class be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.cn).equal(' btn-default');
  });

  it('Should be "trash" button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.TRASH} />
    );

    expect(instance.props.type).equal(Button.TRASH);

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'span');
    expect(el.getAttribute('class')).contain('glyphicon');
    expect(el.getAttribute('class')).contain('glyphicon-trash');
  });

  it('Should be "edit" button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.EDIT} />
    );

    expect(instance.props.type).equal(Button.EDIT);

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'span');
    expect(el.getAttribute('class')).contain('glyphicon');
    expect(el.getAttribute('class')).contain('glyphicon-pencil');
  });

  it('Should be "new item" button', () => {
    const label = 'Add new item';

    let instance = ReactTestUtils.renderIntoDocument(
      <Button title={label} />
    );

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'a');
    expect(el.textContent).equal(label);
  });

  it('Should be capture onClick event on TRASH button', (done) => {
    let onClick = () => {
      done();
    };

    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.TRASH} onClick={onClick}/>
    );

    ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance));
  });

  it('Should be capture onClick event on TRASH button', (done) => {
    let onClick = () => {
      done();
    };

    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.EDIT} onClick={onClick}/>
    );

    ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance));
  });
});
<commit_msg>pointless test<commit_after>import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import ReactDOM from 'react-dom';

import Button from './../../src/components/Button';
import { BUTTON_WARNING_LABEL_MISSING } from './../../src/components/Button';

describe('<Button>', () => {
  it('Should be element type button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    let el = ReactDOM.findDOMNode(instance);
    expect(el.nodeName).equal('A');
  });

  it('Should default prop type be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.type).equal(Button.DEFAULT);
  });

  it('Should default prop title be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.title).equal(BUTTON_WARNING_LABEL_MISSING);
  });

    it('Should default prop class be correct', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button />
    );

    expect(instance.props.cn).equal(' btn-default');
  });

  it('Should be "trash" button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.TRASH} />
    );

    expect(instance.props.type).equal(Button.TRASH);

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'span');
    expect(el.getAttribute('class')).contain('glyphicon');
    expect(el.getAttribute('class')).contain('glyphicon-trash');
  });

  it('Should be "edit" button', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.EDIT} />
    );

    expect(instance.props.type).equal(Button.EDIT);

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'span');
    expect(el.getAttribute('class')).contain('glyphicon');
    expect(el.getAttribute('class')).contain('glyphicon-pencil');
  });

  it('Should be "new item" button', () => {
    const label = 'Add new item';

    let instance = ReactTestUtils.renderIntoDocument(
      <Button title={label} />
    );

    let el = ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'a');
    expect(el.textContent).equal(label);
  });

  it('Should be capture onClick event on TRASH button', (done) => {
    let onClick = () => {
      done();
    };

    let instance = ReactTestUtils.renderIntoDocument(
      <Button type={Button.TRASH} onClick={onClick}/>
    );

    ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance));
  });

});
<|endoftext|>


<commit_before>import React from 'react';

import SPELLS from 'common/SPELLS';
import { formatPercentage } from 'common/format';
import SpellLink from 'common/SpellLink';

import StatisticBox, { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import STATISTIC_CATEGORY from 'interface/others/STATISTIC_CATEGORY';
import ItemHealingDone from 'interface/others/ItemHealingDone';
import UptimeIcon from 'interface/icons/Uptime';

import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import Events from 'parser/core/Events';
import Combatants from 'parser/shared/modules/Combatants';
import calculateEffectiveHealing from 'parser/core/calculateEffectiveHealing';

import { HEALING_ABILITIES_AMPED_BY_EARTH_SHIELD } from '../constants';

const EARTHSHIELD_HEALING_INCREASE = 0.10;

class EarthShield extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };
  healing = 0;
  buffHealing = 0;

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTalent(SPELLS.EARTH_SHIELD_TALENT.id);

    // event listener for direct heals when taking damage with earth shield
    this.addEventListener(Events.heal.by(SELECTED_PLAYER).spell(SPELLS.EARTH_SHIELD_HEAL), this.onEarthShieldHeal);

    // event listener for healing being buffed by having earth shield on the target
    HEALING_ABILITIES_AMPED_BY_EARTH_SHIELD.forEach((spell) => {
      this.addEventListener(Events.heal.by(SELECTED_PLAYER).spell(spell), this.onEarthShieldAmpSpellHeal);
    });
  }

  get uptime() {
    return Object.keys(this.combatants.players)
      .map(key => this.combatants.players[key])
      .reduce((uptime, player) =>
        uptime + player.getBuffUptime(SPELLS.EARTH_SHIELD_TALENT.id), 0);
  }

  get uptimePercent() {
    return this.uptime / this.owner.fightDuration;
  }

  get suggestionThresholds() {
    return {
      actual: this.uptimePercent,
      isLessThan: {
        minor: 0.95,
        average: 0.90,
        major: 0.80,
      },
      style: 'percentage',
    };
  }

  onEarthShieldHeal(event) {
    this.healing += (event.amount + (event.absorbed || 0));
  }

  onEarthShieldAmpSpellHeal(event) {
    const combatant = this.combatants.players[event.targetID];
    if (combatant && combatant.hasBuff(SPELLS.EARTH_SHIELD_TALENT.id, event.timestamp)) {
      console.log(event);
      this.buffHealing += calculateEffectiveHealing(event, EARTHSHIELD_HEALING_INCREASE);
    }
  }

  statistic() {
    return (
      <StatisticBox
        label={<SpellLink id={SPELLS.EARTH_SHIELD_TALENT.id} />}
        category={STATISTIC_CATEGORY.TALENTS}
        position={STATISTIC_ORDER.OPTIONAL(45)}
        tooltip={`${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.healing))}% from the HoT and ${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.buffHealing))}% from the healing amp.`}
        value={
          (

              <UptimeIcon /> {formatPercentage(this.uptimePercent)}% uptime

              <ItemHealingDone amount={this.healing + this.buffHealing} />

          )
        }
      />
    );
  }
}

export default EarthShield;
<commit_msg>PR comments<commit_after>import React from 'react';

import SPELLS from 'common/SPELLS';
import { formatPercentage } from 'common/format';
import SpellLink from 'common/SpellLink';

import StatisticBox, { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import STATISTIC_CATEGORY from 'interface/others/STATISTIC_CATEGORY';
import ItemHealingDone from 'interface/others/ItemHealingDone';
import UptimeIcon from 'interface/icons/Uptime';

import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import Events from 'parser/core/Events';
import Combatants from 'parser/shared/modules/Combatants';
import calculateEffectiveHealing from 'parser/core/calculateEffectiveHealing';

import { HEALING_ABILITIES_AMPED_BY_EARTH_SHIELD } from '../constants';

const EARTHSHIELD_HEALING_INCREASE = 0.10;

class EarthShield extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };
  healing = 0;
  buffHealing = 0;

  constructor(...args) {
    super(...args);
    this.active = this.selectedCombatant.hasTalent(SPELLS.EARTH_SHIELD_TALENT.id);

    // event listener for direct heals when taking damage with earth shield
    this.addEventListener(Events.heal.by(SELECTED_PLAYER).spell(SPELLS.EARTH_SHIELD_HEAL), this.onEarthShieldHeal);

    // event listener for healing being buffed by having earth shield on the target
    HEALING_ABILITIES_AMPED_BY_EARTH_SHIELD.forEach((spell) => {
      this.addEventListener(Events.heal.by(SELECTED_PLAYER).spell(spell), this.onEarthShieldAmpSpellHeal);
    });
  }

  get uptime() {
    return Object.keys(this.combatants.players)
      .map(key => this.combatants.players[key])
      .reduce((uptime, player) =>
        uptime + player.getBuffUptime(SPELLS.EARTH_SHIELD_TALENT.id), 0);
  }

  get uptimePercent() {
    return this.uptime / this.owner.fightDuration;
  }

  get suggestionThresholds() {
    return {
      actual: this.uptimePercent,
      isLessThan: {
        minor: 0.95,
        average: 0.90,
        major: 0.80,
      },
      style: 'percentage',
    };
  }

  onEarthShieldHeal(event) {
    this.healing += (event.amount + (event.absorbed || 0));
  }

  onEarthShieldAmpSpellHeal(event) {
    const combatant = this.combatants.players[event.targetID];
    if (combatant && combatant.hasBuff(SPELLS.EARTH_SHIELD_TALENT.id, event.timestamp)) {
      this.buffHealing += calculateEffectiveHealing(event, EARTHSHIELD_HEALING_INCREASE);
    }
  }

  statistic() {
    return (
      <StatisticBox
        label={<SpellLink id={SPELLS.EARTH_SHIELD_TALENT.id} />}
        category={STATISTIC_CATEGORY.TALENTS}
        position={STATISTIC_ORDER.OPTIONAL(45)}
        tooltip={`${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.healing))}% from the HoT and ${formatPercentage(this.owner.getPercentageOfTotalHealingDone(this.buffHealing))}% from the healing increase.`}
        value={
          (

              <UptimeIcon /> {formatPercentage(this.uptimePercent)}% uptime

              <ItemHealingDone amount={this.healing + this.buffHealing} />

          )
        }
      />
    );
  }
}

export default EarthShield;
<|endoftext|>


<commit_before>// Authentication module.
const auth = require('http-auth');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const https = require('https');

const argv = require('yargs')
  .usage('Usage: $0 -p [integer for non-HTTPS port] -i [string of IP address] -s [integer for HTTPS port]')
  .default("p", 4000)
  .default("s", 443)
  .default("i", '')
  .alias('p', 'port')
  .alias('s', 'https')
  .alias('i', 'ip').alias('i', 'ip-address')
  .describe('p', 'Port to run server on')
  .describe('i', 'IP Address to run server on')
  .describe('s', 'Port to run HTTPS server on')
  .help('h')
  .alias('h', 'help')
  .argv;

const path = require('path');
const fs = require('fs-extra');

const basic = auth.basic({
      file: path.join(__dirname, "admin-data", "users.htpasswd") // englewood-admin | helpthesekids
    }
);

// Application setup.
const app = express();
const admin = express();

function initHttps () {
  try {
    const credentials = {
      key: fs.readFileSync('../evl2017/_.evl.uic.edu.key', 'utf8'),
      cert: fs.readFileSync('../evl2017/_.evl.uic.edu.crt', 'utf8'),
    };
    const httpsServer = https.createServer(credentials, app);
    if (argv.ip.length > 0) {
      httpsServer.listen(argv.https, argv.ip, function () {
        console.log("HTTPS Listening on " + this.address().address + ":" + this.address().port);
      });
    } else {
      httpsServer.listen(argv.https, function () {
        console.log("HTTPS Listening on " + this.address().address + ":" + this.address().port);
      });
    }
    return httpsServer;
  } catch (err) {
    console.log('error initializing HTTPS');
    console.log(err);
  }
}

// enable cors
app.use(cors({ origin: '*' }));

admin.use(bodyParser.json());
admin.use(auth.connect(basic));

app.use('/admin', admin);
app.use(express.static("./"));

if(argv.ip.length > 0){
  app.listen(argv.port,argv.ip, function () {
    // console.log('Example app listening on port 4000!')
    console.log("Listening on " + this.address().address + ":" + this.address().port);
  });
}else{
  app.listen(argv.port, function () {
    // console.log('Example app listening on port 4000!')
    console.log("Listening on " + this.address().address + ":" + this.address().port);
  });
}

admin.get('/getlog', (req, res) => {
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
});

admin.put('/savenew', (req, res) => {
  addNewFile(req.body.data, req.body.name, res);
});

admin.put('/chooseold', (req, res) => {

  changeUsedFile(req.body.time, req.body.name, res);
});

function addNewFile(data, fileName, res) {
  let time = Date.now();
  // write as new file to use
  fs.writeFileSync(path.join(__dirname, "admin-data", "EnglewoodLocations.csv"), data);

  // write archiving version, also
  fs.writeFileSync(path.join(__dirname, "admin-data", "archive-data", (time + fileName)), data);

  // parse CSV
  let log = (fs.readFileSync(path.join(__dirname, "admin-data", "LOG.csv")).toString()).split("\n").map(entry => entry.split(","));
  // set existing entries to false
  log.forEach((entry) => { entry[2] = false });
  // join log entries together
  let clearedLog = log.map((entry) => entry.join(","));
  // add new entry
  clearedLog.push(`${time},${fileName},true`);

  // join back into csv string
  let logString = clearedLog.join("\n");

  // write updated log
  fs.writeFileSync(path.join(__dirname, "admin-data", "LOG.csv"), logString);
  // send updated log as response
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
}

function changeUsedFile(timestamp, fileName, res) {
  let time = new Date(+timestamp).getTime();

  // parse CSV
  let log = (fs.readFileSync(path.join(__dirname, "admin-data", "LOG.csv")).toString()).split("\n").map(entry => entry.split(","));
  // update entries to reflect choice
  log.forEach((entry) => { entry[2] = (entry[0] == timestamp && entry[1] == fileName); });

  // copy subversion over to active data directory
  fs.copySync(path.join(__dirname, "admin-data", "archive-data", (timestamp + fileName)), path.join(__dirname, "admin-data", "EnglewoodLocations.csv"));

  // write updated log file
  fs.writeFileSync(path.join(__dirname, "admin-data", "LOG.csv"), log.map(entry => entry.join(',')).join("\n"));
  // send updated log as response
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
}

initHttps();
<commit_msg>Added ca for https credentials<commit_after>// Authentication module.
const auth = require('http-auth');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const https = require('https');

const argv = require('yargs')
  .usage('Usage: $0 -p [integer for non-HTTPS port] -i [string of IP address] -s [integer for HTTPS port]')
  .default("p", 4000)
  .default("s", 443)
  .default("i", '')
  .alias('p', 'port')
  .alias('s', 'https')
  .alias('i', 'ip').alias('i', 'ip-address')
  .describe('p', 'Port to run server on')
  .describe('i', 'IP Address to run server on')
  .describe('s', 'Port to run HTTPS server on')
  .help('h')
  .alias('h', 'help')
  .argv;

const path = require('path');
const fs = require('fs-extra');

const basic = auth.basic({
      file: path.join(__dirname, "admin-data", "users.htpasswd") // englewood-admin | helpthesekids
    }
);

// Application setup.
const app = express();
const admin = express();

function initHttps () {
  try {
    const credentials = {
      key: fs.readFileSync('../evl2017/_.evl.uic.edu.key', 'utf8'),
      cert: fs.readFileSync('../evl2017/_.evl.uic.edu.crt', 'utf8'),
      ca: fs.readFileSync('../evl2017/_.evl.uic.edu-ca.crt', 'utf8'),
    };
    const httpsServer = https.createServer(credentials, app);
    if (argv.ip.length > 0) {
      httpsServer.listen(argv.https, argv.ip, function () {
        console.log("HTTPS Listening on " + this.address().address + ":" + this.address().port);
      });
    } else {
      httpsServer.listen(argv.https, function () {
        console.log("HTTPS Listening on " + this.address().address + ":" + this.address().port);
      });
    }
    return httpsServer;
  } catch (err) {
    console.log('error initializing HTTPS');
    console.log(err);
  }
}

// enable cors
app.use(cors({ origin: '*' }));

admin.use(bodyParser.json());
admin.use(auth.connect(basic));

app.use('/admin', admin);
app.use(express.static("./"));

if(argv.ip.length > 0){
  app.listen(argv.port,argv.ip, function () {
    // console.log('Example app listening on port 4000!')
    console.log("Listening on " + this.address().address + ":" + this.address().port);
  });
}else{
  app.listen(argv.port, function () {
    // console.log('Example app listening on port 4000!')
    console.log("Listening on " + this.address().address + ":" + this.address().port);
  });
}

admin.get('/getlog', (req, res) => {
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
});

admin.put('/savenew', (req, res) => {
  addNewFile(req.body.data, req.body.name, res);
});

admin.put('/chooseold', (req, res) => {

  changeUsedFile(req.body.time, req.body.name, res);
});

function addNewFile(data, fileName, res) {
  let time = Date.now();
  // write as new file to use
  fs.writeFileSync(path.join(__dirname, "admin-data", "EnglewoodLocations.csv"), data);

  // write archiving version, also
  fs.writeFileSync(path.join(__dirname, "admin-data", "archive-data", (time + fileName)), data);

  // parse CSV
  let log = (fs.readFileSync(path.join(__dirname, "admin-data", "LOG.csv")).toString()).split("\n").map(entry => entry.split(","));
  // set existing entries to false
  log.forEach((entry) => { entry[2] = false });
  // join log entries together
  let clearedLog = log.map((entry) => entry.join(","));
  // add new entry
  clearedLog.push(`${time},${fileName},true`);

  // join back into csv string
  let logString = clearedLog.join("\n");

  // write updated log
  fs.writeFileSync(path.join(__dirname, "admin-data", "LOG.csv"), logString);
  // send updated log as response
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
}

function changeUsedFile(timestamp, fileName, res) {
  let time = new Date(+timestamp).getTime();

  // parse CSV
  let log = (fs.readFileSync(path.join(__dirname, "admin-data", "LOG.csv")).toString()).split("\n").map(entry => entry.split(","));
  // update entries to reflect choice
  log.forEach((entry) => { entry[2] = (entry[0] == timestamp && entry[1] == fileName); });

  // copy subversion over to active data directory
  fs.copySync(path.join(__dirname, "admin-data", "archive-data", (timestamp + fileName)), path.join(__dirname, "admin-data", "EnglewoodLocations.csv"));

  // write updated log file
  fs.writeFileSync(path.join(__dirname, "admin-data", "LOG.csv"), log.map(entry => entry.join(',')).join("\n"));
  // send updated log as response
  res.sendFile(path.join(__dirname, "admin-data", "LOG.csv"));
}

initHttps();
<|endoftext|>


<commit_before>var searchbar = require('searchbar/searchbar.js')
var webviews = require('webviews.js')
var modalMode = require('modalMode.js')
var urlParser = require('util/urlParser.js')
var bookmarkStar = require('navbar/bookmarkStar.js')

const tabEditor = {
  container: document.getElementById('tab-editor'),
  input: document.getElementById('tab-editor-input'),
  star: null,
  show: function (tabId, editingValue, showSearchbar) {
    /* Edit mode is not available in modal mode. */
    if (modalMode.enabled()) {
      return
    }

    tabEditor.container.hidden = false

    bookmarkStar.update(tabId, tabEditor.star)

    webviews.requestPlaceholder('editMode')

    document.body.classList.add('is-edit-mode')

    var currentURL = urlParser.getSourceURL(tabs.get(tabId).url)
    if (currentURL === 'min://newtab') {
      currentURL = ''
    }

    tabEditor.input.value = editingValue || currentURL
    tabEditor.input.focus()
    if (!editingValue) {
      tabEditor.input.select()
    }

    searchbar.show(tabEditor.input)

    if (showSearchbar !== false) {
      if (editingValue) {
        searchbar.showResults(editingValue, null)
      } else {
        searchbar.showResults('', null)
      }
    }

    /* animation */
    if (tabs.count() > 1) {
      requestAnimationFrame(function () {

        var item = document.querySelector(`.tab-item[data-tab="${tabId}"]`)
        var originCoordinates = item.getBoundingClientRect()

        var finalCoordinates = document.querySelector('#tabs').getBoundingClientRect()

        var translateX = Math.min(Math.round(originCoordinates.x - finalCoordinates.x) * 0.5, window.innerWidth)

        tabEditor.container.style.opacity = 0
        tabEditor.container.style.transform = `translateX(${translateX}px)`
        requestAnimationFrame(function () {
          tabEditor.container.style.transition = '0.15s all'
          tabEditor.container.style.opacity = 1
          tabEditor.container.style.transform = ''
        })
      })
    }
  },
  hide: function () {
    tabEditor.container.hidden = true
    tabEditor.container.removeAttribute('style')

    tabEditor.input.blur()
    searchbar.hide()

    document.body.classList.remove('is-edit-mode')

    webviews.hidePlaceholder('editMode')
  },
  initialize: function () {
    tabEditor.input.setAttribute('placeholder', l('searchbarPlaceholder'))

    tabEditor.star = bookmarkStar.create()
    tabEditor.container.appendChild(tabEditor.star)

    tabEditor.input.addEventListener('keydown', function (e) {
      if (e.keyCode === 9 || e.keyCode === 40) { // if the tab or arrow down key was pressed
        searchbar.focusItem()
        e.preventDefault()
      }
    })

    // keypress doesn't fire on delete key - use keyup instead
    tabEditor.input.addEventListener('keyup', function (e) {
      if (e.keyCode === 8) {
        searchbar.showResults(this.value, e)
      }
    })

    tabEditor.input.addEventListener('keypress', function (e) {
      if (e.keyCode === 13) { // return key pressed; update the url
        if (this.getAttribute('data-autocomplete') && this.getAttribute('data-autocomplete').toLowerCase() === this.value.toLowerCase()) {
          // special case: if the typed input is capitalized differently from the actual URL that was autocompleted (but is otherwise the same), then we want to open the actual URL instead of what was typed.
          // see https://github.com/minbrowser/min/issues/314#issuecomment-276678613
          searchbar.openURL(this.getAttribute('data-autocomplete'), e)
        } else {
          searchbar.openURL(this.value, e)
        }
      } else if (e.keyCode === 9) {
        return
        // tab key, do nothing - in keydown listener
      } else if (e.keyCode === 16) {
        return
        // shift key, do nothing
      } else if (e.keyCode === 8) {
        return
        // delete key is handled in keyUp
      } else { // show the searchbar
        searchbar.showResults(this.value, e)
      }

      // on keydown, if the autocomplete result doesn't change, we move the selection instead of regenerating it to avoid race conditions with typing. Adapted from https://github.com/patrickburke/jquery.inlineComplete

      var v = e.key
      var sel = this.value.substring(this.selectionStart, this.selectionEnd).indexOf(v)

      if (v && sel === 0) {
        this.selectionStart += 1
        e.preventDefault()
      }
    })

    document.getElementById('webviews').addEventListener('click', function () {
      tabEditor.hide()
    })
  }
}

tabEditor.initialize()

module.exports = tabEditor
<commit_msg>adjust animation<commit_after>var searchbar = require('searchbar/searchbar.js')
var webviews = require('webviews.js')
var modalMode = require('modalMode.js')
var urlParser = require('util/urlParser.js')
var bookmarkStar = require('navbar/bookmarkStar.js')

const tabEditor = {
  container: document.getElementById('tab-editor'),
  input: document.getElementById('tab-editor-input'),
  star: null,
  show: function (tabId, editingValue, showSearchbar) {
    /* Edit mode is not available in modal mode. */
    if (modalMode.enabled()) {
      return
    }

    tabEditor.container.hidden = false

    bookmarkStar.update(tabId, tabEditor.star)

    webviews.requestPlaceholder('editMode')

    document.body.classList.add('is-edit-mode')

    var currentURL = urlParser.getSourceURL(tabs.get(tabId).url)
    if (currentURL === 'min://newtab') {
      currentURL = ''
    }

    tabEditor.input.value = editingValue || currentURL
    tabEditor.input.focus()
    if (!editingValue) {
      tabEditor.input.select()
    }

    searchbar.show(tabEditor.input)

    if (showSearchbar !== false) {
      if (editingValue) {
        searchbar.showResults(editingValue, null)
      } else {
        searchbar.showResults('', null)
      }
    }

    /* animation */
    if (tabs.count() > 1) {
      requestAnimationFrame(function () {

        var item = document.querySelector(`.tab-item[data-tab="${tabId}"]`)
        var originCoordinates = item.getBoundingClientRect()

        var finalCoordinates = document.querySelector('#tabs').getBoundingClientRect()

        var translateX = Math.min(Math.round(originCoordinates.x - finalCoordinates.x) * 0.45, window.innerWidth)

        tabEditor.container.style.opacity = 0
        tabEditor.container.style.transform = `translateX(${translateX}px)`
        requestAnimationFrame(function () {
          tabEditor.container.style.transition = '0.135s all'
          tabEditor.container.style.opacity = 1
          tabEditor.container.style.transform = ''
        })
      })
    }
  },
  hide: function () {
    tabEditor.container.hidden = true
    tabEditor.container.removeAttribute('style')

    tabEditor.input.blur()
    searchbar.hide()

    document.body.classList.remove('is-edit-mode')

    webviews.hidePlaceholder('editMode')
  },
  initialize: function () {
    tabEditor.input.setAttribute('placeholder', l('searchbarPlaceholder'))

    tabEditor.star = bookmarkStar.create()
    tabEditor.container.appendChild(tabEditor.star)

    tabEditor.input.addEventListener('keydown', function (e) {
      if (e.keyCode === 9 || e.keyCode === 40) { // if the tab or arrow down key was pressed
        searchbar.focusItem()
        e.preventDefault()
      }
    })

    // keypress doesn't fire on delete key - use keyup instead
    tabEditor.input.addEventListener('keyup', function (e) {
      if (e.keyCode === 8) {
        searchbar.showResults(this.value, e)
      }
    })

    tabEditor.input.addEventListener('keypress', function (e) {
      if (e.keyCode === 13) { // return key pressed; update the url
        if (this.getAttribute('data-autocomplete') && this.getAttribute('data-autocomplete').toLowerCase() === this.value.toLowerCase()) {
          // special case: if the typed input is capitalized differently from the actual URL that was autocompleted (but is otherwise the same), then we want to open the actual URL instead of what was typed.
          // see https://github.com/minbrowser/min/issues/314#issuecomment-276678613
          searchbar.openURL(this.getAttribute('data-autocomplete'), e)
        } else {
          searchbar.openURL(this.value, e)
        }
      } else if (e.keyCode === 9) {
        return
        // tab key, do nothing - in keydown listener
      } else if (e.keyCode === 16) {
        return
        // shift key, do nothing
      } else if (e.keyCode === 8) {
        return
        // delete key is handled in keyUp
      } else { // show the searchbar
        searchbar.showResults(this.value, e)
      }

      // on keydown, if the autocomplete result doesn't change, we move the selection instead of regenerating it to avoid race conditions with typing. Adapted from https://github.com/patrickburke/jquery.inlineComplete

      var v = e.key
      var sel = this.value.substring(this.selectionStart, this.selectionEnd).indexOf(v)

      if (v && sel === 0) {
        this.selectionStart += 1
        e.preventDefault()
      }
    })

    document.getElementById('webviews').addEventListener('click', function () {
      tabEditor.hide()
    })
  }
}

tabEditor.initialize()

module.exports = tabEditor
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.sendStatus(200);
});

router.get('/:sessionId', function(req, res, next) {
  res.statusCode = 200;
  res.send({
    id: req.params.sessionId,
    items : [
      {name:'Item 1', description:'Lorem Ipsum'},
      {name:'Item number 2', description:'Lorem Ipsum hfhfhfhf'},
      {name:'I am 3', description:'Lorem asdfasdf Ipsum'},
      {name:'Four', description:'Lorem 444444444 v  44 4 4 4Ipsum'}
    ]
  });
});

router.post('/:sessionId/estimate', function(req, res, next) {
  res.statusCode = 200;
  res.send();
});

module.exports = router;
<commit_msg>#3 Add dummy data listing sessions<commit_after>var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.send({
    items: [
      {name:'Dummy Session', url: "/sessions/123456"}
    ]
  })
});

router.get('/:sessionId', function(req, res, next) {
  if (req.params.sessionId == "123456") {
    res.send({
      id: req.params.sessionId,
      items: [
        {name: 'Item 1', description: 'Lorem Ipsum'},
        {name: 'Item number 2', description: 'Lorem Ipsum hfhfhfhf'},
        {name: 'I am 3', description: 'Lorem asdfasdf Ipsum'},
        {name: 'Four', description: 'Lorem 444444444 v  44 4 4 4Ipsum'}
      ]
    });
  } else res.sendStatus(404);
});

router.post('/:sessionId/estimate', function(req, res, next) {
  res.statusCode = 200;
  res.send();
});

module.exports = router;
<|endoftext|>


<commit_before>module.exports = (ctx, next) => {
  return next();
};
<commit_msg>Update old policy format<commit_after>module.exports = ctx => {
  return true;
};
<|endoftext|>


<commit_before>/**
 * Check if user is logged in
 */
var checkUserLoggedIn = function() {
    if(Meteor.user()) {
        Router.go('dashboard');
    } else {
        this.render('loginRequired');
 //       return this.next();
    }
};

Router.onBeforeAction(checkUserLoggedIn, {except: WSL.publicRoutes });
<commit_msg>user login check<commit_after>/**
 * Check if user is logged in
 */
var checkUserLoggedIn = function() {
    if(Meteor.user()) {
        Router.go(Router.current().route.path(this));
    } else {
        this.render('loginRequired');
    }
    this.next();
};
Router.onBeforeAction(checkUserLoggedIn, {except: WSL.publicRoutes });
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('secc:'+process.pid+':lib:clientPreprocessed');
var zlib = require('zlib');
var path = require('path');
var querystring = require('querystring');
var fs = require("fs");
var http = require("http");
var crypto = require('crypto');

var async = require('async');
var compile = require('./compile.js');
var environment = require('./environment.js');

module.exports.performPreprocessedMode = function(job, settings, cb) {
  debug('performPreprocessedMode');

  async.waterfall([
    function(callback) {
      var options = { preprocessedInfile : job.preprocessedInfile,
                      compilerPath: job.compilerPath,
                      argv: job.localArgv};
      var preprocessedStream = compile.GeneratePreprocessed(job.sourcePath, options);
      preprocessedStream.on('finish', function(err, sourceHash) {
        if (err) return callback(err);  //GeneratePreprocessed error.

        job.sourceHash = sourceHash;
        callback(null, preprocessedStream);
      });
    },

    function(preprocessedStream, callback) {
      //ask who.
      var formData = {
        systemInformation : environment.getSystemInformation(),
        compilerInformation : job.compilerInformation,
        mode : job.mode,
        projectId: job.projectId,
        cachePrefered : job.cachePrefered,
        crossPrefered : job.crossPrefered,
        sourcePath : job.sourcePath,
        sourceHash: job.sourceHash,
        argvHash : job.argvHash
      };

      debug('sourceHash : %s , argvHash : %s', job.sourceHash, job.argvHash);
      var options = {
        hostname: process.env.SECC_ADDRESS || settings.client.scheduler.address,
        port: process.env.SECC_PORT || settings.client.scheduler.port,
        path: '/job/new',
        method: 'POST',
        headers : {'Content-Type': 'application/json'}
      };

      var req = http.request(options);
      req.on('error', function(err) {return callback(err);})
      req.setTimeout(10000, function(){
        return this.emit('error', new Error('Timeout in request /job/new'));
      });
      req.on('response', function (res) {
        if(res.statusCode !== 200
          || res.headers['content-type'].indexOf('application/json') === -1) {
          this.abort();
          return this.emit('error', new Error('Error raised in who request'));
        }

        var data = '';
        res.on('data', function(chunk){data += chunk;});
        res.on('end', function(){
          var json = JSON.parse(data);
          job.id = json.jobId;
          job.local = json.local;
          job.cacheAvailable = json.cache;
          job.crossAvailable = json.cross;
          job.daemon = json.daemon;
          job.archive = json.archive;

          if (job.local)
            return callback(new Error('Build local from scheduler.' + ((json.error && json.error.message) ? ' - ' + json.error.message : '')));

          debug('remote daemon information - daemonId : %s , ip : %s:%s , hostname : %s'
            , job.daemon.daemonId, job.daemon.daemonAddress, job.daemon.daemonPort, job.daemon.system.hostname);
          debug('archiveId : %s , %s ,  %s', job.archive.archiveId
            , job.archive.dumpversion, job.archive.dumpmachine);

          if (job.cachePrefered == true && job.cacheAvailable == true) { //oh, cache~
            var options = {
              hostname: job.daemon.daemonAddress,
              port: job.daemon.daemonPort,
              path: '/cache/' + job.archive.archiveId
                    +'/' + job.sourceHash + '/' + job.argvHash,
              headers: {
                'secc-jobid' : job.id
              },
              method: 'GET'
            };

            debug('cache is available. try URL : %s', options.path);

            var cacheReq = http.request(options);
            cacheReq.on('error', function(err) { //on error, go next(cache failed)
              debug('cache hit failed. run request normal compile.')
              return callback(null, false, preprocessedStream);
            });
            cacheReq.setTimeout(10000, function(){
                return this.emit('error', new Error('Timeout in request cache'));
            });
            cacheReq.on('response', function(res) {
              if(res.statusCode !== 200) {
                this.abort();
                return this.emit('error', new Error('remote cache hit failed'));
              }

              if (typeof res.headers['secc-stdout'] !== 'undefined')
                process.stdout.write(querystring.unescape(res.headers['secc-stdout']));
              if (typeof res.headers['secc-stderr'] !== 'undefined')
                process.stderr.write(querystring.unescape(res.headers['secc-stderr']));

              //download well.
              var extract = require('tar').Extract({path: path.dirname(job.outputPath)});
              extract.on('error', function(err) {debug(err); return callback(err);});
              extract.on('end',function(){
                debug('download and extract done. from cache.');
                return callback(null, true, preprocessedStream);
              });

              res.pipe(zlib.createGunzip()).pipe(extract);
            });
            cacheReq.end();

          } else {
            callback(null, false, preprocessedStream);
          }

        });
      });
      req.write(JSON.stringify(formData));
      req.end();

    },

    // and which daemon is available,
    function(cached, preprocessedStream, callback) {
      if (cached)
        return callback(null); //by-pass if cached which means already processed.

      var gzip = zlib.createGzip({level: 1}) //FIXME : zlib.Z_BEST_SPEED

      //FIXME : need to improve.
      var compiler = (job.crossAvailable) ? job.archive.compiler : job.command;
      var language = (job.language) ? job.language : compile.determineLanguage(job.command, job.sourcePath);

      debug(job.remoteArgv);
      debug('language : %s', language);

      //FIXME : this happens when new remote daemon is on.
      if (typeof job.daemon.system === 'undefined')
        return callback(new Error('remote daemon Error'));

      var options = {
        hostname: job.daemon.daemonAddress,
        port: job.daemon.daemonPort,
        path: '/compile/preprocessed/' + job.archive.archiveId,
        method: 'POST',
        headers: {
          'Content-Encoding' : 'gzip',
          'secc-jobid' : job.id,
          'secc-compiler' : compiler,
          'secc-language' : language,
          'secc-argv' : JSON.stringify(job.remoteArgv),
          'secc-filename' : path.basename(job.outputPath, path.extname(job.outputPath)),
          'secc-cross' : job.crossAvailable,
          'secc-target': (job.targetSpecified)
                          ? job.target
                          : ((job.crossAvailable)
                              ? job.compilerInformation.dumpmachine
                              : null)
        },
        encoding: null //avoid converting the downloaded body to a string and keep it in a binary buffer
      };

      var req = http.request(options);
      req.on('error', function(err) {return callback(err);})
      req.setTimeout(60 * 2 * 1000, function(){
          return this.emit('error', new Error('Timeout in request compilePreprocessed'));
      });
      req.on('response', function(res) {
        if (typeof res.headers['secc-stdout'] !== 'undefined')
          process.stdout.write(querystring.unescape(res.headers['secc-stdout']));
        if (typeof res.headers['secc-stderr'] !== 'undefined')
          process.stderr.write(querystring.unescape(res.headers['secc-stderr']));

        if(res.statusCode !== 200 || res.headers['secc-code'] !== '0') {
          debug(res.headers['secc-code']);
          this.abort();
          return this.emit('error', new Error('remote compile daemon exited with non-zero'));
        }

        //download well.
        var extract = require('tar').Extract({path: path.dirname(job.outputPath)});
        extract.on('error', function(err) {debug(err); return callback(err);});
        extract.on('end',function(){
          debug('download and extract done.');
          return callback(null);
        });

        res.pipe(zlib.createGunzip()).pipe(extract);
      });

      //pipe magic
      return preprocessedStream
        .pipe(gzip).on('error', function(err) {return callback(err);})
        .pipe(req);
    }
    ]
    ,function(err){
      if(err)
        return cb(err);
      return cb(null);
    });
};<commit_msg>[client] buf fix. remote compiler's stdout/stderr should not print when failed.<commit_after>'use strict';

var debug = require('debug')('secc:'+process.pid+':lib:clientPreprocessed');
var zlib = require('zlib');
var path = require('path');
var querystring = require('querystring');
var fs = require("fs");
var http = require("http");
var crypto = require('crypto');

var async = require('async');
var compile = require('./compile.js');
var environment = require('./environment.js');

module.exports.performPreprocessedMode = function(job, settings, cb) {
  debug('performPreprocessedMode');

  async.waterfall([
    function(callback) {
      var options = { preprocessedInfile : job.preprocessedInfile,
                      compilerPath: job.compilerPath,
                      argv: job.localArgv};
      var preprocessedStream = compile.GeneratePreprocessed(job.sourcePath, options);
      preprocessedStream.on('finish', function(err, sourceHash) {
        if (err) return callback(err);  //GeneratePreprocessed error.

        job.sourceHash = sourceHash;
        callback(null, preprocessedStream);
      });
    },

    function(preprocessedStream, callback) {
      //ask who.
      var formData = {
        systemInformation : environment.getSystemInformation(),
        compilerInformation : job.compilerInformation,
        mode : job.mode,
        projectId: job.projectId,
        cachePrefered : job.cachePrefered,
        crossPrefered : job.crossPrefered,
        sourcePath : job.sourcePath,
        sourceHash: job.sourceHash,
        argvHash : job.argvHash
      };

      debug('sourceHash : %s , argvHash : %s', job.sourceHash, job.argvHash);
      var options = {
        hostname: process.env.SECC_ADDRESS || settings.client.scheduler.address,
        port: process.env.SECC_PORT || settings.client.scheduler.port,
        path: '/job/new',
        method: 'POST',
        headers : {'Content-Type': 'application/json'}
      };

      var req = http.request(options);
      req.on('error', function(err) {return callback(err);})
      req.setTimeout(10000, function(){
        return this.emit('error', new Error('Timeout in request /job/new'));
      });
      req.on('response', function (res) {
        if(res.statusCode !== 200
          || res.headers['content-type'].indexOf('application/json') === -1) {
          this.abort();
          return this.emit('error', new Error('Error raised in who request'));
        }

        var data = '';
        res.on('data', function(chunk){data += chunk;});
        res.on('end', function(){
          var json = JSON.parse(data);
          job.id = json.jobId;
          job.local = json.local;
          job.cacheAvailable = json.cache;
          job.crossAvailable = json.cross;
          job.daemon = json.daemon;
          job.archive = json.archive;

          if (job.local)
            return callback(new Error('Build local from scheduler.' + ((json.error && json.error.message) ? ' - ' + json.error.message : '')));

          debug('remote daemon information - daemonId : %s , ip : %s:%s , hostname : %s'
            , job.daemon.daemonId, job.daemon.daemonAddress, job.daemon.daemonPort, job.daemon.system.hostname);
          debug('archiveId : %s , %s ,  %s', job.archive.archiveId
            , job.archive.dumpversion, job.archive.dumpmachine);

          if (job.cachePrefered == true && job.cacheAvailable == true) { //oh, cache~
            var options = {
              hostname: job.daemon.daemonAddress,
              port: job.daemon.daemonPort,
              path: '/cache/' + job.archive.archiveId
                    +'/' + job.sourceHash + '/' + job.argvHash,
              headers: {
                'secc-jobid' : job.id
              },
              method: 'GET'
            };

            debug('cache is available. try URL : %s', options.path);

            var cacheReq = http.request(options);
            cacheReq.on('error', function(err) { //on error, go next(cache failed)
              debug('cache hit failed. run request normal compile.')
              return callback(null, false, preprocessedStream);
            });
            cacheReq.setTimeout(10000, function(){
                return this.emit('error', new Error('Timeout in request cache'));
            });
            cacheReq.on('response', function(res) {
              if(res.statusCode !== 200) {
                this.abort();
                return this.emit('error', new Error('remote cache hit failed'));
              }

              if (typeof res.headers['secc-stdout'] !== 'undefined')
                process.stdout.write(querystring.unescape(res.headers['secc-stdout']));
              if (typeof res.headers['secc-stderr'] !== 'undefined')
                process.stderr.write(querystring.unescape(res.headers['secc-stderr']));

              //download well.
              var extract = require('tar').Extract({path: path.dirname(job.outputPath)});
              extract.on('error', function(err) {debug(err); return callback(err);});
              extract.on('end',function(){
                debug('download and extract done. from cache.');
                return callback(null, true, preprocessedStream);
              });

              res.pipe(zlib.createGunzip()).pipe(extract);
            });
            cacheReq.end();

          } else {
            callback(null, false, preprocessedStream);
          }

        });
      });
      req.write(JSON.stringify(formData));
      req.end();

    },

    // and which daemon is available,
    function(cached, preprocessedStream, callback) {
      if (cached)
        return callback(null); //by-pass if cached which means already processed.

      var gzip = zlib.createGzip({level: 1}) //FIXME : zlib.Z_BEST_SPEED

      //FIXME : need to improve.
      var compiler = (job.crossAvailable) ? job.archive.compiler : job.command;
      var language = (job.language) ? job.language : compile.determineLanguage(job.command, job.sourcePath);

      debug(job.remoteArgv);
      debug('language : %s', language);

      //FIXME : this happens when new remote daemon is on.
      if (typeof job.daemon.system === 'undefined')
        return callback(new Error('remote daemon Error'));

      var options = {
        hostname: job.daemon.daemonAddress,
        port: job.daemon.daemonPort,
        path: '/compile/preprocessed/' + job.archive.archiveId,
        method: 'POST',
        headers: {
          'Content-Encoding' : 'gzip',
          'secc-jobid' : job.id,
          'secc-compiler' : compiler,
          'secc-language' : language,
          'secc-argv' : JSON.stringify(job.remoteArgv),
          'secc-filename' : path.basename(job.outputPath, path.extname(job.outputPath)),
          'secc-cross' : job.crossAvailable,
          'secc-target': (job.targetSpecified)
                          ? job.target
                          : ((job.crossAvailable)
                              ? job.compilerInformation.dumpmachine
                              : null)
        },
        encoding: null //avoid converting the downloaded body to a string and keep it in a binary buffer
      };

      var req = http.request(options);
      req.on('error', function(err) {return callback(err);})
      req.setTimeout(60 * 2 * 1000, function(){
          return this.emit('error', new Error('Timeout in request compilePreprocessed'));
      });
      req.on('response', function(res) {
        if(res.statusCode !== 200 || res.headers['secc-code'] !== '0') {
          debug(res.headers['secc-code']);
          this.abort();
          return this.emit('error', new Error('remote compile daemon exited with non-zero'));
        }

        if (typeof res.headers['secc-stdout'] !== 'undefined')
          process.stdout.write(querystring.unescape(res.headers['secc-stdout']));
        if (typeof res.headers['secc-stderr'] !== 'undefined')
          process.stderr.write(querystring.unescape(res.headers['secc-stderr']));

        //download well.
        var extract = require('tar').Extract({path: path.dirname(job.outputPath)});
        extract.on('error', function(err) {debug(err); return callback(err);});
        extract.on('end',function(){
          debug('download and extract done.');
          return callback(null);
        });

        res.pipe(zlib.createGunzip()).pipe(extract);
      });

      //pipe magic
      return preprocessedStream
        .pipe(gzip).on('error', function(err) {return callback(err);})
        .pipe(req);
    }
    ]
    ,function(err){
      if(err)
        return cb(err);
      return cb(null);
    });
};<|endoftext|>


<commit_before>function clearLocalstorage() {
	// only delete localStorage entries starting with 'mx'
	if (window.localStorage) {
		const allKeys = Object.keys(window.localStorage);
		const mxKeys = allKeys.filter((key) => key.indexOf('mx') === 0);
		mxKeys.forEach((key) => {
			window.localStorage.removeItem(key);
		});
	}

	// delete all indexedDB databases
	if (window.indexedDB) {
		window.indexedDB.databases()
			.then((r) => {
				for (let i = 0; i < r.length; i += 1) {
					window.indexedDB.deleteDatabase(r[i].name);
				}
			});
	}
}

clearLocalstorage();
<commit_msg>delete indexedDB databases in all browsers<commit_after>function clearLocalstorage() {
	// only delete localStorage entries starting with 'mx'
	if (window.localStorage) {
		const allKeys = Object.keys(window.localStorage);
		const mxKeys = allKeys.filter((key) => key.indexOf('mx') === 0);
		mxKeys.forEach((key) => {
			window.localStorage.removeItem(key);
		});
	}

	// delete matrix indexedDB databases
	if (window.indexedDB) {
		// window.indexedDB.databases() is not available in all browsers
		const databases = [
			'logs',
			'matrix-js-sdk:crypto',
			'matrix-js-sdk:riot-web-sync',
		];

		for (let i = 0; i < databases.length; i += 1) {
			window.indexedDB.deleteDatabase(databases[i]);
		}
	}
}

clearLocalstorage();
<|endoftext|>