<commit_before>"use strict";
/*
 * gconfig
 * https://github.com/goliatone/gconfig
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/* jshint strict: false, plusplus: true */
/*global define: false, require: false, module: false, exports: false */
(function (root, name, deps, factory) {

    // Node
    if(typeof deps === 'function') {
        factory = deps;
        deps = [];
    }

    if (typeof exports === 'object') {
        module.exports = factory.apply(root, deps.map(require));
    } else if (typeof define === 'function' && 'amd' in define) {
        //require js, here we assume the file is named as the lower
        //case module name.
        define(name.toLowerCase(), deps, factory);
    } else {
        // Browser
        var d, i = 0, global = root, old = global[name], mod;
        while((d = deps[i]) !== undefined) deps[i++] = root[d];
        global[name] = mod = factory.apply(global, deps);
        //Export no 'conflict module', aliases the module.
        mod.noConflict = function(){
            global[name] = old;
            return mod;
        };
    }
}(this, 'GConfig', function() {

    /**
     * Extend method.
     * @param  {Object} target Source object
     * @return {Object}        Resulting object from
     *                         meging target to params.
     */
    var _extend = function(target) {
        var i = 1, length = arguments.length, source;
        for ( ; i < length; i++ ) {
            // Only deal with defined values
            if ((source = arguments[i]) != undefined ){
                Object.getOwnPropertyNames(source).forEach(function(k){
                    var d = Object.getOwnPropertyDescriptor(source, k) || {value:source[k]};
                    if (d.get) {
                        target.__defineGetter__(k, d.get);
                        if (d.set) target.__defineSetter__(k, d.set);
                    } else if (target !== d.value) target[k] = d.value;
                });
            }
        }
        return target;
    };

    var _map = function(arr, done) {
        var i    = -1,
            len  = arr.length,
            args = Array.prototype.slice.call(arguments, 2);
        (function next(result) {
            var each,
                async,
                abort = (typeof result === 'boolean');

            do{ ++i; } while (!(i in arr) && i !== len);

            if (abort || i === len) {
                if(done) return done(result);
            }

            each = arr[i];
            result = each.apply({
                async: function() {
                    async = true;
                    return next;
                }
            }, args);

            if (!async) next(result);
        }());
    };

    var options = {
        //http://stackoverflow.com/questions/7602410/how-do-i-find-elements-that-contain-a-data-attribute-matching-a-prefix-using-j
        selector:'meta[name^="::NAMESPACE::-"]',
        namespace:'app'
    };

///////////////////////////////////////////////////
// CONSTRUCTOR
///////////////////////////////////////////////////

    /**
     * GConfig constructor
     *
     * @param  {object} config Configuration object.
     */
    var GConfig = function(config){

        config  = config || {};

        config = _extend({}, GConfig.defaults || options, config);

        this.data = {};
        this.meta = document.getElementsByTagName('meta');

        this.namespaces = [];
        this.options = options;
        this.namespace = options.namespace;

        //TODO: Should we do methods instead of strings?
        this.loaders = ['loadMedatada'];
        this.loadMedatada.async = false;

        this.initialized = false;

        this.init(config);
    };

    GConfig.defaults = options;

///////////////////////////////////////////////////
// PRIVATE METHODS
///////////////////////////////////////////////////

    /**
     * Method that triggers data loaders.
     * By default, we use `loadMetadata` a
     * synchronous loader.
     * @return {GConfig}    Fluid interface.
     */
    GConfig.prototype.getConfig = function( )
    {
        //TODO: We should provide a next to each loader
        //to step forward on the chain.
        var onLoadersDone = function(){
            console.log('DONE!!!')
        }.bind(this);
        _map(this.loaders, onLoadersDone, this);

        this.loaders.forEach(function(loader){
            this[loader].call(this);
        }, this);
        this.onConfigLoaded();
    };

    /**
     * TODO: Return promise or emit on done.
     * Method to update the meta object, from the meta NodeList
     */
    GConfig.prototype.loadMedatada = function( )
    {
        var key = null, val = null, nsp = null;

        var meta = this.meta || (this.meta = document.getElementsByTagName('meta'));

        // search desired tag
        for( var i = 0, l = meta.length; i < l; i++ )
        {
            key = meta[i].name || meta[i].getAttribute('property');
            // this.log('meta name: %s :: %s ', key, meta[i].content);

            //no key?
            if(!key) continue;

            //we have a regular meta, skip
            if( key.indexOf(':') === -1 ) continue;

            nsp = key.split(':')[0];
            key = key.split(':')[1];
            val = meta[i].content;

            //trigger callback
            // addMetaCallback(key, val, nsp);
            this.set(key, val, nsp);
        }
    };

    GConfig.prototype.onConfigLoaded = function(){
        /*setTimeout((function(){
            this.emit('ondata');
        }).bind(this), 0);*/
    };

    GConfig.prototype.init = function(config){
        if(this.initialized) return;
        this.initialized = true;

        _extend(this, config);

        this.getConfig( );
        this.log('META: ', this.data);
    };

    /**
     * Extends GConfig's prototype. Use it to add
     * functionality or to override methods. The
     * idea is to support a plugin architecture.
     * @param  {Object} ext Object which's properties and
     *                      methods will get merged into
     *                      GConfig's prototype
     * @return {GConfig}    Fluid interface.
     */
    GConfig.prototype.use = function(ext){

        if(typeof ext === 'function') ext(GConfig);
        else if('register' in ext &&
            typeof ext.register === 'function') ext.register(GConfig);
        else if(typeof ext === 'object') _extend(GConfig.prototype, ext);

        return this;
    };

    /**
     * It will extend the provided object with the
     * matching configuration object under the given
     * namespace.
     * If no namespace is provided, the default one
     * will be used.
     * TODO: Do we want to return GConfig or provided
     * source object? Which should be the chain's subject?
     *
     * @param  {Object} object    Object to be config.
     * @param  {String} namespace Namespace id
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.configure = function(object, namespace){
        _extend(object, this.getNamespace(namespace));
        return this;
    };

    /**
     * Extend the identified namespace with the
     * given object.
     *
     * @param  {Object} object    Object to be merged.
     * @param  {String} namespace Namespace id.
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.merge = function(object, namespace){
        _extend(this.getNamespace(namespace), object);
        return this;
    };

    /**
     * Set a key value under the given namespace
     * @param {String} key       Property value
     * @param {Object} value     Value to be added
     * @param  {String} namespace Namespace id
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.set = function(key, value, namespace){
        //TODO: Make bindable.
        this.log('Adding: %s::%s under %s.', key, value, namespace);
        namespace || (namespace = this.namespace);
        if(!(namespace in this.data)) this.data[namespace] = {};
        this.data[namespace][key] = value;
        return this;
    };

    /**
     * Get a value by key, we can provide a default
     * value in case the key is not registered.
     * @param  {String} key          Key
     * @param  {Object} defaultValue Default value
     * @param  {String} namespace Namespace id
     * @return {Object}           Key value
     */
    GConfig.prototype.get = function(key, defaultValue, namespace){
        namespace || (namespace = this.namespace);
        if(!(namespace in this.data) || !(key in this.data[namespace]))
            return defaultValue;
        return this.data[namespace][key];
    };

    /**
     * Returns a clone of the configuration object
     * identified by `namespace` id.
     * If no namespace id is provided, default is used.
     * We can also pass a second argument to indicate
     * if we want to get a clone of the namespace object
     * or the actual reference.
     *
     * @param  {String} namespace   Namespace id
     * @param  {Boolean} clone      Should we clone namespace
     * @return {Object}             Namespace object.
     */
    GConfig.prototype.getNamespace = function(namespace, clone){
        namespace || (namespace = this.namespace);

        if(!(namespace in this.data)){
            if(typeof clone === 'object') return clone;
            return {};
        }

        if(clone) return _extend({}, this.data[namespace]);

        return this.data[namespace];
    };

    /**
     * Simple log implementation.
     */
    GConfig.prototype.log = function(){
        if('debug' in this && this.debug === false) return;
        console.log.apply(console, arguments);
    };

    //This will eventually be deprecated!
    GConfig.prototype.addMeta = GConfig.prototype.set;
    GConfig.prototype.getMeta = GConfig.prototype.get;

    return GConfig;
}));<commit_msg>GConfig: Updated loader management, works asysnc.<commit_after>"use strict";
/*
 * gconfig
 * https://github.com/goliatone/gconfig
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/* jshint strict: false, plusplus: true */
/*global define: false, require: false, module: false, exports: false */
(function (root, name, deps, factory) {

    // Node
    if(typeof deps === 'function') {
        factory = deps;
        deps = [];
    }

    if (typeof exports === 'object') {
        module.exports = factory.apply(root, deps.map(require));
    } else if (typeof define === 'function' && 'amd' in define) {
        //require js, here we assume the file is named as the lower
        //case module name.
        define(name.toLowerCase(), deps, factory);
    } else {
        // Browser
        var d, i = 0, global = root, old = global[name], mod;
        while((d = deps[i]) !== undefined) deps[i++] = root[d];
        global[name] = mod = factory.apply(global, deps);
        //Export no 'conflict module', aliases the module.
        mod.noConflict = function(){
            global[name] = old;
            return mod;
        };
    }
}(this, 'GConfig', function() {

    /**
     * Extend method.
     * @param  {Object} target Source object
     * @return {Object}        Resulting object from
     *                         meging target to params.
     */
    var _extend = function(target) {
        var i = 1, length = arguments.length, source;
        for ( ; i < length; i++ ) {
            // Only deal with defined values
            if ((source = arguments[i]) != undefined ){
                Object.getOwnPropertyNames(source).forEach(function(k){
                    var d = Object.getOwnPropertyDescriptor(source, k) || {value:source[k]};
                    if (d.get) {
                        target.__defineGetter__(k, d.get);
                        if (d.set) target.__defineSetter__(k, d.set);
                    } else if (target !== d.value) target[k] = d.value;
                });
            }
        }
        return target;
    };

    var _map = function(arr, done) {
        var i    = -1,
            len  = arr.length,
            args = Array.prototype.slice.call(arguments, 2);
        (function next(result) {
            var each,
                async,
                abort = (typeof result === 'boolean');

            do{ ++i; } while (!(i in arr) && i !== len);

            if (abort || i === len) {
                if(done) return done(result);
            }

            each = arr[i];
            result = each.apply({
                async: function() {
                    async = true;
                    return next;
                }
            }, args);

            if (!async) next(result);
        }());
    };

    var options = {
        //http://stackoverflow.com/questions/7602410/how-do-i-find-elements-that-contain-a-data-attribute-matching-a-prefix-using-j
        selector:'meta[name^="::NAMESPACE::-"]',
        namespace:'app'
    };

///////////////////////////////////////////////////
// CONSTRUCTOR
///////////////////////////////////////////////////

    /**
     * GConfig constructor
     *
     * @param  {object} config Configuration object.
     */
    var GConfig = function(config){

        config  = config || {};

        config = _extend({}, GConfig.defaults || options, config);

        this.data = {};
        this.meta = document.getElementsByTagName('meta');

        this.namespaces = [];
        this.options = options;
        this.namespace = options.namespace;

        //TODO: Should we do methods instead of strings?
        //this.loaders = ['loadMedatada'];
        this.loaders = [this.loadMedatada.bind(this)];
        this.loadMedatada.async = false;

        this.initialized = false;

        this.init(config);
    };

    GConfig.defaults = options;

///////////////////////////////////////////////////
// PRIVATE METHODS
///////////////////////////////////////////////////

    /**
     * Method that triggers data loaders.
     * By default, we use `loadMetadata` a
     * synchronous loader.
     * @return {GConfig}    Fluid interface.
     */
    GConfig.prototype.getConfig = function( )
    {
        //TODO: We should provide a next to each loader
        //to step forward on the chain.
        var onLoadersDone = function(){
            this.onConfigLoaded();
        }.bind(this);

        _map(this.loaders, onLoadersDone, this);
    };

    /**
     * TODO: Return promise or emit on done.
     * Method to update the meta object, from the meta NodeList
     */
    GConfig.prototype.loadMedatada = function( )
    {
        var key = null, val = null, nsp = null;

        var meta = this.meta || (this.meta = document.getElementsByTagName('meta'));

        // search desired tag
        for( var i = 0, l = meta.length; i < l; i++ )
        {
            key = meta[i].name || meta[i].getAttribute('property');
            // this.log('meta name: %s :: %s ', key, meta[i].content);

            //no key?
            if(!key) continue;

            //we have a regular meta, skip
            if( key.indexOf(':') === -1 ) continue;

            nsp = key.split(':')[0];
            key = key.split(':')[1];
            val = meta[i].content;

            //trigger callback
            // addMetaCallback(key, val, nsp);
            this.set(key, val, nsp);
        }
    };

    GConfig.prototype.onConfigLoaded = function(){
        /*setTimeout((function(){
            this.emit('ondata');
        }).bind(this), 0);*/
    };

    GConfig.prototype.init = function(config){
        if(this.initialized) return;
        this.initialized = true;

        _extend(this, config);

        this.getConfig( );
        this.log('META: ', this.data);
    };

    /**
     * Extends GConfig's prototype. Use it to add
     * functionality or to override methods. The
     * idea is to support a plugin architecture.
     * @param  {Object} ext Object which's properties and
     *                      methods will get merged into
     *                      GConfig's prototype
     * @return {GConfig}    Fluid interface.
     */
    GConfig.prototype.use = function(ext){

        if(typeof ext === 'function') ext(GConfig);
        else if('register' in ext &&
            typeof ext.register === 'function') ext.register(GConfig);
        else if(typeof ext === 'object') _extend(GConfig.prototype, ext);

        return this;
    };

    /**
     * It will extend the provided object with the
     * matching configuration object under the given
     * namespace.
     * If no namespace is provided, the default one
     * will be used.
     * TODO: Do we want to return GConfig or provided
     * source object? Which should be the chain's subject?
     *
     * @param  {Object} object    Object to be config.
     * @param  {String} namespace Namespace id
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.configure = function(object, namespace){
        _extend(object, this.getNamespace(namespace));
        return this;
    };

    /**
     * Extend the identified namespace with the
     * given object.
     *
     * @param  {Object} object    Object to be merged.
     * @param  {String} namespace Namespace id.
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.merge = function(object, namespace){
        _extend(this.getNamespace(namespace), object);
        return this;
    };

    /**
     * Set a key value under the given namespace
     * @param {String} key       Property value
     * @param {Object} value     Value to be added
     * @param  {String} namespace Namespace id
     * @return {GConfig}          Fluid interface.
     */
    GConfig.prototype.set = function(key, value, namespace){
        //TODO: Make bindable.
        this.log('Adding: %s::%s under %s.', key, value, namespace);
        namespace || (namespace = this.namespace);
        if(!(namespace in this.data)) this.data[namespace] = {};
        this.data[namespace][key] = value;
        return this;
    };

    /**
     * Get a value by key, we can provide a default
     * value in case the key is not registered.
     * @param  {String} key          Key
     * @param  {Object} defaultValue Default value
     * @param  {String} namespace Namespace id
     * @return {Object}           Key value
     */
    GConfig.prototype.get = function(key, defaultValue, namespace){
        namespace || (namespace = this.namespace);
        if(!(namespace in this.data) || !(key in this.data[namespace]))
            return defaultValue;
        return this.data[namespace][key];
    };

    /**
     * Returns a clone of the configuration object
     * identified by `namespace` id.
     * If no namespace id is provided, default is used.
     * We can also pass a second argument to indicate
     * if we want to get a clone of the namespace object
     * or the actual reference.
     *
     * @param  {String} namespace   Namespace id
     * @param  {Boolean} clone      Should we clone namespace
     * @return {Object}             Namespace object.
     */
    GConfig.prototype.getNamespace = function(namespace, clone){
        namespace || (namespace = this.namespace);

        if(!(namespace in this.data)){
            if(typeof clone === 'object') return clone;
            return {};
        }

        if(clone) return _extend({}, this.data[namespace]);

        return this.data[namespace];
    };

    /**
     * Simple log implementation.
     */
    GConfig.prototype.log = function(){
        if('debug' in this && this.debug === false) return;
        console.log.apply(console, arguments);
    };

    //This will eventually be deprecated!
    GConfig.prototype.addMeta = GConfig.prototype.set;
    GConfig.prototype.getMeta = GConfig.prototype.get;

    return GConfig;
}));<|endoftext|>


