<commit_before>// require ../support/jquery
// require esphinx_ui
// require esphinx/support/ajax
// require esphinx/support/function
// require esphinx/support/array
// require esphinx/observer

var
    jQuery,
    esPhinx,
    Singleton,
    Ajax,
    Constructor;

(function ($module) {
    "use strict";

    $module.extend({

        windows: {
            modal: {
                // functions are objects in js
                new: function (contentSource, options) {
                    var
                        ModalConstructor = Constructor.get($module.windows.modal.new, arguments),
                        self = this,

                        $ = jQuery,
                        ajax = Ajax,
                        args = arguments[0],
                        body = $("body"),
                        time = 0,
                        headers = options.header || options.headers || null,
                        params = options.param || options.params || null,

                        modal,
                        mask,
                        main,
                        header,
                        actions,
                        btnClose,
                        container,
                        btnHide,

                        setButtonsAction = function () {

                            $(document).off("keydown").on("keydown", function (e) {
                                if (e.keyCode === 27) {
                                    self.hide();
                                }
                            });

                            btnHide.click(function () {
                                self.hide();
                            });

                            btnClose.click(function () {
                                self.close();
                            });

                        },

                        observeContent = function () {
                            var
                                imgs,
                                length = 0;

                            esPhinx(container[0]).observe(function (observer) {
                                imgs = main.find("img");
                                if (imgs.length) {
                                    imgs.each(function (i, img) {
                                        esPhinx(img).on("load", function () {
                                            length += 1;
                                        });
                                    });

                                    FlowControl.new({
                                        condition: function (callback) {
                                            callback(length === imgs.length);
                                        },
                                        ready: function () {
                                            main.centralizeOn($(document));
                                            self.show();
                                        }
                                    })

                                } else {
                                    main.centralizeOn($(document));
                                    self.show();
                                }

                                debugger
                                observer.disconnect();
                            });
                        },

                        create = function () {
                            modal = $("

")
                                .addClass("esphinx ui modal");
                            main = $("")
                                .addClass("basicss hidden");
                            mask = $("

")
                                .addClass("basicss fixed transparent mask");
                            header = $("");
                            actions = $("

").addClass("actions");
                            btnClose = $('')
                                .addClass("btn-close");
                            btnHide = $('')
                                .addClass("btn-hide");
                            container = $("

").addClass("container");

                            modal
                                .append(mask)
                                .append(main);

                            main
                                .append(header)
                                .css({
                                    "max-height": $(window).height(),
                                    "max-width": $(document).width()
                                });

                            header.append(actions);

                            actions.append(btnClose);
                            actions.append(btnHide);

                            main.append(container);

                            setButtonsAction();

                            observeContent();

                            ajax.new(contentSource, {
                                params: params,
                                headers: headers,
                                processing: function (xhr) {
                                    if (options.loading) {
                                        options.loading(modal, xhr);
                                    }
                                },
                                success: function (answer) {
                                    body.append(modal);
                                    container.append(answer);
                                }
                            });

                        };

                    if (!(this instanceof ModalConstructor)) {
                        self = Singleton.instanceExists
                            .apply(ModalConstructor, arguments);
                        if (self) {
                            self.show();
                        } else {
                            return ModalConstructor.singleton(arguments);
                        }
                    // that "else" will should to exit for the "show" method can be used by who instanciates it
                    } else {
                        create();
                    }

                    // global scope (public)
                    this.close = function () {
                        main.hide();

                        mask.replaceToggleClass("transparent", "opacity-transition");

                        time = parseFloat(
                            mask.css("transition-duration")
                        ) * 1000;
                        setTimeout(function () {
                            modal.remove();
                        }, time);

                        self.deleteSingleton();
                    };

                    this.hide = function () {
                        main.hide();

                        mask.replaceToggleClass("transparent", "opacity-transition");

                        modal.css("zIndex", -1);

                    };

                    this.show = function () {
                        modal.css("zIndex", 0);
                        mask
                            .replaceToggleClass("transparent",
                                "opacity-transition");

                        main.show();
                    };
                }
            }
        }
    });

}(esPhinx.ui));
<commit_msg>remove debugger<commit_after>// require ../support/jquery
// require esphinx_ui
// require esphinx/support/ajax
// require esphinx/support/function
// require esphinx/support/array
// require esphinx/observer

var
    jQuery,
    esPhinx,
    Singleton,
    Ajax,
    Constructor;

(function ($module) {
    "use strict";

    $module.extend({

        windows: {
            modal: {
                // functions are objects in js
                new: function (contentSource, options) {
                    var
                        ModalConstructor = Constructor.get($module.windows.modal.new, arguments),
                        self = this,

                        $ = jQuery,
                        ajax = Ajax,
                        args = arguments[0],
                        body = $("body"),
                        time = 0,
                        headers = options.header || options.headers || null,
                        params = options.param || options.params || null,

                        modal,
                        mask,
                        main,
                        header,
                        actions,
                        btnClose,
                        container,
                        btnHide,

                        setButtonsAction = function () {

                            $(document).off("keydown").on("keydown", function (e) {
                                if (e.keyCode === 27) {
                                    self.hide();
                                }
                            });

                            btnHide.click(function () {
                                self.hide();
                            });

                            btnClose.click(function () {
                                self.close();
                            });

                        },

                        observeContent = function () {
                            var
                                imgs,
                                length = 0;

                            esPhinx(container[0]).observe(function (observer) {
                                imgs = main.find("img");
                                if (imgs.length) {
                                    imgs.each(function (i, img) {
                                        esPhinx(img).on("load", function () {
                                            length += 1;
                                        });
                                    });

                                    FlowControl.new({
                                        condition: function (callback) {
                                            callback(length === imgs.length);
                                        },
                                        ready: function () {
                                            main.centralizeOn($(document));
                                            self.show();
                                        }
                                    })

                                } else {
                                    main.centralizeOn($(document));
                                    self.show();
                                }

                                observer.disconnect();
                            });
                        },

                        create = function () {
                            modal = $("

")
                                .addClass("esphinx ui modal");
                            main = $("")
                                .addClass("basicss hidden");
                            mask = $("

")
                                .addClass("basicss fixed transparent mask");
                            header = $("");
                            actions = $("

").addClass("actions");
                            btnClose = $('')
                                .addClass("btn-close");
                            btnHide = $('')
                                .addClass("btn-hide");
                            container = $("

").addClass("container");

                            modal
                                .append(mask)
                                .append(main);

                            main
                                .append(header)
                                .css({
                                    "max-height": $(window).height(),
                                    "max-width": $(document).width()
                                });

                            header.append(actions);

                            actions.append(btnClose);
                            actions.append(btnHide);

                            main.append(container);

                            setButtonsAction();

                            observeContent();

                            ajax.new(contentSource, {
                                params: params,
                                headers: headers,
                                processing: function (xhr) {
                                    if (options.loading) {
                                        options.loading(modal, xhr);
                                    }
                                },
                                success: function (answer) {
                                    body.append(modal);
                                    container.append(answer);
                                }
                            });

                        };

                    if (!(this instanceof ModalConstructor)) {
                        self = Singleton.instanceExists
                            .apply(ModalConstructor, arguments);
                        if (self) {
                            self.show();
                        } else {
                            return ModalConstructor.singleton(arguments);
                        }
                    // that "else" will should to exit for the "show" method can be used by who instanciates it
                    } else {
                        create();
                    }

                    // global scope (public)
                    this.close = function () {
                        main.hide();

                        mask.replaceToggleClass("transparent", "opacity-transition");

                        time = parseFloat(
                            mask.css("transition-duration")
                        ) * 1000;
                        setTimeout(function () {
                            modal.remove();
                        }, time);

                        self.deleteSingleton();
                    };

                    this.hide = function () {
                        main.hide();

                        mask.replaceToggleClass("transparent", "opacity-transition");

                        modal.css("zIndex", -1);

                    };

                    this.show = function () {
                        modal.css("zIndex", 0);
                        mask
                            .replaceToggleClass("transparent",
                                "opacity-transition");

                        main.show();
                    };
                }
            }
        }
    });

}(esPhinx.ui));
<|endoftext|>


<commit_before>
describe("mapview", function() {

  var view;
  beforeEach(function() {
    var table = TestUtil.createTable('test');
    var infowindow = new cdb.geo.ui.InfowindowModel({ });
    var map = new cdb.admin.Map();
    map.layers.add(new cdb.geo.MapLayer());
    map.layers.add(new cdb.geo.MapLayer());

    view = new cdb.admin.MapTab({
      model: map,
      table: table,
      infowindow: infowindow,
      menu: new cdb.admin.RightMenu({})
    });
    // view.baseLayerChooser = {
    //   render: function() {
    //     return {
    //       "el": "dummy"
    //     }
    //   }
    // }
    // view._bindDataLayer(map.get('dataLayer').cid);

  });

  afterEach(function() {
    localStorage.clear();
  })

  it("should render", function() {
    view.render();
    expect(view.$('#map').length).toEqual(1);
    expect(view.$('.base_maps').length).toEqual(1);
    expect(view.$('.share').length).toEqual(1);
  });

  it("should trigger the georef warning when there's no geom in the table", function() {
    localStorage.clear();
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

  it("should trigger the georef warning when there's no data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

  it("should NOT trigger the georef warning when there the_geom and data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.options.table._data.reset([{'the_geom':'{"type":"Point","coordinates":["1","1"]}'}])
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef warning only once when there's no geom in the table", function() {
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef only once warning when there's no data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef again when formerly there were any data and now there are data but not georeferenced", function() {

    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry'], ['name','string']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table._data.reset([{'name':'tralará'}])
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

});
<commit_msg>dropdown html leftovers removed from tests<commit_after>
describe("mapview", function() {

  var view;
  beforeEach(function() {
    var table = TestUtil.createTable('test');
    var infowindow = new cdb.geo.ui.InfowindowModel({ });
    var map = new cdb.admin.Map();
    map.layers.add(new cdb.geo.MapLayer());
    map.layers.add(new cdb.geo.MapLayer());
    var element = $('

');
    element.appendTo($('body'))
    view = new cdb.admin.MapTab({
      model: map,
      table: table,
      infowindow: infowindow,
      menu: new cdb.admin.RightMenu({}),
      el: element
    });
    window.aaa= view;
    // view.baseLayerChooser = {
    //   render: function() {
    //     return {
    //       "el": "dummy"
    //     }
    //   }
    // }
    // view._bindDataLayer(map.get('dataLayer').cid);

  });

  afterEach(function() {
    localStorage.clear();
    view.$el.html('').remove();
    $('.dropdown').remove();
  })

  it("should render", function() {
    view.render();
    expect(view.$('#map').length).toEqual(1);
    expect(view.$('.base_maps').length).toEqual(1);
    expect(view.$('.share').length).toEqual(1);
  });

  it("should trigger the georef warning when there's no geom in the table", function() {
    localStorage.clear();
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

  it("should trigger the georef warning when there's no data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

  it("should NOT trigger the georef warning when there the_geom and data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.options.table._data.reset([{'the_geom':'{"type":"Point","coordinates":["1","1"]}'}])
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef warning only once when there's no geom in the table", function() {
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef only once warning when there's no data in the table", function() {
    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeFalsy()
  })

  it("should trigger the georef again when formerly there were any data and now there are data but not georeferenced", function() {

    view.options.table = TestUtil.createTable('test', [['the_geom', 'geometry'], ['name','string']]);
    view.bindGeoRefCheck();
    view.render();
    view.options.table.trigger("dataLoaded");
    view.noGeoRefDialog = undefined;
    view.options.table._data.reset([{'name':'tralará'}])
    view.options.table.trigger("dataLoaded");
    expect(view.noGeoRefDialog).toBeTruthy()
  })

});
<|endoftext|>


<commit_before>"use strict"

function Model(robotPosition, goal, obstacles)
{
  this.robotPosition = robotPosition;
  this.goal          = goal;
  this.obstacles     = obstacles;
}

function Circle(position, velocity, radius)
{
  this.position = position;
  this.velocity = velocity;
  this.radius   = radius;
}

Circle.prototype.update = function(dt)
{
  var newPosition = Vec2.add(this.position, Vec2.scale(dt, this.velocity));

  if(newPosition[0] < -gridSize)
  {
    this.position[0] = -2 * gridSize - newPosition[0];
    this.velocity = Vec2.scale(-1, this.velocity);
  }
  else if(newPosition[0] > gridSize)
  {
    this.position[0] = 2 * gridSize - newPosition[0];
    this.velocity = Vec2.scale(-1, this.velocity);
  }
  else
  {
    this.position[0] = newPosition[0];
  }
}

Circle.prototype.draw = function()
{
  ctx.beginPath();
  ctx.arc(this.position[0], this.position[1], this.radius, 0, Math.PI*2);
  ctx.fill();
}

Circle.prototype.force = function(position)
{
  var difference = Vec2.sub(position, this.position);
  var length     = Vec2.length(difference);

  return Vec2.scale((this.radius*this.radius)/(length*length*length), difference);
}

function Segment(a, b, width)
{
  this.a     = a;
  this.b     = b;
  this.width = width;
}

Segment.prototype.update = function(dt){ return this; }

Segment.prototype.draw = function()
{
  ctx.lineWidth = 2*(this.width - robotDisplayRadius);
  ctx.lineCap = "round";
  ctx.beginPath();
  ctx.moveTo(this.a[0], this.a[1]);
  ctx.lineTo(this.b[0], this.b[1]);
  ctx.stroke();
}

Segment.prototype.force = function(position)
{
  var ab = Vec2.sub(this.b, this.a);
  var ap = Vec2.sub(position, this.a);
  var bp = Vec2.sub(position, this.b);

  if(Vec2.dot(ab, ap) < 0)
  {
    var apDist = Vec2.length(ap);
    return Vec2.scale(this.width*this.width / (apDist*apDist*apDist), ap);
  }
  else if(Vec2.dot(ab, bp) > 0)
  {
    var bpDist = Vec2.length(bp);
    return Vec2.scale(this.width*this.width / (bpDist*bpDist*bpDist), bp);
  }
  else
  {
    var perp = Vec2.normalize([-ab[1], ab[0]]);
    var perpDist = Vec2.dot(perp, ap);
    return Vec2.scale(-(this.width*this.width) / (perpDist*perpDist), perp);
  }
}
<commit_msg>Fix Segment Force Bug<commit_after>"use strict"

function Model(robotPosition, goal, obstacles)
{
  this.robotPosition = robotPosition;
  this.goal          = goal;
  this.obstacles     = obstacles;
}

function Circle(position, velocity, radius)
{
  this.position = position;
  this.velocity = velocity;
  this.radius   = radius;
}

Circle.prototype.update = function(dt)
{
  var newPosition = Vec2.add(this.position, Vec2.scale(dt, this.velocity));

  if(newPosition[0] < -gridSize)
  {
    this.position[0] = -2 * gridSize - newPosition[0];
    this.velocity = Vec2.scale(-1, this.velocity);
  }
  else if(newPosition[0] > gridSize)
  {
    this.position[0] = 2 * gridSize - newPosition[0];
    this.velocity = Vec2.scale(-1, this.velocity);
  }
  else
  {
    this.position[0] = newPosition[0];
  }
}

Circle.prototype.draw = function()
{
  ctx.beginPath();
  ctx.arc(this.position[0], this.position[1], this.radius, 0, Math.PI*2);
  ctx.fill();
}

Circle.prototype.force = function(position)
{
  var difference = Vec2.sub(position, this.position);
  var length     = Vec2.length(difference);

  return Vec2.scale((this.radius*this.radius)/(length*length*length), difference);
}

function Segment(a, b, width)
{
  this.a     = a;
  this.b     = b;
  this.width = width;
}

Segment.prototype.update = function(dt){ return this; }

Segment.prototype.draw = function()
{
  ctx.lineWidth = 2*(this.width - robotDisplayRadius);
  ctx.lineCap = "round";
  ctx.beginPath();
  ctx.moveTo(this.a[0], this.a[1]);
  ctx.lineTo(this.b[0], this.b[1]);
  ctx.stroke();
}

Segment.prototype.force = function(position)
{
  var ab = Vec2.sub(this.b  , this.a);
  var ap = Vec2.sub(position, this.a);
  var bp = Vec2.sub(position, this.b);

  if(Vec2.dot(ab, ap) < 0)
  {
    var apDist = Vec2.length(ap);
    return Vec2.scale(this.width*this.width / (apDist*apDist*apDist), ap);
  }
  else if(Vec2.dot(ab, bp) > 0)
  {
    var bpDist = Vec2.length(bp);
    return Vec2.scale(this.width*this.width / (bpDist*bpDist*bpDist), bp);
  }
  else
  {
    var perp = Vec2.normalize([-ab[1], ab[0]]);
    var perpDist = Vec2.dot(perp, ap);
    return Vec2.scale(((perpDist > 0 ? 1 : -1) * this.width * this.width) / (perpDist*perpDist), perp);
  }
}
<|endoftext|>


<commit_before>/**
 * @hide
 * The base directive class.  Classes extending [DocumentJS.Pair] [DocumentJS.Pair.static.add|add] directives
 * to be matched against.  The available directives are:
 *

 *
[DocumentJS.Directive.Init|init]

 *
[DocumentJS.Directive.Param|param]

 *
[DocumentJS.Directive.Inherits|inherits]

 *
[DocumentJS.Directive.Return|return]

 *
[DocumentJS.Directive.Author|author]

 *
[DocumentJS.Directive.Hide|hide]

 *
[DocumentJS.Directive.CodeStart|codestart]

 *
[DocumentJS.Directive.CodeEnd|codeend]

 *
[DocumentJS.Directive.Alias|alias]

 *
[DocumentJS.Directive.Plugin|plugin]

 *

 *
How directives work

 * Directives mix in their add and add_more functions into DocumentJS.Pair classes.
 * These functions work with [DocumentJS.Pair.prototype.comment_setup|Pair::comment_setup] to
 * read directives (things that look like @something) and make sense of their data.
 *
 *
 */
DocumentJS.Class.extend("DocumentJS.Directive",
/* @prototype */
{
    /**
     * Called when [DocumentJS.Pair.prototype.comment_setup|comment_setup] first sees a line with the matching
     * directive.
     * If the function returns null or false, following lines without another directive will be added to
     * real_comment.  If the function returns data, the add_more will be called with lines following this line
     * and the data returned.
     *
     * In these functions, save the data from comments like:
     * @codestart
     * this.my_data = line.match(/\d\d/)
     * @codeend
     * It's important to note that this refers to the Pair instance of the class that has added this directive.
     *
     * @param {String} line the line with the directive on it.
     * @return {Object} if false, add future lines to real_comment, otherwise, call add_more with future lines
     * and the data returned.
     */
    add: function(line){
        var m = line.match(/^\s*@(\w+)\s*(.*)/)
        if(m){
            this[m[1]] = m[2];
        }
    }
    /**
     * @function add_more
     * Adds lines following a directive.
     * @param {String} line the current comment line
     * @param {Object} prior data the data returned from the previous add or add_more.
     * @return {Object} if false, ends calling add_more with future lines, otherwise; calls add_more with the next
     * line and the return value.
     */
})
//start directives
/**
 * @hide
 * Describes constructor functionality.  Matches multiple lines
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Init',
{
    add: function(line){
            var parts = line.match(/\s?@init(.*)?/);
            if(!parts || !parts[1]){
                this.init_description = " ";
                return true;
            }
            this.init_description = parts.pop();
            return this.init_description;
    },
    add_more: function(line){
        this.init_description +="\n"+ line;
    }
});
/**
 * @hide
 * Adds parameter information of the format: "@param {optional:type} name description" .
 * Matches multiple lines.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Param',{
    add_more : function(line, last){
        if(last)
            last.description += "\n"+line;
    },
    /**
     * Adds @param data to the constructor function
     * @param {String} line
     */
    add: function(line){
        var parts = line.match(/\s*@param\s+(?:\{([^}]+)\})?\s+([^\s]+) ?(.*)?/);
        if(!parts){
            print("LINE: \n"+line+"\n does not match @params {optional:TYPE} NAME DESCRIPTION")
            return;
        }
        var description = parts.pop();
        var n = parts.pop(), optional = false, defaultVal;
        //check if it has anything ...
		var nameParts = n.match(/\[([\w\.]+)(?:=([^\]]*))?\]/)
		if(nameParts){
			optional = true;
			defaultVal = nameParts[2]
			n = nameParts[1]
		}

        var param = this.params[n] ? this.params[n] : this.params[n] = {order: this.ordered_params().length };

        param.description = description || "";
        param.name = n;
        param.type = parts.pop()|| "";

		param.optional = optional;
        if(defaultVal){
			param["default"] = defaultVal;
		}

		return this.params[n];
    }
});
/**
 * @hide
 * Says current class or constructor inherits from another class or contructor.
 * Looks for "@inherits constructor or class name"
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Inherits',{
    add: function(line){
        var m = line.match(/^\s*@\w+ ([\w\.]+)/)
        if(m){
            this.inherits = m[1];
        }
    }
})
/**
 * @hide
 * Describes return data in the format "@return {type} description".
 * Matches multiple lines.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Return',{
    add: function(line){
        var parts = line.match(/\s*@return\s+(?:\{([\w\.\/]+)\})?\s*(.*)?/);

        if(!parts) {
           return;
        }

        var description = parts.pop() || "";
        var type = parts.pop();
        this.ret = {description: description, type: type};
        return this.ret;
    },
    add_more : function(line){
        this.ret.description += "\n"+line;
    }
})
/**
 * @hide
 * Describes who the author of a class is.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Author',{
    add: function(line){
        var m = line.match(/^\s*@author\s*(.*)/)
        if(m){
            this.author = m[1];
        }
    }
});
/**
 * @hide
 * Hides this class or constructor from the left hand side bar.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Hide',{
    add: function(line){
        var m = line.match(/^\s*@hide/)
        if(m){
            this.hide = true;
        }
    }
});
/**
 * @hide
 * Starts a code block.  Looks for "@codestart code_type".  Matches
 * multiple lines.  Must end with "@codeend".
 */
DocumentJS.Directive.extend('DocumentJS.Directive.CodeStart',{
    add: function(line){
        var m = line.match(/^\s*@codestart\s*([\w-]*)\s*(.*)/)
        if(m){
            this.comment_code_type = m[1] ? m[1].toLowerCase() : 'javascript';
            this.comment_code = [];
            return true;
        }
    },
    add_more : function(line){
        this.comment_code.push(line);
    }
});
/**
 * @hide
 * Stops a code block
 */
DocumentJS.Directive.extend('DocumentJS.Directive.CodeEnd',{
    add: function(line){
        var m = line.match(/^\s*@codeend/)

        if(m){
            var joined = this.comment_code.join("\n");
			if(this.comment_code_type == "javascript")
				joined = joined.replace(/\*\|/g,"*/")
			this.real_comment +=
            "
"+joined+"
"
        }
        return false;
    }
});
/**
 * @hide
 * This Class or Constructor is known by another name. Format: "@alias other_name"
 *
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Alias',{
    add: function(line){
        var m = line.match(/^\s*@alias\s*([\w\-\.]*)/)
        if(m){
            this.alias = m[1];
        }
    }
});
/**
 * @hide
 * Adds to another plugin. Format: "@plugin plugin_name"
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Plugin',{
    add: function(line){
        this.plugin = line.match(/@plugin ([^ ]+)/)[1];
    }
});

/**
 * @hide
 * Adds tags for searching
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Tag',{
    add: function(line){
        var parts = line.match(/^\s*@tag\s*(.+)/);

        if(!parts) {
           return;
        }
        this.tags = parts[1].split(/\s*,\s*/g)
        //return this.ret;
    }//,
    //add_more : function(line){
    //    this.tags.concat(line.split(/\s*,\s*/g))
    //}
});

/**
 * @hide
 * Adds an iframe to some page with example code, e.g. @iframe phui/menu/menu.html 320
 * 320 is the iframe height.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.iFrame',{
    add: function(line){
        var m = line.match(/^\s*@iframe\s*([\w\.\/]*)\s*([\w]*)\s*(.*)/)

        if(m){
            var iframe_src = m[1] ? m[1].toLowerCase() : '';
			var iframe_height = m[2] ? m[2] : '320';
			this.real_comment +=
            "

"
        }
    }
});
<commit_msg>Some styling improvements to @iframe directive.<commit_after>/**
 * @hide
 * The base directive class.  Classes extending [DocumentJS.Pair] [DocumentJS.Pair.static.add|add] directives
 * to be matched against.  The available directives are:
 *

 *
[DocumentJS.Directive.Init|init]

 *
[DocumentJS.Directive.Param|param]

 *
[DocumentJS.Directive.Inherits|inherits]

 *
[DocumentJS.Directive.Return|return]

 *
[DocumentJS.Directive.Author|author]

 *
[DocumentJS.Directive.Hide|hide]

 *
[DocumentJS.Directive.CodeStart|codestart]

 *
[DocumentJS.Directive.CodeEnd|codeend]

 *
[DocumentJS.Directive.Alias|alias]

 *
[DocumentJS.Directive.Plugin|plugin]

 *

 *
How directives work

 * Directives mix in their add and add_more functions into DocumentJS.Pair classes.
 * These functions work with [DocumentJS.Pair.prototype.comment_setup|Pair::comment_setup] to
 * read directives (things that look like @something) and make sense of their data.
 *
 *
 */
DocumentJS.Class.extend("DocumentJS.Directive",
/* @prototype */
{
    /**
     * Called when [DocumentJS.Pair.prototype.comment_setup|comment_setup] first sees a line with the matching
     * directive.
     * If the function returns null or false, following lines without another directive will be added to
     * real_comment.  If the function returns data, the add_more will be called with lines following this line
     * and the data returned.
     *
     * In these functions, save the data from comments like:
     * @codestart
     * this.my_data = line.match(/\d\d/)
     * @codeend
     * It's important to note that this refers to the Pair instance of the class that has added this directive.
     *
     * @param {String} line the line with the directive on it.
     * @return {Object} if false, add future lines to real_comment, otherwise, call add_more with future lines
     * and the data returned.
     */
    add: function(line){
        var m = line.match(/^\s*@(\w+)\s*(.*)/)
        if(m){
            this[m[1]] = m[2];
        }
    }
    /**
     * @function add_more
     * Adds lines following a directive.
     * @param {String} line the current comment line
     * @param {Object} prior data the data returned from the previous add or add_more.
     * @return {Object} if false, ends calling add_more with future lines, otherwise; calls add_more with the next
     * line and the return value.
     */
})
//start directives
/**
 * @hide
 * Describes constructor functionality.  Matches multiple lines
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Init',
{
    add: function(line){
            var parts = line.match(/\s?@init(.*)?/);
            if(!parts || !parts[1]){
                this.init_description = " ";
                return true;
            }
            this.init_description = parts.pop();
            return this.init_description;
    },
    add_more: function(line){
        this.init_description +="\n"+ line;
    }
});
/**
 * @hide
 * Adds parameter information of the format: "@param {optional:type} name description" .
 * Matches multiple lines.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Param',{
    add_more : function(line, last){
        if(last)
            last.description += "\n"+line;
    },
    /**
     * Adds @param data to the constructor function
     * @param {String} line
     */
    add: function(line){
        var parts = line.match(/\s*@param\s+(?:\{([^}]+)\})?\s+([^\s]+) ?(.*)?/);
        if(!parts){
            print("LINE: \n"+line+"\n does not match @params {optional:TYPE} NAME DESCRIPTION")
            return;
        }
        var description = parts.pop();
        var n = parts.pop(), optional = false, defaultVal;
        //check if it has anything ...
		var nameParts = n.match(/\[([\w\.]+)(?:=([^\]]*))?\]/)
		if(nameParts){
			optional = true;
			defaultVal = nameParts[2]
			n = nameParts[1]
		}

        var param = this.params[n] ? this.params[n] : this.params[n] = {order: this.ordered_params().length };

        param.description = description || "";
        param.name = n;
        param.type = parts.pop()|| "";

		param.optional = optional;
        if(defaultVal){
			param["default"] = defaultVal;
		}

		return this.params[n];
    }
});
/**
 * @hide
 * Says current class or constructor inherits from another class or contructor.
 * Looks for "@inherits constructor or class name"
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Inherits',{
    add: function(line){
        var m = line.match(/^\s*@\w+ ([\w\.]+)/)
        if(m){
            this.inherits = m[1];
        }
    }
})
/**
 * @hide
 * Describes return data in the format "@return {type} description".
 * Matches multiple lines.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Return',{
    add: function(line){
        var parts = line.match(/\s*@return\s+(?:\{([\w\.\/]+)\})?\s*(.*)?/);

        if(!parts) {
           return;
        }

        var description = parts.pop() || "";
        var type = parts.pop();
        this.ret = {description: description, type: type};
        return this.ret;
    },
    add_more : function(line){
        this.ret.description += "\n"+line;
    }
})
/**
 * @hide
 * Describes who the author of a class is.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Author',{
    add: function(line){
        var m = line.match(/^\s*@author\s*(.*)/)
        if(m){
            this.author = m[1];
        }
    }
});
/**
 * @hide
 * Hides this class or constructor from the left hand side bar.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Hide',{
    add: function(line){
        var m = line.match(/^\s*@hide/)
        if(m){
            this.hide = true;
        }
    }
});
/**
 * @hide
 * Starts a code block.  Looks for "@codestart code_type".  Matches
 * multiple lines.  Must end with "@codeend".
 */
DocumentJS.Directive.extend('DocumentJS.Directive.CodeStart',{
    add: function(line){
        var m = line.match(/^\s*@codestart\s*([\w-]*)\s*(.*)/)
        if(m){
            this.comment_code_type = m[1] ? m[1].toLowerCase() : 'javascript';
            this.comment_code = [];
            return true;
        }
    },
    add_more : function(line){
        this.comment_code.push(line);
    }
});
/**
 * @hide
 * Stops a code block
 */
DocumentJS.Directive.extend('DocumentJS.Directive.CodeEnd',{
    add: function(line){
        var m = line.match(/^\s*@codeend/)

        if(m){
            var joined = this.comment_code.join("\n");
			if(this.comment_code_type == "javascript")
				joined = joined.replace(/\*\|/g,"*/")
			this.real_comment +=
            "
"+joined+"
"
        }
        return false;
    }
});
/**
 * @hide
 * This Class or Constructor is known by another name. Format: "@alias other_name"
 *
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Alias',{
    add: function(line){
        var m = line.match(/^\s*@alias\s*([\w\-\.]*)/)
        if(m){
            this.alias = m[1];
        }
    }
});
/**
 * @hide
 * Adds to another plugin. Format: "@plugin plugin_name"
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Plugin',{
    add: function(line){
        this.plugin = line.match(/@plugin ([^ ]+)/)[1];
    }
});

/**
 * @hide
 * Adds tags for searching
 */
DocumentJS.Directive.extend('DocumentJS.Directive.Tag',{
    add: function(line){
        var parts = line.match(/^\s*@tag\s*(.+)/);

        if(!parts) {
           return;
        }
        this.tags = parts[1].split(/\s*,\s*/g)
        //return this.ret;
    }//,
    //add_more : function(line){
    //    this.tags.concat(line.split(/\s*,\s*/g))
    //}
});

/**
 * @hide
 * Adds an iframe to some page with example code, e.g. @iframe phui/menu/menu.html 320
 * 320 is the iframe height.
 */
DocumentJS.Directive.extend('DocumentJS.Directive.iFrame',{
    add: function(line){
        var m = line.match(/^\s*@iframe\s*([\w\.\/]*)\s*([\w]*)\s*(.*)/)

        if(m){
            var iframe_src = m[1] ? m[1].toLowerCase() : '';
			var iframe_height = m[2] ? m[2] : '320';
			this.real_comment +=
            ""
        }
    }
});
<|endoftext|>


<commit_before>const { ipcRenderer: ipc } = require('electron');
const parse = require('./app/shared/database/parse');
const crypto = require('crypto');
const Datastore = require('nedb');
const db = new Datastore({
  filename: `${__dirname}/tasks.db`,
  afterSerialization: (object) => {
    const cipher = crypto.createCipher('aes256', 'sample-key');
    return (cipher.update(object, 'utf8', 'hex') + cipher.final('hex'));
  },
  beforeDeserialization: (object) => {
    const decipher = crypto.createDecipher('aes256', 'sample-key');
    return (decipher.update(object, 'hex', 'utf8') + decipher.final('utf8'));
  },
  autoload: true,
});

/**
 * Get a query, parse it and add it to
 * database
 * @param  {string}   query task query
 * @param  {Function} cb  callback
 * @return {undefined}
 */
function insert(query, cb) {
  const taskObj = parse(query);
  db.insert(taskObj, (err) => {
    if (err) {
      ipc.send('insert-error', err);
    } else {
      cb();
    }
  });
}

/**
 * Find appropriate tasks based on type
 * @param  {string}   type Determines type of task
 *                         to be found
 * @param  {Function} cb   callback
 * @return {undefined}
 */
function find(type, cb) {
  const now = Date.now();
  switch (type) {
  case 'open':
    db.find({
      $and: [{ start: { $lt: now } },
            { end: { $gt: now } },
            { status: 0 },
          ],
    }, { text: 1, start: 1, end: 1, units: 1 },
        (err, tasks) => {
          if (err) {
            ipc.send('find-error', err);
          } else {
            const nowInner = (Date.now() + (86400000 - (Date.now() % 86400000))) +
              (new Date().getTimezoneOffset() * 60000);
            const sorted = Object.keys(tasks).sort((a, b) => {
              const totalA = tasks[a].end - tasks[a].start;
              const totalB = tasks[b].end - tasks[b].start;
              const partialA = nowInner - tasks[a].start;
              const partialB = nowInner - tasks[b].start;
              const ratioA = partialA / totalA;
              const ratioB = partialB / totalB;
              return ratioB - ratioA;
            });
            cb(sorted.map(key => tasks[key]));
          }
        });
    break;
  case 'overdue':
    db.find({
      $and: [{ end: { $lt: now } },
            { status: 0 },
          ],
    }, { text: 1, start: 1, end: 1, units: 1 },
        (err, tasks) => {
          if (err) {
            ipc.send('find-error', err);
          } else {
            const nowInner = (Date.now() + (86400000 - (Date.now() % 86400000))) +
              (new Date().getTimezoneOffset() * 60000);
            const sorted = Object.keys(tasks).sort((a, b) => {
              const totalA = tasks[a].end - tasks[a].start;
              const totalB = tasks[b].end - tasks[b].start;
              const partialA = nowInner - tasks[a].start;
              const partialB = nowInner - tasks[b].start;
              const ratioA = partialA / totalA;
              const ratioB = partialB / totalB;
              return ratioB - ratioA;
            });
            cb(sorted.map(key => tasks[key]));
          }
        });
    break;
  default:
  }
}

/**
 * Mark a task as done in the database
 * @param  {number}   taskId task id
 * @param  {Function} cb     callback
 * @return {undefined}
 */
function markAsDone(taskId, cb) {
  db.find(
    { _id: taskId },
    { start: 1, end: 1, period: 1 },
    (err, tasks) => {
      if (err) {
        ipc.send('find-error', err);
      } else {
        const { start, end, period } = tasks[0];
        if (period === -1) {
          db.update({
            _id: taskId,
          }, { $set: {
            status: 1,
          } }, {}, (errInner) => {
            if (errInner) {
              ipc.send('update-error', err);
            } else {
              cb();
            }
          });
        } else {
          db.update({
            _id: taskId,
          }, { $set: {
            start: start + period,
            end: end + period,
          } }, {}, (errInner) => {
            if (errInner) {
              ipc.send('update-error', err);
            } else {
              cb();
            }
          });
        }
      }
    }
  );
}

/**
 * Remove a task from database
 * @param  {number}   taskId task id
 * @param  {Function} cb     callback
 * @return {undefined}
 */
function remove(taskId, cb) {
  db.remove({
    _id: taskId,
  }, {}, (err) => {
    if (err) {
      ipc.send('remove-error', err);
    } else {
      cb();
    }
  });
}

/**
 * Edit a task in database
 * @param  {number}   taskId  task id
 * @param  {string}   newText new task text
 * @param  {Function} cb      callback
 * @return {undefined}
 */
function edit(taskId, newText, cb) {
  db.update({
    _id: taskId,
  }, {
    $set: {
      text: newText,
    },
  }, {}, (err) => {
    if (err) {
      ipc.send('update-error', err);
    } else {
      cb();
    }
  });
}

angular.module('MainApp')
  .factory('db', () => {
    return {
      insert,
      find,
      markAsDone,
      remove,
      edit,
    };
  });
<commit_msg>Resolve eslint error<commit_after>const { ipcRenderer: ipc } = require('electron');
const parse = require('./app/shared/database/parse');
const crypto = require('crypto');
const Datastore = require('nedb');
const db = new Datastore({
  filename: `${__dirname}/tasks.db`,
  afterSerialization: (object) => {
    const cipher = crypto.createCipher('aes256', 'sample-key');
    return (cipher.update(object, 'utf8', 'hex') + cipher.final('hex'));
  },
  beforeDeserialization: (object) => {
    const decipher = crypto.createDecipher('aes256', 'sample-key');
    return (decipher.update(object, 'hex', 'utf8') + decipher.final('utf8'));
  },
  autoload: true,
});

/**
 * Get a query, parse it and add it to
 * database
 * @param  {string}   query task query
 * @param  {Function} cb  callback
 * @return {undefined}
 */
function insert(query, cb) {
  const taskObj = parse(query);
  db.insert(taskObj, (err) => {
    if (err) {
      ipc.send('insert-error', err);
    } else {
      cb();
    }
  });
}

/**
 * Find appropriate tasks based on type
 * @param  {string}   type Determines type of task
 *                         to be found
 * @param  {Function} cb   callback
 * @return {undefined}
 */
function find(type, cb) {
  const now = Date.now();
  switch (type) {
  case 'open':
    db.find({
      $and: [{ start: { $lt: now } },
            { end: { $gt: now } },
            { status: 0 },
          ],
    }, { text: 1, start: 1, end: 1, units: 1 },
        (err, tasks) => {
          if (err) {
            ipc.send('find-error', err);
          } else {
            const nowInner = (Date.now() + (86400000 - (Date.now() % 86400000))) +
              (new Date().getTimezoneOffset() * 60000);
            const sorted = Object.keys(tasks).sort((a, b) => {
              const totalA = tasks[a].end - tasks[a].start;
              const totalB = tasks[b].end - tasks[b].start;
              const partialA = nowInner - tasks[a].start;
              const partialB = nowInner - tasks[b].start;
              const ratioA = partialA / totalA;
              const ratioB = partialB / totalB;
              return ratioB - ratioA;
            });
            cb(sorted.map(key => tasks[key]));
          }
        });
    break;
  case 'overdue':
    db.find({
      $and: [{ end: { $lt: now } },
            { status: 0 },
          ],
    }, { text: 1, start: 1, end: 1, units: 1 },
        (err, tasks) => {
          if (err) {
            ipc.send('find-error', err);
          } else {
            const nowInner = (Date.now() + (86400000 - (Date.now() % 86400000))) +
              (new Date().getTimezoneOffset() * 60000);
            const sorted = Object.keys(tasks).sort((a, b) => {
              const totalA = tasks[a].end - tasks[a].start;
              const totalB = tasks[b].end - tasks[b].start;
              const partialA = nowInner - tasks[a].start;
              const partialB = nowInner - tasks[b].start;
              const ratioA = partialA / totalA;
              const ratioB = partialB / totalB;
              return ratioB - ratioA;
            });
            cb(sorted.map(key => tasks[key]));
          }
        });
    break;
  default:
  }
}

/**
 * Mark a task as done in the database
 * @param  {number}   taskId task id
 * @param  {Function} cb     callback
 * @return {undefined}
 */
function markAsDone(taskId, cb) {
  db.find(
    { _id: taskId },
    { start: 1, end: 1, period: 1 },
    (err, tasks) => {
      if (err) {
        ipc.send('find-error', err);
      } else {
        const { start, end, period } = tasks[0];
        if (period === -1) {
          db.update({
            _id: taskId,
          }, { $set: {
            status: 1,
          } }, {}, (errInner) => {
            if (errInner) {
              ipc.send('update-error', err);
            } else {
              cb();
            }
          });
        } else {
          db.update({
            _id: taskId,
          }, { $set: {
            start: start + period,
            end: end + period,
          } }, {}, (errInner) => {
            if (errInner) {
              ipc.send('update-error', err);
            } else {
              cb();
            }
          });
        }
      }
    }
  );
}

/**
 * Remove a task from database
 * @param  {number}   taskId task id
 * @param  {Function} cb     callback
 * @return {undefined}
 */
function remove(taskId, cb) {
  db.remove({
    _id: taskId,
  }, {}, (err) => {
    if (err) {
      ipc.send('remove-error', err);
    } else {
      cb();
    }
  });
}

/**
 * Edit a task in database
 * @param  {number}   taskId  task id
 * @param  {string}   newText new task text
 * @param  {Function} cb      callback
 * @return {undefined}
 */
function edit(taskId, newText, cb) {
  db.update({
    _id: taskId,
  }, {
    $set: {
      text: newText,
    },
  }, {}, (err) => {
    if (err) {
      ipc.send('update-error', err);
    } else {
      cb();
    }
  });
}

angular.module('MainApp')
  .factory('db', () => {
    const ret = {
      insert,
      find,
      markAsDone,
      remove,
      edit,
    };
    return ret;
  });
<|endoftext|>


<commit_before>'use strict';

module.exports = {

  // Common options for all karma targets
  options: {

    // Use mocha and chai for tests
    frameworks: ['mocha', 'chai'],

    // Web server port
    port: 9876,

    // Enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: OFF || ERROR || WARN || INFO || DEBUG
    logLevel: 'INFO',

    // Enable / disable watching file and executing tests whenever
    // any file changes
    autoWatch: false,

    // List of browsers to execute tests on
    browsers: [
      'PhantomJS'
    ],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true

  },

  // Plugin unit tests
  plugin: {
    configFile: 'tests/client/karmaConf.js'
  }

};
<commit_msg>commands: rename karma:plugin<commit_after>'use strict';

module.exports = {

  // Common options for all karma targets
  options: {

    // Use mocha and chai for tests
    frameworks: ['mocha', 'chai'],

    // Web server port
    port: 9876,

    // Enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: OFF || ERROR || WARN || INFO || DEBUG
    logLevel: 'INFO',

    // Enable / disable watching file and executing tests whenever
    // any file changes
    autoWatch: false,

    // List of browsers to execute tests on
    browsers: [
      'PhantomJS'
    ],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true

  },

  // Plugin unit tests
  'back-office': {
    configFile: 'tests/client/karmaConf.js'
  }

};
<|endoftext|>


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

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name abs
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/special/abs}
*/
setReadOnly( ns, 'abs', require( '@stdlib/math/special/abs' ) );

/**
* @name iabs
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/special/iabs}
*/
setReadOnly( ns, 'iabs', require( '@stdlib/math/special/iabs' ) );

// EXPORTS //

module.exports = ns;
<commit_msg>Fix require path<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name abs
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/special/abs}
*/
setReadOnly( ns, 'abs', require( '@stdlib/math/special/abs' ) );

/**
* @name inabs
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/special/inabs}
*/
setReadOnly( ns, 'inabs', require( '@stdlib/math/special/inabs' ) );

// EXPORTS //

module.exports = ns;
<|endoftext|>


<commit_before>import loadScript from 'load-script';
import Promise from 'promise';
import ThreeDSecureStrategy from './strategy';

const debug = require('debug')('recurly:risk:three-d-secure:stripe');
const LIB_URL = 'https://js.stripe.com/v3/';

export default class StripeStrategy extends ThreeDSecureStrategy {
  constructor (...args) {
    super(...args);

    debug('loading Stripe library');
    this.loadStripeLibrary()
      .catch(cause => this.threeDSecure.error('3ds-vendor-load-error', { vendor: 'Stripe', cause }))
      .then(() => {
        this.stripe = window.Stripe(this.stripePublishableKey);
        debug('Stripe checkout instance created', this.stripe);
        this.markReady();
      })
      .done();
  }

  get stripePublishableKey () {
    return this.actionToken.gateway.credentials.publishable_key;
  }

  get stripeClientSecret () {
    return this.actionToken.three_d_secure.params.client_secret;
  }

  /**
   * Provides the target DOM element for which we will apply
   * fingerprint detection, challenge flows, and results
   *
   * @param {HTMLElement} element
   */
  attach (element) {
    super.attach(element);

    this.whenReady(() => {
      this.stripe.handleCardPayment(this.stripeClientSecret).then(result => {
        if (result.error) {
          return this.threeDSecure.error('3ds-auth-error', { cause: result.error });
        }
        this.emit('done', result.paymentIntent);
      });
    });
  }

  /**
   * Loads Adyen library dependency
   */
  loadStripeLibrary (done) {
    return new Promise((resolve, reject) => {
      if (window.Stripe) return resolve();
      loadScript(LIB_URL, error => {
        if (error) reject(err);
        else resolve();
      })
    });
  }
}
<commit_msg>Use handleCardAction for post SCA<commit_after>import loadScript from 'load-script';
import Promise from 'promise';
import ThreeDSecureStrategy from './strategy';

const debug = require('debug')('recurly:risk:three-d-secure:stripe');
const LIB_URL = 'https://js.stripe.com/v3/';

export default class StripeStrategy extends ThreeDSecureStrategy {
  constructor (...args) {
    super(...args);

    debug('loading Stripe library');
    this.loadStripeLibrary()
      .catch(cause => this.threeDSecure.error('3ds-vendor-load-error', { vendor: 'Stripe', cause }))
      .then(() => {
        this.stripe = window.Stripe(this.stripePublishableKey);
        debug('Stripe checkout instance created', this.stripe);
        this.markReady();
      })
      .done();
  }

  get stripePublishableKey () {
    return this.actionToken.gateway.credentials.publishable_key;
  }

  get stripeClientSecret () {
    return this.actionToken.three_d_secure.params.client_secret;
  }

  /**
   * Provides the target DOM element for which we will apply
   * fingerprint detection, challenge flows, and results
   *
   * @param {HTMLElement} element
   */
  attach (element) {
    super.attach(element);

    this.whenReady(() => {
      this.stripe.handleCardAction(this.stripeClientSecret).then(result => {
        if (result.error) {
          return this.threeDSecure.error('3ds-auth-error', { cause: result.error });
        }
        this.emit('done', result.paymentIntent);
      });
    });
  }

  /**
   * Loads Adyen library dependency
   */
  loadStripeLibrary (done) {
    return new Promise((resolve, reject) => {
      if (window.Stripe) return resolve();
      loadScript(LIB_URL, error => {
        if (error) reject(err);
        else resolve();
      })
    });
  }
}
<|endoftext|>


<commit_before>'use strict';

const graphql = require('graphql');
const graphqlService = require('../index');
const paymentProcessorType = require('../types/payment-processor');
const paymentProcessorEnum = require('../types/payment-processor-enum');

const addPaymentMethod = {
  type: paymentProcessorType,
  args: {
    name: {
      type: paymentProcessorEnum
    },
    data: {
      type: graphql.GraphQLString
    }
  },
  resolve: function(_, args) {
    return graphqlService.defaultPaymentProcessor
        .then((paymentProcessor) => {
          const data = JSON.parse(args.data);
          if(paymentProcessor){
            if(paymentProcessor.paymentMethods > 1){
              throw new Error('Multiple card support not available at this time.');
            }

            return new Promise((resolve, reject) => {
              paymentProcessor.addPaymentMethod(data)
                .then((paymentProcessor) => {
                  return resolve(paymentProcessor);
                })
            })
          }

          return graphqlService.addPaymentProcessor(args.name, data);
        })
        .catch((err) => {
          console.error(err);
          return {error: new Error(err)};
        });
  }
};

module.exports = addPaymentMethod;
<commit_msg>Refactor<commit_after>'use strict';

const graphql = require('graphql');
const graphqlService = require('../index');
const paymentProcessorType = require('../types/payment-processor');
const paymentProcessorEnum = require('../types/payment-processor-enum');

const addPaymentMethod = {
  type: paymentProcessorType,
  args: {
    name: {
      type: paymentProcessorEnum
    },
    data: {
      type: graphql.GraphQLString
    }
  },
  resolve: function(_, args) {
    return graphqlService.defaultPaymentProcessor
      .then((paymentProcessor) => {
        const data = JSON.parse(args.data);

        if (!paymentProcessor) {
          return graphqlService.addPaymentProcessor(args.name, data);
        }

        if (paymentProcessor.paymentMethods > 1) {
          throw new Error('Multiple card support not available at this time.');
        }

        return new Promise((resolve, reject) => {
          paymentProcessor
            .addPaymentMethod(data)
            .then((paymentProcessor) => resolve(paymentProcessor));
        });

      }).catch((err) => {
        console.error(err);
        return {error: new Error(err)};
      });
  }
};

module.exports = addPaymentMethod;
<|endoftext|>


<commit_before>import RSVP from 'rsvp';
import Service, {inject as service} from '@ember/service';
import config from 'ghost-admin/config/environment';

export default Service.extend({
    ajax: service(),
    ghostPaths: service(),

    // This is needed so we can disable it in unit tests
    testing: undefined,

    scriptPromises: null,

    init() {
        this._super(...arguments);
        this.scriptPromises = {};

        if (this.testing === undefined) {
            this.testing = config.environment === 'test';
        }
    },

    loadScript(key, url) {
        if (this.testing) {
            return RSVP.resolve();
        }

        if (this.scriptPromises[key]) {
            return this.scriptPromises[key];
        }

        let scriptPromise = new RSVP.Promise((resolve, reject) => {
            let {adminRoot} = this.ghostPaths;

            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.async = true;
            script.src = `${adminRoot}${url}`;

            let el = document.getElementsByTagName('script')[0];
            el.parentNode.insertBefore(script, el);

            script.addEventListener('load', () => {
                resolve();
            });

            script.addEventListener('error', () => {
                reject(new Error(`${url} failed to load`));
            });
        });

        this.scriptPromises[key] = scriptPromise;

        return scriptPromise;
    },

    loadStyle(key, url, alternate = false) {
        if (this.testing || document.querySelector(`#${key}-styles`)) {
            return RSVP.resolve();
        }

        return new RSVP.Promise((resolve, reject) => {
            let link = document.createElement('link');
            link.id = `${key}-styles`;
            link.rel = alternate ? 'alternate stylesheet' : 'stylesheet';
            link.href = `${this.ghostPaths.adminRoot}${url}`;
            link.onload = () => {
                if (alternate) {
                    // If stylesheet is alternate and we disable the stylesheet before injecting into the DOM,
                    // the onload handler never gets called. Thus, we should disable the link after it has finished loading
                    link.disabled = true;
                }
                resolve();
            };
            link.onerror = reject;

            if (alternate) {
                link.title = key;
            }

            document.querySelector('head').appendChild(link);
        });
    }
});
<commit_msg>🐛 Fixed night shift toggle in Firefox Nightly. (#1174)<commit_after>import RSVP from 'rsvp';
import Service, {inject as service} from '@ember/service';
import config from 'ghost-admin/config/environment';

export default Service.extend({
    ajax: service(),
    ghostPaths: service(),

    // This is needed so we can disable it in unit tests
    testing: undefined,

    scriptPromises: null,

    init() {
        this._super(...arguments);
        this.scriptPromises = {};

        if (this.testing === undefined) {
            this.testing = config.environment === 'test';
        }
    },

    loadScript(key, url) {
        if (this.testing) {
            return RSVP.resolve();
        }

        if (this.scriptPromises[key]) {
            return this.scriptPromises[key];
        }

        let scriptPromise = new RSVP.Promise((resolve, reject) => {
            let {adminRoot} = this.ghostPaths;

            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.async = true;
            script.src = `${adminRoot}${url}`;

            let el = document.getElementsByTagName('script')[0];
            el.parentNode.insertBefore(script, el);

            script.addEventListener('load', () => {
                resolve();
            });

            script.addEventListener('error', () => {
                reject(new Error(`${url} failed to load`));
            });
        });

        this.scriptPromises[key] = scriptPromise;

        return scriptPromise;
    },

    loadStyle(key, url, alternate = false) {
        if (this.testing || document.querySelector(`#${key}-styles`)) {
            return RSVP.resolve();
        }

        return new RSVP.Promise((resolve, reject) => {
            let link = document.createElement('link');
            link.id = `${key}-styles`;
            link.rel = alternate ? 'alternate stylesheet' : 'stylesheet';
            link.href = `${this.ghostPaths.adminRoot}${url}`;
            link.onload = () => {
                link.onload = null;
                if (alternate) {
                    // If stylesheet is alternate and we disable the stylesheet before injecting into the DOM,
                    // the onload handler never gets called. Thus, we should disable the link after it has finished loading
                    link.disabled = true;
                }
                resolve();
            };
            link.onerror = reject;

            if (alternate) {
                link.title = key;
            }

            document.querySelector('head').appendChild(link);
        });
    }
});
<|endoftext|>


<commit_before>/* eslint-disable */
'use strict';

module.exports = {
    name: 'asset-delivery',

    isDevelopingAddon() {
        return true;
    },

    postBuild: function (results) {
        const fs = this.project.require('fs-extra');
        const walkSync = this.project.require('walk-sync');

        const assetsOut = `../core/core/built/admin`;
        fs.removeSync(assetsOut);
        fs.ensureDirSync(assetsOut);

        // the dist folder contains more than just index.html and /assets, especially
        // for development builds but for Ghost's purposes it only needs to serve
        // index.html and /assets

        // copy the index.html file
        fs.copySync(`${results.directory}/index.html`, `${assetsOut}/index.html`, {overwrite: true, dereference: true});

        // copy all the `/assets` files
        const assets = walkSync(results.directory + '/assets');

        assets.forEach(function (relativePath) {
            if (relativePath.slice(-1) === '/') { return; }

            fs.copySync(`${results.directory}/assets/${relativePath}`, `${assetsOut}/assets/${relativePath}`, {overwrite: true, dereference: true});
        });
    }
};
<commit_msg>Removed icon files from packaged tarball<commit_after>/* eslint-disable */
'use strict';

module.exports = {
    name: 'asset-delivery',

    isDevelopingAddon() {
        return true;
    },

    postBuild: function (results) {
        const fs = this.project.require('fs-extra');
        const walkSync = this.project.require('walk-sync');

        const assetsOut = `../core/core/built/admin`;
        fs.removeSync(assetsOut);
        fs.ensureDirSync(assetsOut);

        // the dist folder contains more than just index.html and /assets, especially
        // for development builds but for Ghost's purposes it only needs to serve
        // index.html and /assets

        // copy the index.html file
        fs.copySync(`${results.directory}/index.html`, `${assetsOut}/index.html`, {overwrite: true, dereference: true});

        // copy all the `/assets` files, except the `icons` folder
        const assets = walkSync(results.directory + '/assets', {
            ignore: ['icons']
        });

        assets.forEach(function (relativePath) {
            if (relativePath.slice(-1) === '/') { return; }

            fs.copySync(`${results.directory}/assets/${relativePath}`, `${assetsOut}/assets/${relativePath}`, {overwrite: true, dereference: true});
        });
    }
};
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*global Windows:true */

var cordova = require('cordova');
var Connection = require('cordova/plugin/Connection');

module.exports = {

    getConnectionInfo:function(win,fail,args)
    {
        console.log("NetworkStatusProxy::getConnectionInfo");
        var winNetConn = Windows.Networking.Connectivity;
        var networkInfo = winNetConn.NetworkInformation;
        var networkCostInfo = winNetConn.NetworkCostType;
        var networkConnectivityInfo = winNetConn.NetworkConnectivityLevel;
        var networkAuthenticationInfo = winNetConn.NetworkAuthenticationType;
        var networkEncryptionInfo = winNetConn.NetworkEncryptionType;

        var connectionType;

        var profile = Windows.Networking.Connectivity.NetworkInformation.getInternetConnectionProfile();
        if(profile) {
            var conLevel = profile.getNetworkConnectivityLevel();
            var interfaceType = profile.networkAdapter.ianaInterfaceType;

            if (conLevel == Windows.Networking.Connectivity.NetworkConnectivityLevel.none) {
                connectionType = Connection.NONE;
            }
            else {
                switch (interfaceType) {
                    case 71:
                        connectionType = Connection.WIFI;
                        break;
                    case 6:
                        connectionType = Connection.ETHERNET;
                        break;
                    default:
                        connectionType = Connection.UNKNOWN;
                        break;
                }
            }
        }
        // FYI
        //Connection.UNKNOWN  'Unknown connection';
        //Connection.ETHERNET 'Ethernet connection';
        //Connection.WIFI     'WiFi connection';
        //Connection.CELL_2G  'Cell 2G connection';
        //Connection.CELL_3G  'Cell 3G connection';
        //Connection.CELL_4G  'Cell 4G connection';
        //Connection.NONE     'No network connection';

        setTimeout(function () {
            if (connectionType) {
                win(connectionType);
            } else {
                win(Connection.NONE);
            }
        },0);
    }

};

require("cordova/commandProxy").add("NetworkStatus",module.exports);<commit_msg>[Windows8] added 3G type for 3GPP and 3GPP2<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*global Windows:true */

var cordova = require('cordova');
var Connection = require('cordova/plugin/Connection');

module.exports = {

    getConnectionInfo:function(win,fail,args)
    {
        console.log("NetworkStatusProxy::getConnectionInfo");
        var winNetConn = Windows.Networking.Connectivity;
        var networkInfo = winNetConn.NetworkInformation;
        var networkCostInfo = winNetConn.NetworkCostType;
        var networkConnectivityInfo = winNetConn.NetworkConnectivityLevel;
        var networkAuthenticationInfo = winNetConn.NetworkAuthenticationType;
        var networkEncryptionInfo = winNetConn.NetworkEncryptionType;

        var connectionType;

        var profile = Windows.Networking.Connectivity.NetworkInformation.getInternetConnectionProfile();
        if(profile) {
            var conLevel = profile.getNetworkConnectivityLevel();
            var interfaceType = profile.networkAdapter.ianaInterfaceType;

            if (conLevel == Windows.Networking.Connectivity.NetworkConnectivityLevel.none) {
                connectionType = Connection.NONE;
            }
            else {
                switch (interfaceType) {
                    case 71:
                        connectionType = Connection.WIFI;
                        break;
                    case 6:
                        connectionType = Connection.ETHERNET;
                        break;
                    case 243: // (3GPP WWAN) // Fallthrough is intentional
                    case 244: // (3GPP2 WWAN)
                         connectionType = Connection.CELL_3G;
                         break;
                    default:
                        connectionType = Connection.UNKNOWN;
                        break;
                }
            }
        }
        // FYI
        //Connection.UNKNOWN  'Unknown connection';
        //Connection.ETHERNET 'Ethernet connection';
        //Connection.WIFI     'WiFi connection';
        //Connection.CELL_2G  'Cell 2G connection';
        //Connection.CELL_3G  'Cell 3G connection';
        //Connection.CELL_4G  'Cell 4G connection';
        //Connection.NONE     'No network connection';

        setTimeout(function () {
            if (connectionType) {
                win(connectionType);
            } else {
                win(Connection.NONE);
            }
        },0);
    }

};

require("cordova/commandProxy").add("NetworkStatus",module.exports);<|endoftext|>


<commit_before>'use strict';
(function (window) {
    var digits = [
            '零',
            '一',
            '二',
            '三',
            '四',
            '五',
            '六',
            '七',
            '八',
            '九'
        ], subScale = [
            '',
            '',
            '十',
            '百',
            '千'
        ], scale = [
            '',
            '万',
            '亿',
            '兆'
        ], scaleSize = 4;
    var digitsPinyin = [
            'líng',
            'yī',
            'èr',
            'sān',
            'sì',
            'wǔ',
            'liù',
            'qī',
            'bā',
            'jiǔ'
        ], subScalePinyin = [
            '',
            '',
            'shí',
            'bǎi',
            'qiān'
        ], scalePinyin = [
            '',
            'wàn',
            'yì',
            'zhào'
        ], pinyin = {};
    digits.forEach(function (digit, index) {
        pinyin[digit] = digitsPinyin[index];
    });
    subScale.forEach(function (word, index) {
        if (word !== '')
            pinyin[word] = subScalePinyin[index];
    });
    scale.forEach(function (word, index) {
        if (word !== '')
            pinyin[word] = scalePinyin[index];
    });
    pinyin['点'] = 'diǎn';
    pinyin['负'] = 'fù';
    function sanitise(strVal) {
        var val = strVal.toString().replace(/[\,\s]/g, '');
        val = val.replace(/^0+(?!\.)/, '');
        if (val.indexOf('.') >= 0 && /0*$/.test(val)) {
            val = val.replace(/0*$/, '');
        }
        if (isNaN(parseFloat(val)))
            throw new Error('Please input only numbers');
        return val;
    }
    function translateDigit(strDigit) {
        return digits[parseInt(strDigit)];
    }
    function translateSection(arrDigit, scaleLevel) {
        if (arrDigit.length > scaleSize)
            throw new Error('Section should only have $(scaleSize) digits');
        var subScaleLevelIndex = arrDigit.length, intEndIndex = arrDigit.join('').search(/0+$/), strOutput = '';
        intEndIndex = intEndIndex === -1 ? arrDigit.length : intEndIndex;
        for (var digitIndex = 0; digitIndex < intEndIndex; digitIndex++) {
            var digit = arrDigit[digitIndex];
            strOutput += translateDigit(digit) + (digit !== '0' ? subScale[subScaleLevelIndex] : '');
            subScaleLevelIndex--;
        }
        window.CP.exitedLoop(1);
        if (arrDigit.join('') === '10') {
            strOutput = strOutput.slice(-1);
        } else {
            if (arrDigit.length === 2 && arrDigit[0] === '1') {
                strOutput = strOutput.slice(-2);
            }
        }
        return strOutput + scale[scaleLevel === undefined ? 0 : scaleLevel];
    }
    function translateInteger(strVal, scaleLevel) {
        if (strVal.toString().length > scale.length * scaleSize) {
            throw new Error('chNum only supports up to 16 digits');
        }
        var arrDigit = strVal.toString().split(''), section = arrDigit.splice(-scaleSize, scaleSize), translatedSection = translateSection(section, scaleLevel).replace(/零+/, '零');
        if (!!arrDigit.length) {
            return translateInteger(arrDigit.join(''), (scaleLevel === undefined ? 0 : scaleLevel) + 1) + translatedSection;
        } else {
            return translatedSection;
        }
    }
    function translateFractional(strVal) {
        return strVal.toString().split('').map(function (strDigit) {
            return translateDigit(strDigit);
        }).join('');
    }
    function romaniser(strChinese) {
        return strChinese.split('').map(function (digit) {
            return pinyin[digit];
        });
    }
    function chNum(strVal) {
        var _a = sanitise(strVal).split('.'), integer = _a[0], fractional = _a[1], isNegative = integer.indexOf('-') === 0;
        if (isNegative)
            integer = integer.replace('-', '');
        var outInteger = translateInteger(integer), outFractional = !!fractional ? translateFractional(fractional) : false, output = '';
        if (isNegative)
            output += '负';
        if (!!outFractional) {
            output += (outInteger === '' ? translateDigit(0) : outInteger) + '点' + outFractional;
        } else {
            output += outInteger;
        }
        return {
            chinese: output.split(''),
            romanised: romaniser(output)
        };
    }
    window.chNum = chNum;
}(window));
(function (window) {
    function measureText(txt, font) {
        var id = 'text-width-tester', $tag = $('#' + id);
        if (!$tag.length) {
            $tag = $('' + txt + '');
            $('body').append($tag);
        } else {
            $tag.css({ font: font }).html(txt);
        }
        return {
            width: $tag.width(),
            height: $tag.height()
        };
    }
    function shrinkToFill(input, fontSize, fontWeight, fontFamily) {
        var $input = $(input), txt = $input.val(), maxWidth = $input.width() + 5, font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
        var textWidth = measureText(txt, font).width;
        if (textWidth > maxWidth) {
            fontSize = fontSize * maxWidth / textWidth * 0.9;
            font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
            $input.css({ font: font });
        } else {
            $input.css({ font: font });
        }
    }
    function table_shrinkToFill(table, measuredRowIndex, fontSize, fontWeight, fontFamily) {
        var row = $('tr', table)[measuredRowIndex], cells = $('td', row), cellMaxWidth = $(cells[0]).width() + 5, textWidths = [], textMaxWidth, font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
        Array.prototype.forEach.call(cells, function (cell) {
            textWidths.push(measureText(cell.innerText, font).width);
        });
        textMaxWidth = Math.max.apply(Math, textWidths);
        if (textMaxWidth > cellMaxWidth) {
            font = fontWeight + ' ' + fontSize * cellMaxWidth / textMaxWidth * 0.9 + 'pt ' + fontFamily;
        }
        $('.output-table td').css({ font: font });
    }
    ;
    window.measureText = measureText;
    window.shrinkToFill = shrinkToFill;
    window.table_shrinkToFill = table_shrinkToFill;
}(window));
$(document).ready(function () {
    var input = $('#input');
    input.keyup(function () {
        shrinkToFill(this, 100, '', '\'Reem Kufi\', san-serif');
        var translated = chNum(this.value), table = $('.output-table');
        table.empty();
        $('.output').append(tabulate(translated));
        table_shrinkToFill(table[0], 1, 40, '', '\'Noto Sans SC\', sans-serif');
    });
    input.val(3.14159265);
    input.keyup();
    function tabulate(translated) {
        var table = $('.output-table');
        [
            translated.chinese,
            translated.romanised
        ].forEach(function (str) {
            var row = $('

');
            str.forEach(function (char, index) {
                row.append($('	').text(char));
            });
            table.append(row);
        });
        return table;
    }
});
<commit_msg>Update chNum.js<commit_after>'use strict';
(function (window) {
    var digits = [
            '零',
            '一',
            '二',
            '三',
            '四',
            '五',
            '六',
            '七',
            '八',
            '九'
        ], subScale = [
            '',
            '',
            '十',
            '百',
            '千'
        ], scale = [
            '',
            '万',
            '亿',
            '兆'
        ], scaleSize = 4;
    var digitsPinyin = [
            'líng',
            'yī',
            'èr',
            'sān',
            'sì',
            'wǔ',
            'liù',
            'qī',
            'bā',
            'jiǔ'
        ], subScalePinyin = [
            '',
            '',
            'shí',
            'bǎi',
            'qiān'
        ], scalePinyin = [
            '',
            'wàn',
            'yì',
            'zhào'
        ], pinyin = {};
    digits.forEach(function (digit, index) {
        pinyin[digit] = digitsPinyin[index];
    });
    subScale.forEach(function (word, index) {
        if (word !== '')
            pinyin[word] = subScalePinyin[index];
    });
    scale.forEach(function (word, index) {
        if (word !== '')
            pinyin[word] = scalePinyin[index];
    });
    pinyin['点'] = 'diǎn';
    pinyin['负'] = 'fù';
    function sanitise(strVal) {
        var val = strVal.toString().replace(/[\,\s]/g, '');
        val = val.replace(/^0+(?!\.)/, '');
        if (val.indexOf('.') >= 0 && /0*$/.test(val)) {
            val = val.replace(/0*$/, '');
        }
        if (isNaN(parseFloat(val)))
            throw new Error('Please input only numbers');
        return val;
    }
    function translateDigit(strDigit) {
        return digits[parseInt(strDigit)];
    }
    function translateSection(arrDigit, scaleLevel) {
        if (arrDigit.length > scaleSize)
            throw new Error('Section should only have $(scaleSize) digits');
        var subScaleLevelIndex = arrDigit.length, intEndIndex = arrDigit.join('').search(/0+$/), strOutput = '';
        intEndIndex = intEndIndex === -1 ? arrDigit.length : intEndIndex;
        for (var digitIndex = 0; digitIndex < intEndIndex; digitIndex++) {
            var digit = arrDigit[digitIndex];
            strOutput += translateDigit(digit) + (digit !== '0' ? subScale[subScaleLevelIndex] : '');
            subScaleLevelIndex--;
        }
        if (arrDigit.join('') === '10') {
            strOutput = strOutput.slice(-1);
        } else {
            if (arrDigit.length === 2 && arrDigit[0] === '1') {
                strOutput = strOutput.slice(-2);
            }
        }
        return strOutput + scale[scaleLevel === undefined ? 0 : scaleLevel];
    }
    function translateInteger(strVal, scaleLevel) {
        if (strVal.toString().length > scale.length * scaleSize) {
            throw new Error('chNum only supports up to 16 digits');
        }
        var arrDigit = strVal.toString().split(''), section = arrDigit.splice(-scaleSize, scaleSize), translatedSection = translateSection(section, scaleLevel).replace(/零+/, '零');
        if (!!arrDigit.length) {
            return translateInteger(arrDigit.join(''), (scaleLevel === undefined ? 0 : scaleLevel) + 1) + translatedSection;
        } else {
            return translatedSection;
        }
    }
    function translateFractional(strVal) {
        return strVal.toString().split('').map(function (strDigit) {
            return translateDigit(strDigit);
        }).join('');
    }
    function romaniser(strChinese) {
        return strChinese.split('').map(function (digit) {
            return pinyin[digit];
        });
    }
    function chNum(strVal) {
        var _a = sanitise(strVal).split('.'), integer = _a[0], fractional = _a[1], isNegative = integer.indexOf('-') === 0;
        if (isNegative)
            integer = integer.replace('-', '');
        var outInteger = translateInteger(integer), outFractional = !!fractional ? translateFractional(fractional) : false, output = '';
        if (isNegative)
            output += '负';
        if (!!outFractional) {
            output += (outInteger === '' ? translateDigit(0) : outInteger) + '点' + outFractional;
        } else {
            output += outInteger;
        }
        return {
            chinese: output.split(''),
            romanised: romaniser(output)
        };
    }
    window.chNum = chNum;
}(window));
(function (window) {
    function measureText(txt, font) {
        var id = 'text-width-tester', $tag = $('#' + id);
        if (!$tag.length) {
            $tag = $('' + txt + '');
            $('body').append($tag);
        } else {
            $tag.css({ font: font }).html(txt);
        }
        return {
            width: $tag.width(),
            height: $tag.height()
        };
    }
    function shrinkToFill(input, fontSize, fontWeight, fontFamily) {
        var $input = $(input), txt = $input.val(), maxWidth = $input.width() + 5, font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
        var textWidth = measureText(txt, font).width;
        if (textWidth > maxWidth) {
            fontSize = fontSize * maxWidth / textWidth * 0.9;
            font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
            $input.css({ font: font });
        } else {
            $input.css({ font: font });
        }
    }
    function table_shrinkToFill(table, measuredRowIndex, fontSize, fontWeight, fontFamily) {
        var row = $('tr', table)[measuredRowIndex], cells = $('td', row), cellMaxWidth = $(cells[0]).width() + 5, textWidths = [], textMaxWidth, font = fontWeight + ' ' + fontSize + 'pt ' + fontFamily;
        Array.prototype.forEach.call(cells, function (cell) {
            textWidths.push(measureText(cell.innerText, font).width);
        });
        textMaxWidth = Math.max.apply(Math, textWidths);
        if (textMaxWidth > cellMaxWidth) {
            font = fontWeight + ' ' + fontSize * cellMaxWidth / textMaxWidth * 0.9 + 'pt ' + fontFamily;
        }
        $('.output-table td').css({ font: font });
    }
    ;
    window.measureText = measureText;
    window.shrinkToFill = shrinkToFill;
    window.table_shrinkToFill = table_shrinkToFill;
}(window));
$(document).ready(function () {
    var input = $('#input');
    input.keyup(function () {
        shrinkToFill(this, 100, '', '\'Reem Kufi\', san-serif');
        var translated = chNum(this.value), table = $('.output-table');
        table.empty();
        $('.output').append(tabulate(translated));
        table_shrinkToFill(table[0], 1, 40, '', '\'Noto Sans SC\', sans-serif');
    });
    input.val(3.14159265);
    input.keyup();
    function tabulate(translated) {
        var table = $('.output-table');
        [
            translated.chinese,
            translated.romanised
        ].forEach(function (str) {
            var row = $('

');
            str.forEach(function (char, index) {
                row.append($('	').text(char));
            });
            table.append(row);
        });
        return table;
    }
});
<|endoftext|>


<commit_before>var mongoose = require('mongoose');

var userSchema = new mongoose.Schema({
  name: { type: String, lowercase: true },
  group: String
});

var User = exports.User = mongoose.model('user', userSchema);

exports.connect_database = function() {
  var url = process.env.MONGODB || 'mongodb://localhost:27017/ps';
  mongoose.connect(url);
  mongoose.connection.on('error', function() {
    console.error('MongoDB Connection Error. Make sure MongoDB is running.');
  });
};

exports.importUsergroups = function(usergroups, Config) {
  User.find({}, function(err, users) {
    if (err) return;
    users.forEach(function(user) {
      usergroups[user.name] =  (user.group || Config.groupsranking[0]) + user.name;
    });
  });
};

exports.exportUsergroups = function(usergroups) {
  var users = [];
  for (var i in usergroups) {
    users.push({
      name: usergroups[i].substr(1).replace(/,/g, ''),
      group: usergroups[i].substr(0, 1)
    });
  }
  users.forEach(function(user) {
    User.findOne({ name: user.name.toLowerCase() }, function(err, userModel) {
      if (err) return;
      if (!userModel) {
        user = new User({
          name: user.name,
          group: user.group
        });
        return user.save(function(err) {
          if (err) return err;
        });
      }
      userModel.group = user.group;
      userModel.save(function(err) {
        if (err) return;
      });
    });
  });
};
<commit_msg>Fix demotion to regular user<commit_after>var mongoose = require('mongoose');

var userSchema = new mongoose.Schema({
  name: { type: String, lowercase: true },
  group: String
});

var User = exports.User = mongoose.model('user', userSchema);

exports.connect_database = function() {
  var url = process.env.MONGODB || 'mongodb://localhost:27017/ps';
  mongoose.connect(url);
  mongoose.connection.on('error', function() {
    console.error('MongoDB Connection Error. Make sure MongoDB is running.');
  });
};

exports.importUsergroups = function(usergroups, Config) {
  User.find({}, function(err, users) {
    if (err) return;
    users.forEach(function(user) {
      usergroups[user.name] =  (user.group || Config.groupsranking[0]) + user.name;
    });
  });
};

exports.exportUsergroups = function(usergroups) {
  var users = [];
  for (var i in usergroups) {
    users.push({
      name: usergroups[i].substr(1).replace(/,/g, ''),
      group: usergroups[i].substr(0, 1)
    });
  }
  users.forEach(function(user) {
    User.findOne({ name: user.name.toLowerCase() }, function(err, userModel) {
      if (err) return;
      if (!userModel) {
        user = new User({
          name: user.name,
          group: user.group
        });
        return user.save(function(err) {
          if (err) return err;
        });
      }
      userModel.group = user.group;
      userModel.save(function(err) {
        if (err) return;
      });
    });
  });
  users = users.map(function(user) {
    return user.name;
  });
  User.find({}, function(err, usersModel) {
    if (err) return;
    usersModel.forEach(function(user) {
      if (users.indexOf(user.name) < 0) {
        User.findOne({name: user.name}, function(err, user) {
          if (err) return;
          user.group = '';
          user.save(function(err) {
            if (err) return;
          });
        });
      }
    });
  });
};
<|endoftext|>