<commit_before>var d3plus = window.d3plus || {};
window.d3plus = d3plus;

d3plus.version = "1.1.2 - Navy";

d3plus.ie = /*@cc_on!@*/false;

d3plus.fontawesome = false

var sheets = document.styleSheets

for (var s = 0; s < sheets.length; s++) {
  if (sheets[s].href && sheets[s].href.indexOf("font-awesome") >= 0) {
    d3plus.fontawesome = true
    break;
  }
}

d3plus.rtl = d3.select("html").attr("dir") == "rtl"

d3plus.scrollbar = function() {

  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild(inner);

  document.body.appendChild(outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild(outer);

  var val = (w1 - w2)

  d3plus.scrollbar = function(){
    return val
  }

  return val;

}

d3.select(window).on("load.d3plus_scrollbar",function(){
  d3plus.scrollbar()
})

d3plus.evt = {}; // stores all mouse events that could occur

// Modernizr touch events
if (window.Modernizr && Modernizr.touch) {
  d3plus.evt.click = "touchend"
  d3plus.evt.down = "touchstart"
  d3plus.evt.up = "touchend"
  d3plus.evt.over = "touchstart"
  d3plus.evt.out = "touchend"
  d3plus.evt.move = "touchmove"
} else {
  d3plus.evt.click = "click"
  d3plus.evt.down = "mousedown"
  d3plus.evt.up = "mouseup"
  if (d3plus.ie) {
    d3plus.evt.over = "mouseenter"
    d3plus.evt.out = "mouseleave"
  }
  else {
    d3plus.evt.over = "mouseover"
    d3plus.evt.out = "mouseout"
  }
  d3plus.evt.move = "mousemove"
}

// Modernizr SVG Capable Detect
d3plus.svg = true
if (window.Modernizr && Modernizr.svg === false) {
  d3plus.svg = false
}

d3plus.apps = {};
d3plus.color = {};
d3plus.console = {};
d3plus.data = {};
d3plus.forms = {};
d3plus.info = {};
d3plus.shape = {};
d3plus.styles = {};
d3plus.tooltip = {};
d3plus.utils = {};
d3plus.variable = {};
d3plus.zoom = {};

d3plus.console.print = function(type,message,style) {
  if (d3plus.ie) console.log("[d3plus] "+message)
  else console[type]("%c[d3plus]%c "+message,"font-weight:bold;",style)
}
d3plus.console.log = function(message,style) {
  if (!style) var style = "font-weight:bold;"
  d3plus.console.print("log",message,style)
}
d3plus.console.group = function(message,style) {
  if (!style) var style = "font-weight:bold;"
  d3plus.console.print("group",message,style)
}
d3plus.console.warning = function(message,style) {
  if (!style) var style = "font-weight:bold;color:red;"
  message = "WARNING: "+message
  d3plus.console.print("log",message,style)
}
d3plus.console.groupEnd = function() {
  if (!d3plus.ie) console.groupEnd()
}
d3plus.console.time = function(message) {
  if (!d3plus.ie) console.time(message)
}
d3plus.console.timeEnd = function(message) {
  if (!d3plus.ie) console.timeEnd(message)
}
<commit_msg>updated version to 1.1.3<commit_after>var d3plus = window.d3plus || {};
window.d3plus = d3plus;

d3plus.version = "1.1.3 - Navy";

d3plus.ie = /*@cc_on!@*/false;

d3plus.fontawesome = false

var sheets = document.styleSheets

for (var s = 0; s < sheets.length; s++) {
  if (sheets[s].href && sheets[s].href.indexOf("font-awesome") >= 0) {
    d3plus.fontawesome = true
    break;
  }
}

d3plus.rtl = d3.select("html").attr("dir") == "rtl"

d3plus.scrollbar = function() {

  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild(inner);

  document.body.appendChild(outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild(outer);

  var val = (w1 - w2)

  d3plus.scrollbar = function(){
    return val
  }

  return val;

}

d3.select(window).on("load.d3plus_scrollbar",function(){
  d3plus.scrollbar()
})

d3plus.evt = {}; // stores all mouse events that could occur

// Modernizr touch events
if (window.Modernizr && Modernizr.touch) {
  d3plus.evt.click = "touchend"
  d3plus.evt.down = "touchstart"
  d3plus.evt.up = "touchend"
  d3plus.evt.over = "touchstart"
  d3plus.evt.out = "touchend"
  d3plus.evt.move = "touchmove"
} else {
  d3plus.evt.click = "click"
  d3plus.evt.down = "mousedown"
  d3plus.evt.up = "mouseup"
  if (d3plus.ie) {
    d3plus.evt.over = "mouseenter"
    d3plus.evt.out = "mouseleave"
  }
  else {
    d3plus.evt.over = "mouseover"
    d3plus.evt.out = "mouseout"
  }
  d3plus.evt.move = "mousemove"
}

// Modernizr SVG Capable Detect
d3plus.svg = true
if (window.Modernizr && Modernizr.svg === false) {
  d3plus.svg = false
}

d3plus.apps = {};
d3plus.color = {};
d3plus.console = {};
d3plus.data = {};
d3plus.forms = {};
d3plus.info = {};
d3plus.shape = {};
d3plus.styles = {};
d3plus.tooltip = {};
d3plus.utils = {};
d3plus.variable = {};
d3plus.zoom = {};

d3plus.console.print = function(type,message,style) {
  if (d3plus.ie) console.log("[d3plus] "+message)
  else console[type]("%c[d3plus]%c "+message,"font-weight:bold;",style)
}
d3plus.console.log = function(message,style) {
  if (!style) var style = "font-weight:bold;"
  d3plus.console.print("log",message,style)
}
d3plus.console.group = function(message,style) {
  if (!style) var style = "font-weight:bold;"
  d3plus.console.print("group",message,style)
}
d3plus.console.warning = function(message,style) {
  if (!style) var style = "font-weight:bold;color:red;"
  message = "WARNING: "+message
  d3plus.console.print("log",message,style)
}
d3plus.console.groupEnd = function() {
  if (!d3plus.ie) console.groupEnd()
}
d3plus.console.time = function(message) {
  if (!d3plus.ie) console.time(message)
}
d3plus.console.timeEnd = function(message) {
  if (!d3plus.ie) console.timeEnd(message)
}
<|endoftext|>


<commit_before>function mapWorker(fun,callback,onerr){
	if(typeof Worker === 'undefined'){
		return fakeMapWorker(fun,callback,onerr);
	}
	onerr = onerr || function(){callback();};
	var w = new Communist();
	var obj = {__func__:fun};
	obj.data = function(data){
		var that = this;
		var cb = function(data,transform){
			that.fire('data',data,transform);
		};
		var resp = that.__func__(data);
		if(resp !== "undefined"){
			cb(resp);
		}
	};
	obj.start = function(){
		this.on('data',function(data){
			this.data(data);
		});
	};
	var worker = c.communist(obj);
	var startIt = function(){
		worker.start().then(function(){},function(e){
			onerr(e);
			startIt();
		});
	};
	w.data=function(data,transfer){
		worker.fire('data',data,transfer);
		return w;
	};
	w.close=function(){
		return worker.close();
	};
	return w;
}<commit_msg>that's not a function on this branch yet<commit_after>function mapWorker(fun,callback,onerr){
	if(typeof Worker === 'undefined'){
		return fakeMapWorker(fun,callback,onerr);
	}
	onerr = onerr || function(){callback();};
	var w = new Communist();
	var obj = {__func__:fun};
	obj.data = function(data){
		var that = this;
		var cb = function(data,transform){
			that.fire('data',data,transform);
		};
		var resp = that.__func__(data);
		if(resp !== "undefined"){
			cb(resp);
		}
	};
	obj.start = function(){
		this.on('data',function(data){
			this.data(data);
		});
	};
	var worker = object(obj);
	var startIt = function(){
		worker.start().then(function(){},function(e){
			onerr(e);
			startIt();
		});
	};
	w.data=function(data,transfer){
		worker.fire('data',data,transfer);
		return w;
	};
	w.close=function(){
		return worker.close();
	};
	return w;
}<|endoftext|>


<commit_before>/**
 * Abstract superclass for closed geometric shapes,
 * such as Polygon or Circle.
 * The buildPath() method must be overriden to define
 * the shape to be drawn.
 *
 * Copyright (c) 2013 Marshall Farrier
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Dependencies:
 * extend.js
 */

var _c = _c || {};

(function(_c) {
    "use strict";

    _c.draw = _c.draw || {};
    _c.draw.Shape = _c.Base.extend({
        init: function(params) {
            this.styles = params.styles || {};
        },

        render: function(context, callback) {
            this.buildPath(context);
            callback();
        },

        clip: function(context, callback) {
            this.render(context, function() {
                context.clip();
                callback();
            });
        },

        fill: function(context) {
            var _this = this;

            this.render(context, function() {
                if (_this.styles.fillStyle) context.fillStyle = _this.styles.fillStyle;
                context.fill();
            });
        },

        stroke: function(context) {
            var _this = this;

            this.render(context, function() {
                if (_this.styles.strokeStyle) context.strokeStyle = _this.styles.strokeStyle;
                if (_this.styles.lineWidth) context.lineWidth = _this.styles.lineWidth;
                context.stroke();
            });
        },

        draw: function(context) {
            _c.draw.paint(this, this.render, context);
        },

        drawClipped: function(context) {
            _c.draw.paint(this, this.clip, context);
        },

        /**
         * prep the context by setting strokeStyle, lineWidth and
         * fillStyle.
         */
        prep: function(context) {
            for (var style in this.styles) {
                context[style] = this.styles[style];
            }
        },

        /**
         * abstract method
         */
        buildPath: function(context) {
            alert('Subclasses must override buildPath()!');
        }
    });
})(_c);
<commit_msg>Wrap Shape#drawClipped() in a save/restore block<commit_after>/**
 * Abstract superclass for closed geometric shapes,
 * such as Polygon or Circle.
 * The buildPath() method must be overriden to define
 * the shape to be drawn.
 *
 * Copyright (c) 2013 Marshall Farrier
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Dependencies:
 * extend.js
 */

var _c = _c || {};

(function(_c) {
    "use strict";

    _c.draw = _c.draw || {};
    _c.draw.Shape = _c.Base.extend({
        init: function(params) {
            this.styles = params.styles || {};
        },

        render: function(context, callback) {
            this.buildPath(context);
            callback();
        },

        clip: function(context, callback) {
            this.render(context, function() {
                context.clip();
                callback();
            });
        },

        fill: function(context) {
            var _this = this;

            this.render(context, function() {
                if (_this.styles.fillStyle) context.fillStyle = _this.styles.fillStyle;
                context.fill();
            });
        },

        stroke: function(context) {
            var _this = this;

            this.render(context, function() {
                if (_this.styles.strokeStyle) context.strokeStyle = _this.styles.strokeStyle;
                if (_this.styles.lineWidth) context.lineWidth = _this.styles.lineWidth;
                context.stroke();
            });
        },

        draw: function(context) {
            _c.draw.paint(this, this.render, context);
        },

        /**
         * Wrapped in a save() - restore() block to avoid clipping next drawing
         */
        drawClipped: function(context) {
            context.save();
            _c.draw.paint(this, this.clip, context);
            context.restore();
        },

        /**
         * prep the context by setting strokeStyle, lineWidth and
         * fillStyle.
         */
        prep: function(context) {
            for (var style in this.styles) {
                context[style] = this.styles[style];
            }
        },

        /**
         * abstract method
         */
        buildPath: function(context) {
            alert('Subclasses must override buildPath()!');
        }
    });
})(_c);
<|endoftext|>


<commit_before>/**
 * @file Tip component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import Theme from '../Theme';

import Position from '../_statics/Position';

import Util from '../_vendors/Util';

class Tip extends Component {

    static Position = Position;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    render() {

        const {className, contentClassName, ...restProps} = this.props,

            tipClassName = classNames('tip', {
                [className]: className
            }),

            tipContentClassName = classNames('tip-content', {
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        className={tipClassName}
                        contentClassName={tipContentClassName}/>
        );
    }

}

Tip.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true, menu will have animation effects.
     */
    isAnimated: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isTriggerPositionFixed: PropTypes.bool,
    showModal: PropTypes.bool,

    /**
     * The function of tip render.
     */
    onRender: PropTypes.func,

    /**
     * The function of tip rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of tip destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of tip destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Tip.defaultProps = {

    theme: Theme.DARK,

    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    showModal: false

};

export default Tip;<commit_msg>update Tip<commit_after>/**
 * @file Tip component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import Theme from '../Theme';

import Position from '../_statics/Position';

import Util from '../_vendors/Util';

class Tip extends Component {

    static Position = Position;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    render() {

        const {className, contentClassName, ...restProps} = this.props,

            tipClassName = classNames('tip', {
                [className]: className
            }),

            tipContentClassName = classNames('tip-content', {
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        className={tipClassName}
                        contentClassName={tipContentClassName}/>
        );
    }

}

Tip.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true, menu will have animation effects.
     */
    isAnimated: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isTriggerPositionFixed: PropTypes.bool,
    resetPositionWait: PropTypes.number,
    showModal: PropTypes.bool,

    /**
     * The function of tip render.
     */
    onRender: PropTypes.func,

    /**
     * The function of tip rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of tip destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of tip destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Tip.defaultProps = {

    theme: Theme.DARK,

    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    resetPositionWait: 250,
    showModal: false

};

export default Tip;
<|endoftext|>


<commit_before>/**
 * Utility functions for handling address objects.
 * An address is expected to contain:
 *   addressLine1: string,
 *   addressLine2: string, (optional)
 *   zip: string
 *
 *   A full list of potentially available data can be found at:
 *   https://bristol.cyclos.org/bristolpoundsandbox03/api#!/Addresses/viewAddress
 */

function addressToString (address) {
	const addressLine2 = [address.buildingNumber, address.street].filter(a => a).join(', ');
  	return [address.addressLine1, addressLine2, address.addressLine3, address.zip]
    	.filter(a => a)
    	.join(', ')
}

export default addressToString

<commit_msg>fix address to includ townOrCity (API v1.1.1)<commit_after>/**
 * Utility functions for handling address objects.
 * An address is expected to contain:
 *   addressLine1: string,
 *   addressLine2: string, (optional)
 *   zip: string
 *
 *   A full list of potentially available data can be found at:
 *   https://bristol.cyclos.org/bristolpoundsandbox03/api#!/Addresses/viewAddress
 */

function addressToString (address) {
	const addressLine2 = [address.buildingNumber, address.street].filter(a => a).join(', ');
  	return [address.addressLine1, addressLine2, address.addressLine3, address.townOrCity, address.postcode]
    	.filter(a => a)
    	.join(', ')
}

export default addressToString

<|endoftext|>


<commit_before>var ContentStore = {
  findxx: function() {
    return (
      {"sections": [
        {
          "id": "de5f",
          "blocks": [
            {
              "id": "56ef",
              "type": "h2",
              "tag": "h2",
              "text": "Page Title"
            },
            {
              "id": "667a",
              "type": "p",
              "tag": "p",
              "text": "Build your page here"
            }
          ]
        }
      ]}
    );
  },
  find: function() {
    return (
      {"sections": [
        {
          "id": "de5f",
          "blocks": [
            {
              "id": "56ef",
              "type": "h2",
              "tag": "h2",
              "text": "History of Photography"
            },
            {
              "id": "667a",
              "type": "p",
              "tag": "p",
              "text": "Photography is a word derived from the Greek words photos (“light”) and graphein (“to draw”) The word was first used by the scientist Sir John F.W. Herschel in 1839."
            },
            {
              "id": "7421",
              "type": "figure",
              "tag": "figure",
              "src": "http://tmp.derekdevries.com/daguerrotype.jpg",
              "width": 1370,
              "height": 709,
              "text": "Daguerrotype"
            },
            {
              "id": "67a3",
              "type": "p",
              "tag": "p",
              "text": "The metal-based daguerreotype process soon had some competition from the paper-based calotype negative and salt print processes invented by Henry Fox Talbot."
            },
            {
              "id": "667b",
              "type": "blockquote",
              "tag": "blockquote",
              "text": "For me, the camera is a sketch book, an instrument of intuition and spontaneity."
            },
            {
              "id": "7314",
              "type": "p",
              "tag": "p",
              "text": "The history of photography has roots in remote antiquity with the discovery of the principle of the camera obscura and the observation that some substances are visibly altered by exposure to light. As far as is known, nobody thought of bringing these two phenomena together to capture camera images in permanent form until around 1800, when Thomas Wedgwood made the first reliably documented although unsuccessful attempt."
            },
          ]
        },
        {
          "id": "0fb3",
          "blocks": [
            {
              "id": "7315",
              "type": "p",
              "tag": "p",
              "text": "In the mid-1820s, Nicéphore Niépce succeeded, but several days of exposure in the camera were required and the earliest results were very crude. Niépce's associate Louis Daguerre went on to develop the daguerreotype process, the first publicly announced photographic process, which required only minutes of exposure in the camera and produced clear, finely detailed results. It was commercially introduced in 1839, a date generally accepted as the birth year of practical photography"
            },
            {
              "id": "74ca",
              "type": "figure",
              "tag": "figure",
              "src": "https://www.youtube.com/embed/oK6JW1prwTw",
              "text": "The First Photographer: The Photographs of Nicéphore Niépce"
            },
            {
              "id": "c277",
              "type": "h3",
              "tag": "h3",
              "text": "Pinhole Camera"
            },
            {
              "id": "cca9",
              "type": "p",
              "tag": "p",
              "text": "Alhazen (Ibn Al-Haytham), a great authority on optics in the Middle Ages who lived around 1000AD, invented the first pinhole camera, (also called the Camera Obscura and was able to explain why the images were upside down."
            },
            {
              "id": "a141",
              "type": "h4",
              "tag": "h4",
              "text": "The First Photograph"
            },
            {
              "id": "59b1",
              "type": "ul",
              "tag": "ul",
              "blocks": [
                {
                  "id": "4007",
                  "type": "li",
                  "tag": "li",
                  "text": "Joseph Nicephore Niepce"
                },
                {
                  "id": "4ca9",
                  "type": "li",
                  "tag": "li",
                  "text": "View from an upstairs window at Niépce's estate"
                }
              ]
            },
            {
              "id": "fce3",
              "type": "h4",
              "tag": "h4",
              "text": "Alfred Steiglitz"
            },
            {
              "id": "dc62",
              "type": "ol",
              "tag": "ol",
              "blocks": [
                {
                  "id": "f5a4",
                  "type": "li",
                  "tag": "li",
                  "text": "Early years (1864–1890)"
                },
                {
                  "id": "cc96",
                  "type": "li",
                  "tag": "li",
                  "text": "New York and the Camera Club (1891–1901)"
                }
              ]
            },
            {
              "id": "d8c1",
              "type": "figure",
              "tag": "figure",
              "src": "http://tmp.derekdevries.com/clay-henry.jpg",
              "width": 400,
              "height": 500,
              "text": ""
            }
          ]
        },
        {
          "id": "9fb3",
          "blocks": [
            {
              "id": "6353",
              "type": "p",
              "tag": "p",
              "text": "Development of Photography as a Technology in different eras",
              "meta": {
                "align": "center"
              }
            },
            {
              "id": "e07e",
              "type": "p",
              "tag": "p",
              "text": "The metal-based daguerreotype process soon had some competition from the paper-based calotype negative and salt print processes invented by Henry Fox Talbot. Subsequent innovations reduced the required camera exposure time from minutes to seconds and eventually to a small fraction of a second",
              "markups": {
                "a": [{
                  "range": [16,29], "value": "http://google.com"
                }]
              }
            },
            {
              "id": "1532",
              "type": "pre",
              "tag": "pre",
              "text": "(ns markov-elear.core-test\n  (:require [clojure.test :refer :all]\n            [markov-elear.core :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))"
            },
            {
              "id": "1d6e",
              "type": "p",
              "tag": "p",
              "text": "Photography is the result of combining several different technical discoveries.",
              "markups": {
                "strong": [{
                  "range": [67,79]
                }]
              }
            },
            {
              "id": "1d6b",
              "type": "p",
              "tag": "p",
              "text": "photos!",
              "markups": {
                "strong": [{
                  "range": [0,7]
                }]
              }
            },
            {
              "id": "1d6d",
              "type": "p",
              "tag": "p",
              "text": "Long before the first photographs were made, Chinese philosopher Mo Ti and Greek mathematicians Aristotle and Euclid described a pinhole camera in the 5th and 4th centuries BCE.",
              "markups": {
                "strong": [{
                  "range": [0,4]
                }],
                "em": [{
                  "range": [22,33]
                }]
              }
            },
            {
              "id": "1d6c",
              "type": "p",
              "tag": "p",
              "text": "In 1833 Niépce died suddenly, leaving his notes to Daguerre.",
              "markups": {
                "strong": [{
                  "range": [0,7]
                }]
              }
            },

            {
              "id": "067c",
              "type": "blockquote",
              "tag": "blockquote",
              "text": "Today everything exists to end in a photograph.",
              "meta": {
                "align": "center"
              }
            },
            {
              "id": "e5fe",
              "type": "p",
              "tag": "p",
              "text": " And more paragraphs of text that are escaped "
            },
            {
              "id": "e5ff",
              "type": "p",
              "tag": "p",
              "text": "And that can combine both markup and escaped",
              "markups": {
                "strong": [{
                  "range": [21,25]
                }],
                "em": [{
                  "range": [21,25]
                }],
                "a": [{
                  "range": [21,25], "value": "http://google.com"
                }]
              }

            }

          ]
        }
      ]}
    );
  },
  update: function(json) {
    // var str = JSON.stringify(json);
    //
    // save when content changes
    //
  }
};

module.exports = ContentStore;
<commit_msg>update some example data<commit_after>var ContentStore = {
  findxx() {
    return (
      {"sections": [
        {
          "id": "de5f",
          "blocks": [
            {
              "id": "56ef",
              "type": "h2",
              "text": "Page Title"
            },
            {
              "id": "667a",
              "type": "p",
              "text": "Build your page here"
            }
          ]
        }
      ]}
    );
  },

  find() {
    return (
      {"sections": [
        {
          "id": "de5f",
          "blocks": [
            {
              "id": "56ef",
              "type": "h2",
              "text": "History of Photography"
            },
            {
              "id": "667a",
              "type": "p",
              "text": "Photography is a word derived from the Greek words photos (“light”) and graphein (“to draw”) The word was first used by the scientist Sir John F.W. Herschel in 1839."
            },
            {
              "id": "7421",
              "type": "figure",
              "src": "http://tmp.derekdevries.com/daguerrotype.jpg",
              "width": 1370,
              "height": 709,
              "text": ""
            }
          ]
        }
      ]}
    );
  },

  findxxx() {
    return (
      {"sections": [
        {
          "id": "de5f",
          "blocks": [
            {
              "id": "56ef",
              "type": "h2",
              "text": "History of Photography"
            },
            {
              "id": "667a",
              "type": "p",
              "text": "Photography is a word derived from the Greek words photos (“light”) and graphein (“to draw”) The word was first used by the scientist Sir John F.W. Herschel in 1839."
            },
            {
              "id": "7421",
              "type": "figure",
              "src": "http://tmp.derekdevries.com/daguerrotype.jpg",
              "width": 1370,
              "height": 709,
              "text": "Daguerrotype"
            },
            {
              "id": "67a3",
              "type": "p",
              "text": "The metal-based daguerreotype process soon had some competition from the paper-based calotype negative and salt print processes invented by Henry Fox Talbot."
            },
            {
              "id": "667b",
              "type": "blockquote",
              "text": "For me, the camera is a sketch book, an instrument of intuition and spontaneity."
            },
            {
              "id": "7314",
              "type": "p",
              "text": "The history of photography has roots in remote antiquity with the discovery of the principle of the camera obscura and the observation that some substances are visibly altered by exposure to light. As far as is known, nobody thought of bringing these two phenomena together to capture camera images in permanent form until around 1800, when Thomas Wedgwood made the first reliably documented although unsuccessful attempt."
            },
          ]
        },
        {
          "id": "0fb3",
          "blocks": [
            {
              "id": "7315",
              "type": "p",
              "text": "In the mid-1820s, Nicéphore Niépce succeeded, but several days of exposure in the camera were required and the earliest results were very crude. Niépce's associate Louis Daguerre went on to develop the daguerreotype process, the first publicly announced photographic process, which required only minutes of exposure in the camera and produced clear, finely detailed results. It was commercially introduced in 1839, a date generally accepted as the birth year of practical photography"
            },
            {
              "id": "74ca",
              "type": "figure",
              "src": "https://www.youtube.com/embed/oK6JW1prwTw",
              "text": "The First Photographer: The Photographs of Nicéphore Niépce"
            },
            {
              "id": "c277",
              "type": "h3",
              "text": "Pinhole Camera"
            },
            {
              "id": "cca9",
              "type": "p",
              "text": "Alhazen (Ibn Al-Haytham), a great authority on optics in the Middle Ages who lived around 1000AD, invented the first pinhole camera, (also called the Camera Obscura and was able to explain why the images were upside down."
            },
            {
              "id": "a141",
              "type": "h4",
              "text": "The First Photograph"
            },
            {
              "id": "59b1",
              "type": "ul",
              "blocks": [
                {
                  "id": "4007",
                  "type": "li",
                  "text": "Joseph Nicephore Niepce"
                },
                {
                  "id": "3007",
                  "type": "li",
                  "text": "French inventor"
                },
                {
                  "id": "2007",
                  "type": "li",
                  "text": "Polished sheet of pewter"
                },
                {
                  "id": "4ca9",
                  "type": "li",
                  "text": "View from an upstairs window at Niépce's estate"
                }
              ]
            },
            {
              "id": "fce3",
              "type": "h4",
              "text": "Alfred Steiglitz"
            },
            {
              "id": "dc62",
              "type": "ol",
              "blocks": [
                {
                  "id": "f5a4",
                  "type": "li",
                  "text": "Early years (1864–1890)"
                },
                {
                  "id": "cc96",
                  "type": "li",
                  "text": "New York and the Camera Club (1891–1901)"
                }
              ]
            },
            {
              "id": "d8c1",
              "type": "figure",
              "src": "http://tmp.derekdevries.com/clay-henry.jpg",
              "width": 400,
              "height": 500,
              "text": ""
            }
          ]
        },
        {
          "id": "9fb3",
          "blocks": [
            {
              "id": "6353",
              "type": "p",
              "text": "Development of Photography as a Technology in different eras",
              "meta": {
                "align": "center"
              }
            },
            {
              "id": "e07e",
              "type": "p",
              "text": "The metal-based daguerreotype process soon had some competition from the paper-based calotype negative and salt print processes invented by Henry Fox Talbot. Subsequent innovations reduced the required camera exposure time from minutes to seconds and eventually to a small fraction of a second",
              "markups": {
                "a": [{
                  "range": [16,29], "value": "http://google.com"
                }]
              }
            },
            {
              "id": "1532",
              "type": "pre",
              "text": "(ns markov-elear.core-test\n  (:require [clojure.test :refer :all]\n            [markov-elear.core :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))"
            },
            {
              "id": "1d6e",
              "type": "p",
              "text": "Photography is the result of combining several different technical discoveries.",
              "markups": {
                "strong": [{
                  "range": [67,79]
                }]
              }
            },
            {
              "id": "1d6b",
              "type": "p",
              "text": "photos!",
              "markups": {
                "strong": [{
                  "range": [0,7]
                }]
              }
            },
            {
              "id": "1d6d",
              "type": "p",
              "text": "Long before the first photographs were made, Chinese philosopher Mo Ti and Greek mathematicians Aristotle and Euclid described a pinhole camera in the 5th and 4th centuries BCE.",
              "markups": {
                "strong": [{
                  "range": [0,4]
                }],
                "em": [{
                  "range": [22,33]
                }]
              }
            },
            {
              "id": "1d6c",
              "type": "p",
              "text": "In 1833 Niépce died suddenly, leaving his notes to Daguerre.",
              "markups": {
                "strong": [{
                  "range": [0,7]
                }]
              }
            },

            {
              "id": "067c",
              "type": "blockquote",
              "text": "Today everything exists to end in a photograph.",
              "meta": {
                "align": "center"
              }
            },
            {
              "id": "e5fe",
              "type": "p",
              "text": " And more paragraphs of text that are escaped "
            },
            {
              "id": "e5ff",
              "type": "p",
              "text": "And that can combine both markup and escaped",
              "markups": {
                "strong": [{
                  "range": [21,25]
                }],
                "em": [{
                  "range": [21,25]
                }],
                "a": [{
                  "range": [21,25], "value": "http://google.com"
                }]
              }

            }

          ]
        }
      ]}
    );
  },
  update: function(json) {
    var str = JSON.stringify(json);
    // console.log(str)
    // save when content changes
  }
};

module.exports = ContentStore;
<|endoftext|>


<commit_before>/*
 * gmodule
 * https://github.com/goliatone/gmodule
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/*global define:true*/
/* jshint strict: false */
define('gmodule', ['module', 'jquery'], function(module, jQuery) {

	//TODO: How do we get a reference to the global object here?
	var _namespace = this; //module.config().namespace || this;
	var _exportName = 'Module'; //module.config().exportName || 'Module';

	var _splice = Array.prototype.splice;

    var _isArray = function(obj){
        return obj.toString() === '[object Array]';
    };

    var _merge = function(a, b){
        for(var p in b){
            if(b.hasOwnProperty(p))
                a[p] = b[p];
        }
        return a;
    };

    var Module = function(name, parent){
        // if(_namespace[name])
            // return name;

        //Lets figure out parent.
        //TODO: Add support for com.domain.Module.
        //parent = parent.split('.');
        //while(target = parent.pop()) parent = _namespace[target];
        parent = parent || Module;

        if(typeof parent === 'string'){
            parent = _namespace[parent];
        }

        var self = function(){
            if( 'init' in this) this.init.apply(this, arguments);
        };

        //define default constructor. TODO:we could rename it.
        self.prototype.init = function(){};

        //Change self proto.
        if(parent){
            for( var i in parent){
                if(parent.hasOwnProperty(i)){
                    self[i] = Module.clone(parent[i]);
                }
            }

            for( i in parent.prototype){
                if(parent.prototype.hasOwnProperty(i)){
                    self.prototype[i] = Module.clone(parent.prototype[i]);
                }
            }

            var Ctor = function(){
                this.ctor = this.constructor = self;
            };
            Ctor.prototype = parent.prototype;
            self.prototype = new Ctor();

            //We need to create super after proto.
            //self._super = parent;
            self.prototype._super = parent.prototype;
        }

    //------------------------------
    // Adding class/static properties: i.e: User.findByPk().
        self.extend = function(obj, target){
            /*target = target || self;
            var extended = obj.extended;
            for(var i in obj){
                if(obj.hasOwnProperty(i))
                    target[i] = obj[i];
            }

            if(extended) extended.call(target,target);
            return self;*/

            var args;
            if(arguments.length > 2 ){
                target = obj;
                args = _splice.call(arguments,0);
            } else {
                args = [obj];
            }

            target = target || self;
            var _extend = function(){
                var extended = obj.extended;
                for(var i in obj){
                    if(obj.hasOwnProperty(i))
                        target[i] = obj[i];
                }

                if(extended) extended.call(target,target);
            };

            var i = 0, t = args.length;
            for(;i<t;i++){
                _extend(args[i]);
            }

            return target;
        };
    //  -----------------------------------
    //  Adding instance properties- user.id = 23;
        /**
         * All properties of the provided object will be
         * copied into the prototype of all Module instances.
         *
         * @access  public
         * @param   Object  Template with properties to include.
         * @return  Object  Instance, fluid interface.
         */
        self.include = function(){
            var _include = function(obj){
                var included = obj.included;
                for(var i in obj){
                    if(obj.hasOwnProperty(i))
                        self.fn[i] = obj[i];
                }
                if(included) included.call(self.fn, self.fn);
            };

            var i = 0, t = arguments.length;
            for(;i<t;i++){
                _include(arguments[i]);
            }

            return self;
        };

        /**
         * Utility mehtod to proxy function calls
         * with the proper scope.
         * Any extra parameters passed to it, will be
         * concatenated into the final call.
         *
         * @access public
         * @param   Function    Function to be proxied.
         * @return  Function    Wrapped function with scope set to self.
         */
        self.proxy = function(func){
            var a = _splice.call(arguments,1);
            var self = this;
            return function(){
                var a2 = _splice.call(arguments,0);
                return func.apply(self, a.concat(a2));
            };
        };

        //shortcuts.
        self.fn = self.prototype;
        self.fn.parent = parent;
        self.fn.proxy  = self.proxy;

        // The class/parent name
        self.prototype.__name__  = self.__name__  = name;
        self.prototype.__class__ = self;

        //Store a reference by name in the provided namespace.
        _namespace[name] = self;

        return self;
    };

    Module.__name__    = 'Module';
    //REVIEW: Should we have a per module or use jii.VERSION?
    Module.__version__ = '0.0.1';

    Module.decorator = function(implementation){
        var self = this;
        var Decorator = function(){};
        Decorator.prototype.decorate = function(){
            var i = 0,
                t = arguments.length;
            for(;i < t; i++){
                implementation( arguments[i], this);
            }
        };

        Decorator.prototype.owner = self;

        return new Decorator(self);
    };

    Module.override = function(src, method, fn){
        src.parent = src.parent || {};
        src.parent[method] = src[method];
        src[method] = fn;
    };

    /**
     * Utility method to clone an object.
     *
     * @access  public.
     * @param   object  Object to be cloned.
     * @return  object  Cloned object.
     */
    Module.clone = function(src){
        if (typeof src === 'function') return src;
        if (typeof src !== 'object') return src;
        var out = _isArray(src) ? [] : {};
        return _merge(out, src);
    };

    /*Module.merge = function(){
        console.log(_splice.call(arguments,0))
        return jQuery.extend.apply(jQuery, _splice.call(arguments,0));
    };*/

    /**
     * Scope in which the module will store all clases,
     * to prevent pollution of the global namespace.
     *
     * @access public
     * @param   object  scoped namespace for the module.
     * @return  object  scoped namespace for the module.
     */
    Module.namespace = function(ns){
        var namespace = ns || _namespace;
        if(!namespace.hasOwnProperty(_exportName))
            namespace[_exportName] = Module;
        return namespace;
    };

    Module.prototype.init = function(){
        console.log('Module: Init!');
        return 'This is just a stub!';
    };

    return Module;
});<commit_msg>Refactoring module def.<commit_after>/*
 * gmodule
 * https://github.com/goliatone/gmodule
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/* jshint strict: false, plusplus: true */
/*global define: false, require: false, module: false, exports: false */
(function (root, name, deps, factory) {
    "use strict";
    if (typeof exports === 'object') {
        // Node
         if(typeof deps === 'function') {
            factory = deps;
            deps = [];
        }
        module.exports = factory.apply(root, deps.map(require));
    } else if (typeof define === 'function' && 'amd' in define) {
        //require js
        define(name, deps, factory);
    } else {
        // Browser
        var d, i = 0, global = root, old = global[name], mod;
        while((d = deps[i]) !== undefined) deps[i++] = root[d];
        global[name] = mod = factory.apply(global, deps);
        //Export no 'conflict module', aliases the module.
        mod.noConflict = function(){
            global[name] = old;
            return mod;
        };
    }
    //TODO: Get rid of jquery!
}(this, "gmodule", function() {

    //TODO: How do we get a reference to the global object here?
    var _namespace = this; //module.config().namespace || this;
    var _exportName = 'Module'; //module.config().exportName || 'Module';

    var _splice = Array.prototype.splice;

    var _isArray = function(obj){
        return obj.toString() === '[object Array]';
    };

    var _merge = function(a, b){
        for(var p in b){
            if(b.hasOwnProperty(p))
                a[p] = b[p];
        }
        return a;
    };

    var Module = function(name, parent){
        // if(_namespace[name])
            // return name;

        //Lets figure out parent.
        //TODO: Add support for com.domain.Module.
        //parent = parent.split('.');
        //while(target = parent.pop()) parent = _namespace[target];
        parent = parent || Module;

        if(typeof parent === 'string'){
            parent = _namespace[parent];
        }

        var self = function(){
            if( 'init' in this) this.init.apply(this, arguments);
        };

        //define default constructor. TODO:we could rename it.
        self.prototype.init = function(){};

        //Change self proto.
        if(parent){
            for( var i in parent){
                if(parent.hasOwnProperty(i)){
                    self[i] = Module.clone(parent[i]);
                }
            }

            for( i in parent.prototype){
                if(parent.prototype.hasOwnProperty(i)){
                    self.prototype[i] = Module.clone(parent.prototype[i]);
                }
            }

            var Ctor = function(){
                this.ctor = this.constructor = self;
            };
            Ctor.prototype = parent.prototype;
            self.prototype = new Ctor();

            //We need to create super after proto.
            //self._super = parent;
            self.prototype._super = parent.prototype;
        }

    //------------------------------
    // Adding class/static properties: i.e: User.findByPk().
        self.extend = function(obj, target){
            /*target = target || self;
            var extended = obj.extended;
            for(var i in obj){
                if(obj.hasOwnProperty(i))
                    target[i] = obj[i];
            }

            if(extended) extended.call(target,target);
            return self;*/

            var args;
            if(arguments.length > 2 ){
                target = obj;
                args = _splice.call(arguments,0);
            } else {
                args = [obj];
            }

            target = target || self;
            var _extend = function(){
                var extended = obj.extended;
                for(var i in obj){
                    if(obj.hasOwnProperty(i))
                        target[i] = obj[i];
                }

                if(extended) extended.call(target,target);
            };

            var i = 0, t = args.length;
            for(;i<t;i++){
                _extend(args[i]);
            }

            return target;
        };
    //  -----------------------------------
    //  Adding instance properties- user.id = 23;
        /**
         * All properties of the provided object will be
         * copied into the prototype of all Module instances.
         *
         * @access  public
         * @param   Object  Template with properties to include.
         * @return  Object  Instance, fluid interface.
         */
        self.include = function(){
            var _include = function(obj){
                var included = obj.included;
                for(var i in obj){
                    if(obj.hasOwnProperty(i))
                        self.fn[i] = obj[i];
                }
                if(included) included.call(self.fn, self.fn);
            };

            var i = 0, t = arguments.length;
            for(;i<t;i++){
                _include(arguments[i]);
            }

            return self;
        };

        /**
         * Utility method to proxy function calls
         * with the proper scope.
         * Any extra parameters passed to it, will be
         * concatenated into the final call.
         *
         * @access public
         * @param   Function    Function to be proxied.
         * @return  Function    Wrapped function with scope set to self.
         */
        self.proxy = function(func){
            var a = _splice.call(arguments,1);
            var self = this;
            return function(){
                var a2 = _splice.call(arguments,0);
                return func.apply(self, a.concat(a2));
            };
        };

        //shortcuts.
        self.fn = self.prototype;
        self.fn.parent = parent;
        self.fn.proxy  = self.proxy;

        // The class/parent name
        self.prototype.__name__  = self.__name__  = name;
        self.prototype.__class__ = self;

        //Store a reference by name in the provided namespace.
        _namespace[name] = self;

        return self;
    };

    Module.__name__    = 'Module';
    //REVIEW: Should we have a per module or use jii.VERSION?
    Module.__version__ = '0.0.1';

    Module.decorator = function(implementation){
        var self = this;
        var Decorator = function(){};
        Decorator.prototype.decorate = function(){
            var i = 0,
                t = arguments.length;
            for(;i < t; i++){
                implementation( arguments[i], this);
            }
        };

        Decorator.prototype.owner = self;

        return new Decorator(self);
    };

    /**
     * Override a method but store a reference to
     * it on the source object's parent.
     * @param  {Function}   src
     * @param  {Function}   method
     * @param  {Function} fn
     * @return {void}
     */
    Module.override = function(src, method, fn){
        src.parent = src.parent || {};
        src.parent[method] = src[method];
        src[method] = fn;
    };

    /**
     * Utility method to clone an object.
     *
     * @access  public.
     * @param   object  Object to be cloned.
     * @return  object  Cloned object.
     */
    Module.clone = function(src){
        if (typeof src === 'function') return src;
        if (typeof src !== 'object') return src;
        var out = _isArray(src) ? [] : {};
        return _merge(out, src);
    };

    /*Module.merge = function(){
        console.log(_splice.call(arguments,0))
        return jQuery.extend.apply(jQuery, _splice.call(arguments,0));
    };*/

    /**
     * Scope in which the module will store all clases,
     * to prevent pollution of the global namespace.
     *
     * @access public
     * @param   object  scoped namespace for the module.
     * @return  object  scoped namespace for the module.
     */
    Module.namespace = function(ns){
        var namespace = ns || _namespace;
        if(!namespace.hasOwnProperty(_exportName))
            namespace[_exportName] = Module;
        return namespace;
    };

    Module.prototype.init = function(){
        console.log('Module: Init!');
        return 'This is just a stub!';
    };

    return Module;
}));<|endoftext|>


<commit_before>/* eslint-disable no-console */

export const LOAD_CONCEPTS = 'LOAD_CONCEPTS'
export const START_ASSESSMENT = 'START_ASSESSMENT'
export const END_ASSESSMENT = 'END_ASSESSMENT'
export const UPDATE_TESTED_CONCEPTS = 'UPDATE_TESTED_CONCEPTS'
export const UPDATE_TESTED_PROBLEMS = 'UPDATE_TESTED_PROBLEMS'
export const LOAD_CURRENT_CONCEPT = 'LOAD_CURRENT_CONCEPT'
export const LOAD_CURRENT_PROBLEM = 'LOAD_CURRENT_PROBLEM'

export const NEXT_PROBLEM = 'NEXT_PROBLEM'

export const loadConcepts = (concepts) => {
  return {
    type: LOAD_CONCEPTS,
    concepts
  }
}

export const getAllConcepts = () => {
  return dispatch => {
    return fetch('/api/concepts')
      .then( res => res.json())
      .then( concepts => {
        dispatch(loadConcepts(concepts))
      })
      .catch(err => {
        console.log(err)
      })
  }
}

export const addConcept = ({conceptDescr, conceptName, relatedConcepts}) => {

  let relationships = relatedConcepts.map(rel => {

    let precedes = rel.relationship === 'precedes'

    let root_node = precedes ? conceptName : rel.concept
    let other_node = precedes ? rel.concept : conceptName

    return { root_node, other_node, link: 'PRECEDES'}
  })

  return dispatch => {
    return fetch('/api/concepts', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({description: conceptDescr, title: conceptName})
      })
      .then(res => res.json())
      .then(res => {
        console.log(`Added Concept: ${res.title}`)

        fetch('/api/relationships/titles', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(relationships)
        })
        .then(res => res.json())
        .then(res => {
          console.log(`Added ${res.length} relationship(s)`)
          dispatch(getAllConcepts())
        })
      })
      .catch(err => {
        console.log(err)
      })
  }
}

export const addProblem = ({concept, topic, question, answer}) => {

  return (dispatch, getState) => {

    return fetch('/api/problems', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({topic, question, answer})
      })
      .then(res => res.json())
      .then(res => {
        let root_node = res._id
        let other_node
        let concepts = getState().allConcepts.byId
        for (var prop in concepts) {
          if (concepts[prop].title === concept) {
            other_node = concepts[prop]._id
          }
        }

        let relationship = { root_node, other_node, link: 'TESTS'}

        fetch('api/relationships/ids', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify([relationship])
        })
        .then(res => res.json())
        .then(() => { console.log('Added to related concept') })
        .catch(err => {
          console.log(err)
        })
      })
  }
}

export const startAssessment = () => {

  return dispatch => {

    return fetch('/api/concepts/initial', {
        headers: { 'Content-Type': 'application/json'}
      })
      .then(res => res.json())
      .then(res => {
        dispatch({ type: START_ASSESSMENT })
        dispatch(setCurrentValues(res.data[0]))
      })
      .catch(err => { console.log(err) })
  }
}

export const setCurrentValues = (concept) => {

  return dispatch => {

    return fetch('api/problems/relationship?concept=' + concept._id)
      .then(res => res.json())
      .then(res => {
        dispatch({
          type: LOAD_CURRENT_CONCEPT,
          details: concept,
          problems: res.data
        })
        dispatch({
          type: LOAD_CURRENT_PROBLEM,
          problem: res.data[0]
        })
      })
      .catch(err => { console.log(err) })
  }
}

export const updateCurrent = (type, value, status) => {

  return dispatch => {

    if (type === 'problem') {

      let updatedProblem = {...value, status}
      console.log(updatedProblem)

      dispatch(updateTested(type, updatedProblem))

    } else if (type === 'concept') {

      dispatch(updateTested(type, status))

    }
  }
}

export const updateTested = (type, value, status) => {

  return dispatch => {

    let updated = {...value, status}

    if (type === 'problem') {

      dispatch({
        type: UPDATE_TESTED_PROBLEMS,
        problem: updated
      })
    }

    else if (type === 'concept') {

      dispatch({
        type: UPDATE_TESTED_CONCEPTS,
        concept: updated
      })
    }
  }
}

export const nextProblem = (concept, nextIndex) => {

  return dispatch => {
    let nextProblem = concept.problems[nextIndex]

    dispatch({
      type: LOAD_CURRENT_PROBLEM,
      problem: nextProblem
    })
  }
}

export const checkAnswer = ({ answer } , problem) => {

  return (dispatch, getState) => {

    let threshold = 60/100
    let concept = getState().assessment.currentConcept
    let problems = concept.problems
    let testedProblems = getState().assessment.tested.problems

    let problemIndex = problems.reduce((initial, prob, i) => {
      return prob._id === problem._id ? initial + i : initial
    }, 0)

    if (answer.toLowerCase() === problem.answer.toLowerCase()) {

      dispatch(updateTested('problem', problem, 'correct'))

      let totalCorrect = countProblems(testedProblems, 'correct')

      if (totalCorrect / problems.length >= threshold) {

        dispatch(updateTested('concept', concept, 'understood'))

        fetch('/api/concepts/relationship/subsequent?concept=' + concept.details._id, {
          headers: {'Content-Type': 'application/json'},
        })
        .then(res => res.json())
        .then(res => {
          console.log(res.data)
          if (res.data.length !== 0) {
            dispatch(setCurrentValues(res.data[0]))
          } else {
            fetch('/api/concepts/relationship/parallel?concept=' + concept.details._id, {
              headers: {'Content-Type': 'application/json'},
            })
            .then(res => res.json())
            .then(res => {
              console.log(res.data);
              if (res.data.length !== 0) {
                dispatch(setCurrentValues(res.data[0]))
              } else {
                dispatch({type: END_ASSESSMENT})
              }
            })
          }
        })
      } else {
        dispatch(nextProblem(concept, problemIndex + 1))
      }
    } else {

      dispatch(updateTested('problem', problem, 'incorrect'))

      let totalIncorrect = countProblems(testedProblems, 'incorrect')

      if (totalIncorrect / problems.length >= (1 - threshold)) {

        dispatch(updateTested('concept', concept, 'developing'))

        fetch('/api/concepts/relationship/preceding?concept=' + concept._id, {
          headers: {'Content-Type': 'application/json'},
        })
        .then(res => res.json())
        .then(res => {

          if (res.data.length !== 0) {

            let testedConcepts = getState().assessment.tested.concepts
            let notTested = res.data.filter((prob) => {
              return testedConcepts.reduce((initial, testedConcept) => {
                return prob._id === testedConcept._id ? initial + 1 : initial
              }, 0)
            })
            dispatch(setCurrentValues(notTested[0]))
          } else {
            fetch('/api/concepts/relationship/parallel?concept=' + concept._id, {
              headers: {'Content-Type': 'application/json'},
            })
            .then(res => res.json())
            .then(res => {
              if (res.data.length !== 0) {
                dispatch(setCurrentValues(res.data[0]))
              } else {
                dispatch({type: END_ASSESSMENT})
              }
            })
          }
        })
      } else {
        dispatch(nextProblem(concept, problemIndex + 1))
      }
    }

    function countProblems(problems, status) {
      return problems.reduce((initial, prob) => {
        return prob.status === status ? ++initial : initial
      }, 0)
    }
  }
}
<commit_msg>Updates check answer action. #26<commit_after>/* eslint-disable no-console */

export const LOAD_CONCEPTS = 'LOAD_CONCEPTS'
export const START_ASSESSMENT = 'START_ASSESSMENT'
export const END_ASSESSMENT = 'END_ASSESSMENT'
export const UPDATE_TESTED_CONCEPTS = 'UPDATE_TESTED_CONCEPTS'
export const UPDATE_TESTED_PROBLEMS = 'UPDATE_TESTED_PROBLEMS'
export const LOAD_CURRENT_CONCEPT = 'LOAD_CURRENT_CONCEPT'
export const LOAD_CURRENT_PROBLEM = 'LOAD_CURRENT_PROBLEM'

export const NEXT_PROBLEM = 'NEXT_PROBLEM'

export const loadConcepts = (concepts) => {
  return {
    type: LOAD_CONCEPTS,
    concepts
  }
}

export const getAllConcepts = () => {
  return dispatch => {
    return fetch('/api/concepts')
      .then( res => res.json())
      .then( concepts => {
        dispatch(loadConcepts(concepts))
      })
      .catch(err => {
        console.log(err)
      })
  }
}

export const addConcept = ({conceptDescr, conceptName, relatedConcepts}) => {

  let relationships = relatedConcepts.map(rel => {

    let precedes = rel.relationship === 'precedes'

    let root_node = precedes ? conceptName : rel.concept
    let other_node = precedes ? rel.concept : conceptName

    return { root_node, other_node, link: 'PRECEDES'}
  })

  return dispatch => {
    return fetch('/api/concepts', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({description: conceptDescr, title: conceptName})
      })
      .then(res => res.json())
      .then(res => {
        console.log(`Added Concept: ${res.title}`)

        fetch('/api/relationships/titles', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(relationships)
        })
        .then(res => res.json())
        .then(res => {
          console.log(`Added ${res.length} relationship(s)`)
          dispatch(getAllConcepts())
        })
      })
      .catch(err => {
        console.log(err)
      })
  }
}

export const addProblem = ({concept, topic, question, answer}) => {

  return (dispatch, getState) => {

    return fetch('/api/problems', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({topic, question, answer})
      })
      .then(res => res.json())
      .then(res => {
        let root_node = res._id
        let other_node
        let concepts = getState().allConcepts.byId
        for (var prop in concepts) {
          if (concepts[prop].title === concept) {
            other_node = concepts[prop]._id
          }
        }

        let relationship = { root_node, other_node, link: 'TESTS'}

        fetch('api/relationships/ids', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify([relationship])
        })
        .then(res => res.json())
        .then(() => { console.log('Added to related concept') })
        .catch(err => {
          console.log(err)
        })
      })
  }
}

export const startAssessment = () => {

  return dispatch => {

    return fetch('/api/concepts/initial', {
        headers: { 'Content-Type': 'application/json'}
      })
      .then(res => res.json())
      .then(res => {
        dispatch({ type: START_ASSESSMENT })
        dispatch(setCurrentValues(res.data[0]))
      })
      .catch(err => { console.log(err) })
  }
}

export const setCurrentValues = (concept) => {

  return dispatch => {

    return fetch('api/problems/relationship?concept=' + concept._id)
      .then(res => res.json())
      .then(res => {
        dispatch({
          type: LOAD_CURRENT_CONCEPT,
          details: concept,
          problems: res.data
        })
        dispatch({
          type: LOAD_CURRENT_PROBLEM,
          problem: res.data[0]
        })
      })
      .catch(err => { console.log(err) })
  }
}

export const updateCurrent = (type, value, status) => {

  return dispatch => {

    if (type === 'problem') {

      let updatedProblem = {...value, status}
      console.log(updatedProblem)

      dispatch(updateTested(type, updatedProblem))

    } else if (type === 'concept') {

      dispatch(updateTested(type, status))

    }
  }
}

export const updateTested = (type, value, status) => {

  return dispatch => {

    let updated = {...value, status}

    if (type === 'problem') {

      dispatch({
        type: UPDATE_TESTED_PROBLEMS,
        problem: updated
      })
    }

    else if (type === 'concept') {

      dispatch({
        type: UPDATE_TESTED_CONCEPTS,
        concept: updated
      })
    }
  }
}

export const nextProblem = (concept, nextIndex) => {

  return dispatch => {
    let nextProblem = concept.problems[nextIndex]

    dispatch({
      type: LOAD_CURRENT_PROBLEM,
      problem: nextProblem
    })
  }
}

export const checkAnswer = ({ answer } , problem) => {

  return (dispatch, getState) => {

    let threshold = 60/100
    let concept = getState().assessment.currentConcept
    let problems = concept.problems
    let testedProblems = getState().assessment.tested.problems

    let problemIndex = problems.reduce((initial, prob, i) => {
      return prob._id === problem._id ? initial + i : initial
    }, 0)

    if (answer.toLowerCase() === problem.answer.toLowerCase()) {

      dispatch(updateTested('problem', problem, 'correct'))

      let totalCorrect = countProblems(testedProblems, 'correct')

      if (totalCorrect / problems.length >= threshold) {

        dispatch(updateTested('concept', concept, 'understood'))

        fetch('/api/concepts/relationship/subsequent?concept=' + concept.details._id, {
          headers: {'Content-Type': 'application/json'},
        })
        .then(res => res.json())
        .then(res => {
          console.log(res.data)
          if (res.data.length !== 0) {
            dispatch(setCurrentValues(res.data[0]))
          } else {
            fetch('/api/concepts/relationship/parallel?concept=' + concept.details._id, {
              headers: {'Content-Type': 'application/json'},
            })
            .then(res => res.json())
            .then(res => {
              console.log(res.data);
              if (res.data.length !== 0) {
                dispatch(setCurrentValues(res.data[0]))
              } else {
                dispatch({type: END_ASSESSMENT})
              }
            })
          }
        })
      } else {
        dispatch(nextProblem(concept, problemIndex + 1))
      }
    } else {

      dispatch(updateTested('problem', problem, 'incorrect'))

      let totalIncorrect = countProblems(testedProblems, 'incorrect')

      if (totalIncorrect / problems.length >= (1 - threshold)) {

        dispatch(updateTested('concept', concept, 'developing'))

        fetch('/api/concepts/relationship/preceding?concept=' + concept.details._id, {
          headers: {'Content-Type': 'application/json'},
        })
        .then(res => res.json())
        .then(res => {

          if (res.data.length !== 0) {

            let testedConcepts = getState().assessment.tested.concepts
            let notTested = res.data.filter((prob) => {
              return testedConcepts.reduce((initial, testedConcept) => {
                return prob._id === testedConcept._id ? initial + 1 : initial
              }, 0)
            })
            dispatch(setCurrentValues(notTested[0]))
          } else {
            fetch('/api/concepts/relationship/parallel?concept=' + concept.details._id, {
              headers: {'Content-Type': 'application/json'},
            })
            .then(res => res.json())
            .then(res => {
              if (res.data.length !== 0) {
                dispatch(setCurrentValues(res.data[0]))
              } else {
                dispatch({type: END_ASSESSMENT})
              }
            })
          }
        })
      } else {
        dispatch(nextProblem(concept, problemIndex + 1))
      }
    }

    function countProblems(problems, status) {
      return problems.reduce((initial, prob) => {
        return prob.status === status ? ++initial : initial
      }, 0)
    }
  }
}
<|endoftext|>


<commit_before>const config = require('config');
const franc = require('franc');

// Generate a page access token for your page from the App Dashboard
const PAGE_ACCESS_TOKEN = (process.env.MESSENGER_PAGE_ACCESS_TOKEN) ?
(process.env.MESSENGER_PAGE_ACCESS_TOKEN) :
config.get('pageAccessToken');

let FBMessenger = require('fb-messenger');
let messenger = new FBMessenger(PAGE_ACCESS_TOKEN);

export const handler = (data) => {
    let senderID = data.sender.id;
    let pageID = data.recipient.id;
    let timeOfMessage = data.timestamp;
    let message = data.message;
    let senderName = "";

    let lang = franc(message, {blacklist: ['src', 'zlm']});

    console.log("[receivedMessage] user (%d) page (%d) timestamp (%d) and message (%s)",
    senderID, pageID, timeOfMessage, JSON.stringify(message));

    messenger.getProfile(senderID, function (err, body) {
        if(err) return console.error(err)
        console.log(body)
    });

    if(lang == "eng") {
        messenger.sendTextMessage(senderID, 'English');

    } else if (lang == "ind") {
        messenger.sendTextMessage(senderID, 'Maaf , bahasa indonesia ku belum bagus');

    }
}

export default handler;
<commit_msg>Language Detection System Bug Fix 2<commit_after>const config = require('config');
const franc = require('franc');

// Generate a page access token for your page from the App Dashboard
const PAGE_ACCESS_TOKEN = (process.env.MESSENGER_PAGE_ACCESS_TOKEN) ?
(process.env.MESSENGER_PAGE_ACCESS_TOKEN) :
config.get('pageAccessToken');

let FBMessenger = require('fb-messenger');
let messenger = new FBMessenger(PAGE_ACCESS_TOKEN);

export const handler = (data) => {
    let senderID = data.sender.id;
    let pageID = data.recipient.id;
    let timeOfMessage = data.timestamp;
    let message = data.message;
    let senderName = "";
    console.log(message);
    let lang = franc(message, {blacklist: ['src', 'zlm']});

    console.log("[receivedMessage] user (%d) page (%d) timestamp (%d) and message (%s)",
    senderID, pageID, timeOfMessage, JSON.stringify(message));

    messenger.getProfile(senderID, function (err, body) {
        if(err) return console.error(err)
        console.log(body)
    });

    if(lang == "eng") {
        messenger.sendTextMessage(senderID, 'English');

    } else if (lang == "ind") {
        messenger.sendTextMessage(senderID, 'Maaf , bahasa indonesia ku belum bagus');

    }
}

export default handler;
<|endoftext|>