<commit_before>var config      = require('./config'),
    ViewModel   = require('./viewmodel'),
    utils       = require('./utils'),
    makeHash    = utils.hash,
    assetTypes  = ['directive', 'filter', 'partial', 'effect', 'component']

// require these so Browserify can catch them
// so they can be used in Vue.require
require('./observer')
require('./transition')

ViewModel.options = config.globalAssets = {
    directives  : require('./directives'),
    filters     : require('./filters'),
    partials    : makeHash(),
    effects     : makeHash(),
    components  : makeHash()
}

/**
 *  Expose asset registration methods
 */
assetTypes.forEach(function (type) {
    ViewModel[type] = function (id, value) {
        var hash = this.options[type + 's']
        if (!hash) {
            hash = this.options[type + 's'] = makeHash()
        }
        if (!value) return hash[id]
        if (type === 'partial') {
            value = utils.toFragment(value)
        } else if (type === 'component') {
            value = utils.toConstructor(value)
        } else if (type === 'filter') {
            utils.checkFilter(value)
        }
        hash[id] = value
        return this
    }
})

/**
 *  Set config options
 */
ViewModel.config = function (opts, val) {
    if (typeof opts === 'string') {
        if (val === undefined) {
            return config[opts]
        } else {
            config[opts] = val
        }
    } else {
        utils.extend(config, opts)
    }
    return this
}

/**
 *  Expose an interface for plugins
 */
ViewModel.use = function (plugin) {
    if (typeof plugin === 'string') {
        try {
            plugin = require(plugin)
        } catch (e) {
            utils.warn('Cannot find plugin: ' + plugin)
            return
        }
    }

    // additional parameters
    var args = [].slice.call(arguments, 1)
    args.unshift(this)

    if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args)
    } else {
        plugin.apply(null, args)
    }
    return this
}

/**
 *  Expose internal modules for plugins
 */
ViewModel.require = function (path) {
    return require('./' + path)
}

ViewModel.extend = extend
ViewModel.nextTick = utils.nextTick

/**
 *  Expose the main ViewModel class
 *  and add extend method
 */
function extend (options) {

    var ParentVM = this

    // extend data options need to be copied
    // on instantiation
    if (options.data) {
        options.defaultData = options.data
        delete options.data
    }

    // inherit options
    // but only when the super class is not the native Vue.
    if (ParentVM !== ViewModel) {
        options = inheritOptions(options, ParentVM.options, true)
    }
    utils.processOptions(options)

    var ExtendedVM = function (opts, asParent) {
        if (!asParent) {
            opts = inheritOptions(opts, options, true)
        }
        ParentVM.call(this, opts, true)
    }

    // inherit prototype props
    var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
    utils.defProtected(proto, 'constructor', ExtendedVM)

    // allow extended VM to be further extended
    ExtendedVM.extend  = extend
    ExtendedVM.super   = ParentVM
    ExtendedVM.options = options

    // allow extended VM to add its own assets
    assetTypes.forEach(function (type) {
        ExtendedVM[type] = ViewModel[type]
    })

    // allow extended VM to use plugins
    ExtendedVM.use     = ViewModel.use
    ExtendedVM.require = ViewModel.require

    return ExtendedVM
}

/**
 *  Inherit options
 *
 *  For options such as `data`, `vms`, `directives`, 'partials',
 *  they should be further extended. However extending should only
 *  be done at top level.
 *
 *  `proto` is an exception because it's handled directly on the
 *  prototype.
 *
 *  `el` is an exception because it's not allowed as an
 *  extension option, but only as an instance option.
 */
function inheritOptions (child, parent, topLevel) {
    child = child || {}
    if (!parent) return child
    for (var key in parent) {
        if (key === 'el') continue
        var val = child[key],
            parentVal = parent[key]
        if (topLevel && typeof val === 'function' && parentVal) {
            // merge hook functions into an array
            child[key] = [val]
            if (Array.isArray(parentVal)) {
                child[key] = child[key].concat(parentVal)
            } else {
                child[key].push(parentVal)
            }
        } else if (
            topLevel &&
            (utils.isTrueObject(val) || utils.isTrueObject(parentVal))
            && !(parentVal instanceof ViewModel)
        ) {
            // merge toplevel object options
            child[key] = inheritOptions(val, parentVal)
        } else if (val === undefined) {
            // inherit if child doesn't override
            child[key] = parentVal
        }
    }
    return child
}

module.exports = ViewModel<commit_msg>Fix #124 ViewModel.require with component@1.0.0<commit_after>var config      = require('./config'),
    ViewModel   = require('./viewmodel'),
    utils       = require('./utils'),
    makeHash    = utils.hash,
    assetTypes  = ['directive', 'filter', 'partial', 'effect', 'component'],
    // Internal modules that are exposed for plugins
    pluginAPI   = {
        utils: utils,
        config: config,
        transition: require('./transition'),
        observer: require('./observer')
    }

ViewModel.options = config.globalAssets = {
    directives  : require('./directives'),
    filters     : require('./filters'),
    partials    : makeHash(),
    effects     : makeHash(),
    components  : makeHash()
}

/**
 *  Expose asset registration methods
 */
assetTypes.forEach(function (type) {
    ViewModel[type] = function (id, value) {
        var hash = this.options[type + 's']
        if (!hash) {
            hash = this.options[type + 's'] = makeHash()
        }
        if (!value) return hash[id]
        if (type === 'partial') {
            value = utils.toFragment(value)
        } else if (type === 'component') {
            value = utils.toConstructor(value)
        } else if (type === 'filter') {
            utils.checkFilter(value)
        }
        hash[id] = value
        return this
    }
})

/**
 *  Set config options
 */
ViewModel.config = function (opts, val) {
    if (typeof opts === 'string') {
        if (val === undefined) {
            return config[opts]
        } else {
            config[opts] = val
        }
    } else {
        utils.extend(config, opts)
    }
    return this
}

/**
 *  Expose an interface for plugins
 */
ViewModel.use = function (plugin) {
    if (typeof plugin === 'string') {
        try {
            plugin = require(plugin)
        } catch (e) {
            utils.warn('Cannot find plugin: ' + plugin)
            return
        }
    }

    // additional parameters
    var args = [].slice.call(arguments, 1)
    args.unshift(this)

    if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args)
    } else {
        plugin.apply(null, args)
    }
    return this
}

/**
 *  Expose internal modules for plugins
 */
ViewModel.require = function (module) {
    return pluginAPI[module]
}

ViewModel.extend = extend
ViewModel.nextTick = utils.nextTick

/**
 *  Expose the main ViewModel class
 *  and add extend method
 */
function extend (options) {

    var ParentVM = this

    // extend data options need to be copied
    // on instantiation
    if (options.data) {
        options.defaultData = options.data
        delete options.data
    }

    // inherit options
    // but only when the super class is not the native Vue.
    if (ParentVM !== ViewModel) {
        options = inheritOptions(options, ParentVM.options, true)
    }
    utils.processOptions(options)

    var ExtendedVM = function (opts, asParent) {
        if (!asParent) {
            opts = inheritOptions(opts, options, true)
        }
        ParentVM.call(this, opts, true)
    }

    // inherit prototype props
    var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
    utils.defProtected(proto, 'constructor', ExtendedVM)

    // allow extended VM to be further extended
    ExtendedVM.extend  = extend
    ExtendedVM.super   = ParentVM
    ExtendedVM.options = options

    // allow extended VM to add its own assets
    assetTypes.forEach(function (type) {
        ExtendedVM[type] = ViewModel[type]
    })

    // allow extended VM to use plugins
    ExtendedVM.use     = ViewModel.use
    ExtendedVM.require = ViewModel.require

    return ExtendedVM
}

/**
 *  Inherit options
 *
 *  For options such as `data`, `vms`, `directives`, 'partials',
 *  they should be further extended. However extending should only
 *  be done at top level.
 *
 *  `proto` is an exception because it's handled directly on the
 *  prototype.
 *
 *  `el` is an exception because it's not allowed as an
 *  extension option, but only as an instance option.
 */
function inheritOptions (child, parent, topLevel) {
    child = child || {}
    if (!parent) return child
    for (var key in parent) {
        if (key === 'el') continue
        var val = child[key],
            parentVal = parent[key]
        if (topLevel && typeof val === 'function' && parentVal) {
            // merge hook functions into an array
            child[key] = [val]
            if (Array.isArray(parentVal)) {
                child[key] = child[key].concat(parentVal)
            } else {
                child[key].push(parentVal)
            }
        } else if (
            topLevel &&
            (utils.isTrueObject(val) || utils.isTrueObject(parentVal))
            && !(parentVal instanceof ViewModel)
        ) {
            // merge toplevel object options
            child[key] = inheritOptions(val, parentVal)
        } else if (val === undefined) {
            // inherit if child doesn't override
            child[key] = parentVal
        }
    }
    return child
}

module.exports = ViewModel<|endoftext|>


<commit_before>
var fc = $.fullCalendar = { version: "@VERSION" };
var fcViews = fc.views = {};

$.fn.fullCalendar = function(options) {

	// method calling
	if (typeof options == 'string') {
		var args = Array.prototype.slice.call(arguments, 1);
		var res;
		this.each(function() {
			var calendar = $.data(this, 'fullCalendar');
			if (calendar && $.isFunction(calendar[options])) {
				var r = calendar[options].apply(calendar, args);
				if (res === undefined) {
					res = r;
				}
				if (options == 'destroy') {
					$.removeData(this, 'fullCalendar');
				}
			}
		});
		if (res !== undefined) {
			return res;
		}
		return this;
	}

	// would like to have this logic in EventManager, but needs to happen before options are recursively extended
	var eventSources = options.eventSources || [];
	delete options.eventSources;
	if (options.events) {
		eventSources.push(options.events);
		delete options.events;
	}

	options = $.extend(true, {},
		defaults,
		(options.isRTL || options.isRTL===undefined && defaults.isRTL) ? rtlDefaults : {},
		options
	);

	this.each(function(i, _element) {
		var element = $(_element);
		var calendar = new Calendar(element, options, eventSources);
		element.data('fullCalendar', calendar); // TODO: look into memory leak implications
		calendar.render();
	});

	return this;

};

// function for adding/overriding defaults
var setDefaults = function(d) {
	$.extend(true, defaults, d);
}

$.fullCalendar.setDefaults = function(d) {
	setDefaults(d);
}
<commit_msg>redundant function removed (thanks to Thinkscape)<commit_after>
var fc = $.fullCalendar = { version: "@VERSION" };
var fcViews = fc.views = {};

$.fn.fullCalendar = function(options) {

	// method calling
	if (typeof options == 'string') {
		var args = Array.prototype.slice.call(arguments, 1);
		var res;
		this.each(function() {
			var calendar = $.data(this, 'fullCalendar');
			if (calendar && $.isFunction(calendar[options])) {
				var r = calendar[options].apply(calendar, args);
				if (res === undefined) {
					res = r;
				}
				if (options == 'destroy') {
					$.removeData(this, 'fullCalendar');
				}
			}
		});
		if (res !== undefined) {
			return res;
		}
		return this;
	}

	// would like to have this logic in EventManager, but needs to happen before options are recursively extended
	var eventSources = options.eventSources || [];
	delete options.eventSources;
	if (options.events) {
		eventSources.push(options.events);
		delete options.events;
	}

	options = $.extend(true, {},
		defaults,
		(options.isRTL || options.isRTL===undefined && defaults.isRTL) ? rtlDefaults : {},
		options
	);

	this.each(function(i, _element) {
		var element = $(_element);
		var calendar = new Calendar(element, options, eventSources);
		element.data('fullCalendar', calendar); // TODO: look into memory leak implications
		calendar.render();
	});

	return this;

};

// function for adding/overriding defaults
var setDefaults = function(d) {
	$.extend(true, defaults, d);
}

$.fullCalendar.setDefaults = setDefaults;
<|endoftext|>


<commit_before>var req = require('./lib/request.js');
var handle = require('./handle.js');
var events = require('./events.js');
var util = require('./util.js');
var type_of = require('./type-of.js');
var captcha = require('./captcha.js');
var version = require('./version.js');
var request = require('./request.js');

var _global = (window || global);

if(!_global){
	console.log('Not in support');
}

var YHSD = {};
YHSD.events = events;
YHSD.util = util;
YHSD.request = request;
YHSD.captcha = captcha;

_global.yhsd = _global.yhsd || {};

_global.yhsd._$interceptors = {
	request: {
		_$callback: function (oRequest, fnNext) {
			fnNext(oRequest);
		},
		use: function (_fn) {
			this._$callback = _fn;
		},
		run: function (oRequest, fnNext) {
			this._$callback(oRequest, fnNext);
		}
	},
	response: {
		_$callback: function (oResponse, fnNext) {
			fnNext(oResponse);
		},
		use: function (_fn) {
			this._$callback = _fn;
		},
		run: function (oResponse, fnNext) {
			this._$callback(oResponse, fnNext);
		}
	}
};

_global.yhsd.version = function(){
	return version.get();
};

var aFunctionReady = [];
var bHasInit = false;

var runWhenReady = function(fn){
	if(type_of(fn) === 'function'){
		if(bHasInit){
			fn(YHSD);
		}else{
			aFunctionReady.push(fn);
		}
	}
};

_global.yhsd.ready = runWhenReady;
_global.yhsd.sdk = YHSD;

if(typeof _global.yhsdDebug === 'undefined'){
	_global.yhsdDebug = false;
}

var aInitModule = ['account', 'area', 'address', 'blog', 'cart', 'shop', 'order', 'page', 'payment_method', 'product', 'type', 'vendor', 'discount', 'coupon', 'reward_point', 'page_block', 'post', 'favorite', 'service', 'trade_invoice', 'weapp'];

function checkModule(moduleName){
	return (util.inArray(moduleName, aInitModule) > -1);
}

YHSD.account = checkModule('account') ? require('./account.js') : {};
YHSD.area = checkModule('area') ? require('./area.js') : {};
YHSD.address = checkModule('address') ? require('./address.js') : {};
YHSD.blog = checkModule('blog') ? require('./blog.js') : {};
YHSD.cart = checkModule('cart') ? require('./cart.js') : {};
YHSD.discount = checkModule('discount') ? require('./discount.js') : {};
YHSD.shop = checkModule('shop') ? require('./shop.js') : {};
YHSD.order = checkModule('order') ? require('./order.js') : {};
YHSD.page = checkModule('page') ? require('./page.js') : {};
YHSD.payment_method = checkModule('payment_method') ? require('./payment_method.js') : {};
YHSD.product = checkModule('product') ? require('./product.js') : {};
YHSD.type = checkModule('type') ? require('./type.js') : {};
YHSD.vendor = checkModule('vendor') ? require('./vendor.js') : {};
YHSD.coupon = checkModule('coupon') ? require('./coupon.js') : {};
YHSD.reward_point = checkModule('reward_point') ? require('./reward_point.js') : {};
YHSD.page_block = checkModule('page_block') ? require('./page_block.js') : {};
YHSD.post = checkModule('post') ? require('./post.js') : {};
YHSD.favorite = checkModule('favorite') ? require('./favorite.js') : {};
YHSD.service = checkModule('service') ? require('./service.js') : {};
YHSD.trade_invoice = checkModule('trade_invoice') ? require('./trade_invoice.js') : {};
YHSD.weapp = checkModule('weapp') ? require('./weapp.js') : {};

function jssdkInit(){
	if(aFunctionReady.length === 0){
		bHasInit = true;
	}else{
		(aFunctionReady.shift())(YHSD);
		jssdkInit();
	}
}

(function(){
	var ajaxToken = null;
	if('ajaxToken' in _global) {
		jssdkInit();
	} else {
		Object.defineProperty(_global, 'ajaxToken', {
			set: function(token){
				if(!ajaxToken) {
					ajaxToken = token;
					jssdkInit();
				} else {
					ajaxToken = token;
				}
			},
			get: function(){
				return ajaxToken;
			}
		});
	}
})();<commit_msg>feat: Main - _global<commit_after>var events = require('./events.js');
var util = require('./util.js');
var type_of = require('./type-of.js');
var captcha = require('./captcha.js');
var version = require('./version.js');
var request = require('./request.js');

// globalThis 暂时不用
var _global = {};
try {
  _global = global
} catch (error) {
  _global = window
}

var YHSD = {};
YHSD.events = events;
YHSD.util = util;
YHSD.request = request;
YHSD.captcha = captcha;

_global.yhsd = _global.yhsd || {};

_global.yhsd._$interceptors = {
	request: {
		_$callback: function (oRequest, fnNext) {
			fnNext(oRequest);
		},
		use: function (_fn) {
			this._$callback = _fn;
		},
		run: function (oRequest, fnNext) {
			this._$callback(oRequest, fnNext);
		}
	},
	response: {
		_$callback: function (oResponse, fnNext) {
			fnNext(oResponse);
		},
		use: function (_fn) {
			this._$callback = _fn;
		},
		run: function (oResponse, fnNext) {
			this._$callback(oResponse, fnNext);
		}
	}
};

_global.yhsd.version = function(){
	return version.get();
};

var aFunctionReady = [];
var bHasInit = false;

var runWhenReady = function(fn){
	if(type_of(fn) === 'function'){
		if(bHasInit){
			fn(YHSD);
		}else{
			aFunctionReady.push(fn);
		}
	}
};

_global.yhsd.ready = runWhenReady;
_global.yhsd.sdk = YHSD;

if(typeof _global.yhsdDebug === 'undefined'){
	_global.yhsdDebug = false;
}

var aInitModule = ['account', 'area', 'address', 'blog', 'cart', 'shop', 'order', 'page', 'payment_method', 'product', 'type', 'vendor', 'discount', 'coupon', 'reward_point', 'page_block', 'post', 'favorite', 'service', 'trade_invoice', 'weapp'];

function checkModule(moduleName){
	return (util.inArray(moduleName, aInitModule) > -1);
}

YHSD.account = checkModule('account') ? require('./account.js') : {};
YHSD.area = checkModule('area') ? require('./area.js') : {};
YHSD.address = checkModule('address') ? require('./address.js') : {};
YHSD.blog = checkModule('blog') ? require('./blog.js') : {};
YHSD.cart = checkModule('cart') ? require('./cart.js') : {};
YHSD.discount = checkModule('discount') ? require('./discount.js') : {};
YHSD.shop = checkModule('shop') ? require('./shop.js') : {};
YHSD.order = checkModule('order') ? require('./order.js') : {};
YHSD.page = checkModule('page') ? require('./page.js') : {};
YHSD.payment_method = checkModule('payment_method') ? require('./payment_method.js') : {};
YHSD.product = checkModule('product') ? require('./product.js') : {};
YHSD.type = checkModule('type') ? require('./type.js') : {};
YHSD.vendor = checkModule('vendor') ? require('./vendor.js') : {};
YHSD.coupon = checkModule('coupon') ? require('./coupon.js') : {};
YHSD.reward_point = checkModule('reward_point') ? require('./reward_point.js') : {};
YHSD.page_block = checkModule('page_block') ? require('./page_block.js') : {};
YHSD.post = checkModule('post') ? require('./post.js') : {};
YHSD.favorite = checkModule('favorite') ? require('./favorite.js') : {};
YHSD.service = checkModule('service') ? require('./service.js') : {};
YHSD.trade_invoice = checkModule('trade_invoice') ? require('./trade_invoice.js') : {};
YHSD.weapp = checkModule('weapp') ? require('./weapp.js') : {};

function jssdkInit(){
	if(aFunctionReady.length === 0){
		bHasInit = true;
	}else{
		(aFunctionReady.shift())(YHSD);
		jssdkInit();
	}
}

(function(){
	var ajaxToken = null;
	if('ajaxToken' in _global) {
		jssdkInit();
	} else {
		Object.defineProperty(_global, 'ajaxToken', {
			set: function(token){
				if(!ajaxToken) {
					ajaxToken = token;
					jssdkInit();
				} else {
					ajaxToken = token;
				}
			},
			get: function(){
				return ajaxToken;
			}
		});
	}
})();<|endoftext|>


<commit_before>'use strict'

const dgram = require('dgram')
const http = require('http')
const uuid = require('uuid')

const REGISTRATION_PORT = process.env.REGISTRATION_PORT || 8888

function timeLog (msg) {
  console.log(`${new Date().toUTCString()}: ${msg}`)
}

http.createServer((request, response) => {
  response.writeHead(200, {'Content-Type': 'application/json'})
  response.end('{"hello": "world"}\n')
  timeLog.log('Served Request')
}).listen(80)

timeLog('Echo listening on http://localhost')

const client = dgram.createSocket('udp4')

client.bind(REGISTRATION_PORT, () => {
  // This is critical for properly functioning, since the whole point is that
  // we DONT know what might be listening
  client.setBroadcast(true)

  const instanceData = JSON.stringify({
    name: 'echo',
    version: '0.0.1',
    id: uuid.v4()
  })

  function sendRegistrationData () {
    client.send(instanceData, 0, instanceData.length, REGISTRATION_PORT, '255.255.255.255', (err) => {
      if (err) throw err

      timeLog('Sent registration data')
    })
  }

  sendRegistrationData()
  setInterval(sendRegistrationData, 1000 * 30) // Send every 30 seconds
})
<commit_msg>Fixed logging bug<commit_after>'use strict'

const dgram = require('dgram')
const http = require('http')
const uuid = require('uuid')

const REGISTRATION_PORT = process.env.REGISTRATION_PORT || 8888

function timeLog (msg) {
  console.log(`${new Date().toUTCString()}: ${msg}`)
}

http.createServer((request, response) => {
  response.writeHead(200, {'Content-Type': 'application/json'})
  response.end('{"hello": "world"}\n')
  timeLog('Served Request')
}).listen(80)

timeLog('Echo listening on http://localhost')

const client = dgram.createSocket('udp4')

client.bind(REGISTRATION_PORT, () => {
  // This is critical for properly functioning, since the whole point is that
  // we DONT know what might be listening
  client.setBroadcast(true)

  const instanceData = JSON.stringify({
    name: 'echo',
    version: '0.0.1',
    id: uuid.v4()
  })

  function sendRegistrationData () {
    client.send(instanceData, 0, instanceData.length, REGISTRATION_PORT, '255.255.255.255', (err) => {
      if (err) throw err

      timeLog('Sent registration data')
    })
  }

  sendRegistrationData()
  setInterval(sendRegistrationData, 1000 * 30) // Send every 30 seconds
})
<|endoftext|>


<commit_before>/**
 * FCUI (Fengchao UI)
 * Copyright 2014 Baidu Inc. All rights reserved.
 *
 * @file
 * @author Han Bing Feng (hanbingfeng@baidu.com)
 * @param {Function} require require
 * @return {Object} main
 */
define(function (require) {
    var u = require('underscore');
    var main = require('esui/main');

    var skin = require('./extension/FcUiSkin');

    main.esuiVersion = main.version;

    /**
     * 绑定全局扩展
     *
     * 通过此方法绑定的扩展，会对所有的控件实例生效
     *
     * 每一次全局扩展生成实例时，均会复制`options`对象，而不会直接使用引用
     *
     * 派生自ESUI 3.1.0-beta.3
     * @param {string} type 扩展类型
     * @param {Object} options 扩展初始化参数
     */
    main.attachExtension = function (type, option) {
        var options;
        if (typeof this.globalExtensionOptions === 'undefined') {
            options = this.globalExtensionOptions = {};
        }
        options[type] = option || {};
    };

    /**
     * 创建全局扩展对象
     * ESUI里的实现有误，修正过来
     *
     * @return {Extension[]}
     */
    main.createGlobalExtensions = function () {
        var options = this.globalExtensionOptions;
        var extensions = [];
        u.each(options, function (option, type) {
            var extension = this.createExtension(type, option);
            extension && extensions.push(extension);
        }, this);

        return extensions;
    };

    main.registerExtension(skin);

    main.attachExtension('FcUiSkin', {});

    main.version = '0.0.2-alpha.1';

    return main;
});
<commit_msg>import esui main<commit_after>/**
 * FCUI (Fengchao UI)
 * Copyright 2014 Baidu Inc. All rights reserved.
 *
 * @file
 * @author Han Bing Feng (hanbingfeng@baidu.com)
 * @param {Function} require require
 * @return {Object} main
 */
define(function (require) {
    var u = require('underscore');
    var main = require('esui/main');

    var skin = require('./extension/FcUiSkin');

    main.esuiVersion = main.version;

    /**
     * 绑定全局扩展
     *
     * 通过此方法绑定的扩展，会对所有的控件实例生效
     *
     * 每一次全局扩展生成实例时，均会复制`options`对象，而不会直接使用引用
     *
     * 派生自ESUI 3.1.0-beta.3
     * @param {string} type 扩展类型
     * @param {Object} option 扩展初始化参数
     */
    main.attachExtension = function (type, option) {
        var options;
        if (typeof this.globalExtensionOptions === 'undefined') {
            options = this.globalExtensionOptions = {};
        }
        options[type] = option || {};
    };

    /**
     * 创建全局扩展对象
     * ESUI里的实现有误，修正过来
     *
     * @return {Extension[]}
     */
    main.createGlobalExtensions = function () {
        var options = this.globalExtensionOptions;
        var extensions = [];
        u.each(options, function (option, type) {
            var extension = this.createExtension(type, option);
            extension && extensions.push(extension);
        }, this);

        return extensions;
    };

    /**
     * 控件库配置数据
     *
     * @type {Object}
     * @ignore
     */
    var config = {
        uiPrefix: 'data-ui',
        extensionPrefix: 'data-ui-extension',
        customElementPrefix: 'esui',
        instanceAttr: 'data-ctrl-id',
        viewContextAttr: 'data-ctrl-view-context',
        uiClassPrefix: 'ui',
        skinClassPrefix: 'skin',
        stateClassPrefix: 'state'
    };

    /**
     * 从容器DOM元素批量初始化内部的控件渲染
     *
     * @param {HTMLElement} [wrap=document.body] 容器DOM元素，默认
     * @param {Object} [options] init参数
     * @param {Object} [options.viewContext] 视图环境
     * @param {Object} [options.properties] 属性集合，通过id映射
     * @param {Object} [options.valueReplacer] 属性值替换函数
     * @return {Control[]} 初始化的控件对象集合
     */
    /* eslint-disable fecs-max-statements */
    /* 从ESUI拿的旧的main，暂时去掉50行的限制 */
    main.init = function (wrap, options) {
        wrap = wrap || document.body;
        options = options || {};

        var valueReplacer = options.valueReplacer || function (value) {
            return value;
        };

        /**
         * 将字符串数组join成驼峰形式
         *
         * @param {string[]} source 源字符串数组
         * @return {string}
         * @ignore
         */
        function joinCamelCase(source) {
            function replacer(c) {
                return c.toUpperCase();
            }

            for (var i = 1, len = source.length; i < len; i++) {
                source[i] = source[i].replace(/^[a-z]/, replacer);
            }

            return source.join('');
        }

        /**
         * 不覆盖目标对象成员的extend
         *
         * @param {Object} target 目标对象
         * @param {Object} source 源对象
         * @ignore
         */
        function noOverrideExtend(target, source) {
            for (var key in source) {
                if (!(key in target)) {
                    target[key] = source[key];
                }
            }
        }

        /**
         * 将标签解析的值附加到option对象上
         *
         * @param {Object} optionObject option对象
         * @param {string[]} terms 经过切分的标签名解析结果
         * @param {string} value 属性值
         * @ignore
         */
        function extendToOption(optionObject, terms, value) {
            if (terms.length === 0) {
                noOverrideExtend(
                    optionObject,
                    main.parseAttribute(value, valueReplacer)
                );
            }
            else {
                optionObject[joinCamelCase(terms)] = valueReplacer(value);
            }
        }

        function matchReplace(match, ch) {
            return ch.toUpperCase();
        }

        // 把dom元素存储到临时数组中
        // 控件渲染的过程会导致Collection的改变
        var rawElements = wrap.getElementsByTagName('*');
        var elements = [];
        var i;
        var len;
        for (i = 0, len = rawElements.length; i < len; i++) {
            if (rawElements[i].nodeType === 1) {
                elements.push(rawElements[i]);
            }
        }

        var uiPrefix = main.getConfig('uiPrefix');
        var extPrefix = main.getConfig('extensionPrefix');
        var customElementPrefix = main.getConfig('customElementPrefix');
        var uiPrefixLen = uiPrefix.length;
        var extPrefixLen = extPrefix.length;
        var properties = options.properties || {};
        var controls = [];
        for (i = 0, len = elements.length; i < len; i++) {
            var element = elements[i];

            // 有时候，一个控件会自己把`main.innerHTML`生成子控件，比如`Panel`，
            // 但这边有缓存这些子元素，可能又会再生成一次，所以要去掉
            if (element.getAttribute(config.instanceAttr)) {
                continue;
            }

            var attributes = element.attributes;
            var controlOptions = {};
            var extensionOptions = {};
            var terms;
            var extOption;

            // 解析attribute中的参数
            for (var j = 0, attrLen = attributes.length; j < attrLen; j++) {
                var attribute = attributes[j];
                var name = attribute.name;
                var value = attribute.value;

                if (name.indexOf(extPrefix) === 0) {
                    // 解析extension的key
                    terms = name.slice(extPrefixLen + 1).split('-');
                    var extKey = terms[0];
                    terms.shift();

                    // 初始化该key的option对象
                    extOption = extensionOptions[extKey];
                    if (!extOption) {
                        extOption = extensionOptions[extKey] = {};
                    }

                    extendToOption(extOption, terms, value);
                }
                else if (name.indexOf(uiPrefix) === 0) {
                    terms = name.length === uiPrefixLen
                        ? []
                        : name.slice(uiPrefixLen + 1).split('-');
                    extendToOption(controlOptions, terms, value);
                }
            }

            // 根据选项创建控件
            var type = controlOptions.type;
            if (!type) {
                var nodeName = element.nodeName.toLowerCase();
                var esuiPrefixIndex = nodeName.indexOf(customElementPrefix);
                if (esuiPrefixIndex === 0) {
                    var typeFromCustomElement = nodeName.replace(
                        /-(\S)/g,
                        matchReplace
                    );
                    typeFromCustomElement = typeFromCustomElement.slice(
                        customElementPrefix.length
                    );
                    controlOptions.type = typeFromCustomElement;
                    type = typeFromCustomElement;
                }
            }
            if (type) {
                // 从用户传入的properties中merge控件初始化属性选项
                var controlId = controlOptions.id;
                var customOptions = controlId
                    ? properties[controlId]
                    : {};
                var key;

                for (key in customOptions) {
                    if (customOptions.hasOwnProperty(key)) {
                        controlOptions[key] = valueReplacer(customOptions[key]);
                    }
                }

                // 创建控件的插件
                var extensions = controlOptions.extensions || [];
                controlOptions.extensions = extensions;
                for (key in extensionOptions) {
                    if (extensionOptions.hasOwnProperty(key)) {
                        extOption = extensionOptions[key];
                        var extension = main.createExtension(
                            extOption.type,
                            extOption
                        );
                        extension && extensions.push(extension);
                    }
                }

                // 绑定视图环境和控件主元素
                controlOptions.viewContext = options.viewContext;
                // 容器类控件会需要渲染自己的`innerHTML`，
                // 这种渲染使用`initChildren`，再调用`main.init`，
                // 因此需要把此处`main.init`的参数交给控件，方便再带回来，
                // 以便`properties`、`valueReplacer`之类的能保留
                controlOptions.renderOptions = options;
                controlOptions.main = element;

                // 创建控件
                var control = main.create(type, controlOptions);
                if (control) {
                    controls.push(control);
                    if (options.parent) {
                        options.parent.addChild(control);
                    }
                    try {
                        control.render();
                    }
                    catch (ex) {
                        var error = new Error(
                            'Render control '
                                + '"' + (control.id || 'anonymous') + '" '
                                + 'of type ' + control.type + ' '
                                + 'failed because: '
                                + ex.message
                        );
                        error.actualError = ex;
                        throw error;
                    }
                }
            }
        }

        return controls;
    };
    /* eslint-enable fecs-max-statements */

    main.registerExtension(skin);

    main.attachExtension('FcUiSkin', {});

    main.version = '0.0.2-alpha.1';

    return main;
});
<|endoftext|>


<commit_before>require('material-design-lite/material.min.js')
require('material-design-lite/material.min.css')
require('material-design-icons/iconfont/material-icons.css')
require('mapbox-gl/dist/mapbox-gl.css')

import Vue from 'vue'
import Router from 'vue-router'
import Resource from 'vue-resource'
import VueMdl from 'vue-mdl'
import Layout from './components/Layout'
import Footer from './components/Footer'
import Card from './components/Card'
import Search from './components/Search'
import Table from './components/Table'
import Map from './components/Map'
import App from './components/App'
import Home from './components/Home'
import Atlas from './views/Atlas'
import Blog from './components/Blog'
import Login from './components/Login'
import Register from './components/Register'
import Studio from './components/Studio'
import Maps from './components/Maps'
import Fonts from './views/Fonts'
import Data from './components/Data'
import Icons from './components/Icons'
import Upload from './views/Upload'
import DataCardsMap from './components/DataCards-Map'
import DataCardsData from './components/DataCards-Data'
import DataCardsIcon from './components/DataCards-Icon'
import MapView from './components/MapView'
import MapEditor from './components/MapEditor'
import DataCards from './components/DataCards'
import Post from './components/Post.vue'
import TOC from './components/MapEditorToc.vue'
import MapEditorView from './components/MapEditorView.vue'
import MapLayoutView from './components/MapLayoutView.vue'
import MapStyleEditor from './components/MapStyleEditor.vue'
import MapDistrictSelect from './components/MapDistrictSelect'
import ModalStyleTemplate from './components/ModalStyleTemplate'
import Loading from './components/Loading'
import Dialog from './components/Dialog'
import DialogInput from './components/Dialog-Input'
import User from './views/User'

Vue.config.debug = true
Vue.use(Router)
Vue.use(VueMdl)
Vue.use(Resource)

Vue.component('foxgis-layout', Layout)
Vue.component('foxgis-footer', Footer)
Vue.component('foxgis-card', Card)
Vue.component('foxgis-search', Search)
Vue.component('foxgis-table', Table)
Vue.component('foxgis-map', Map)
Vue.component('foxgis-data-cards-map', DataCardsMap)
Vue.component('foxgis-data-cards-data', DataCardsData)
Vue.component('foxgis-data-cards-font', DataCardsFont)
Vue.component('foxgis-data-cards-icon', DataCardsIcon)
Vue.component('foxgis-data-cards', DataCards)
Vue.component('foxgis-post', Post)
Vue.component('foxgis-toc', TOC)
Vue.component('foxgis-drafmap',MapEditorView)
Vue.component('foxgis-layoutmap',MapLayoutView)
Vue.component('foxgis-style-editor',MapStyleEditor)
Vue.component('foxgis-district-select',MapDistrictSelect)
Vue.component('foxgis-style-template',ModalStyleTemplate)
Vue.component('foxgis-loading',Loading)
Vue.component('foxgis-dialog',Dialog)
Vue.component('foxgis-dialog-input',DialogInput)

let router = new Router({
  history: false
})

router.map({
  '/': {
    component: Login
  },
  '/home': {
    component: Home
  },
  '/atlas': {
    component: Atlas
  },
  '/blog': {
    component: Blog
  },
  '/login': {
    component: Login
  },
  '/register': {
    component: Register
  },
  '/studio': {
    component: Studio,
    subRoutes: {
      '/': {
        component: Upload
      },
      '/maps': {
        component: Maps
      },
      '/data': {
        component: Data
      },
      '/fonts': {
        component: Fonts
      },
      '/sprites': {
        component: Icons
      },
      '/uploads': {
        component: Upload
      },
      '/user':{
        component:User
      }
    }
  },
  '/mapview': {
    component: MapView
  },
  '/mapeditor/*any': {
    component: MapEditor
  }
})

router.start(App, '#app')
<commit_msg>edit font<commit_after>require('material-design-lite/material.min.js')
require('material-design-lite/material.min.css')
require('material-design-icons/iconfont/material-icons.css')
require('mapbox-gl/dist/mapbox-gl.css')

import Vue from 'vue'
import Router from 'vue-router'
import Resource from 'vue-resource'
import VueMdl from 'vue-mdl'
import Layout from './components/Layout'
import Footer from './components/Footer'
import Card from './components/Card'
import Search from './components/Search'
import Table from './components/Table'
import Map from './components/Map'
import App from './components/App'
import Home from './components/Home'
import Atlas from './views/Atlas'
import Blog from './components/Blog'
import Login from './components/Login'
import Register from './components/Register'
import Studio from './components/Studio'
import Maps from './components/Maps'
import Fonts from './views/Fonts'
import Data from './components/Data'
import Icons from './components/Icons'
import Upload from './views/Upload'
import DataCardsMap from './components/DataCards-Map'
import DataCardsData from './components/DataCards-Data'
import DataCardsIcon from './components/DataCards-Icon'
import MapView from './components/MapView'
import MapEditor from './components/MapEditor'
import DataCards from './components/DataCards'
import Post from './components/Post.vue'
import TOC from './components/MapEditorToc.vue'
import MapEditorView from './components/MapEditorView.vue'
import MapLayoutView from './components/MapLayoutView.vue'
import MapStyleEditor from './components/MapStyleEditor.vue'
import MapDistrictSelect from './components/MapDistrictSelect'
import ModalStyleTemplate from './components/ModalStyleTemplate'
import Loading from './components/Loading'
import Dialog from './components/Dialog'
import DialogInput from './components/Dialog-Input'
import User from './views/User'

Vue.config.debug = true
Vue.use(Router)
Vue.use(VueMdl)
Vue.use(Resource)

Vue.component('foxgis-layout', Layout)
Vue.component('foxgis-footer', Footer)
Vue.component('foxgis-card', Card)
Vue.component('foxgis-search', Search)
Vue.component('foxgis-table', Table)
Vue.component('foxgis-map', Map)
Vue.component('foxgis-data-cards-map', DataCardsMap)
Vue.component('foxgis-data-cards-data', DataCardsData)
Vue.component('foxgis-data-cards-icon', DataCardsIcon)
Vue.component('foxgis-data-cards', DataCards)
Vue.component('foxgis-post', Post)
Vue.component('foxgis-toc', TOC)
Vue.component('foxgis-drafmap',MapEditorView)
Vue.component('foxgis-layoutmap',MapLayoutView)
Vue.component('foxgis-style-editor',MapStyleEditor)
Vue.component('foxgis-district-select',MapDistrictSelect)
Vue.component('foxgis-style-template',ModalStyleTemplate)
Vue.component('foxgis-loading',Loading)
Vue.component('foxgis-dialog',Dialog)
Vue.component('foxgis-dialog-input',DialogInput)

let router = new Router({
  history: false
})

router.map({
  '/': {
    component: Login
  },
  '/home': {
    component: Home
  },
  '/atlas': {
    component: Atlas
  },
  '/blog': {
    component: Blog
  },
  '/login': {
    component: Login
  },
  '/register': {
    component: Register
  },
  '/studio': {
    component: Studio,
    subRoutes: {
      '/': {
        component: Upload
      },
      '/maps': {
        component: Maps
      },
      '/data': {
        component: Data
      },
      '/fonts': {
        component: Fonts
      },
      '/sprites': {
        component: Icons
      },
      '/uploads': {
        component: Upload
      },
      '/user':{
        component:User
      }
    }
  },
  '/mapview': {
    component: MapView
  },
  '/mapeditor/*any': {
    component: MapEditor
  }
})

router.start(App, '#app')
<|endoftext|>


<commit_before>$(function() {

  function dameId() {
    var id = window.location.search;
    if (id.indexOf('id=') > -1) {
      id=id.split('id=');
      id=parseInt(id[1]);
    } else {
      id=1;
    }
    return id;
  }

  function dameDestinatarios(csv) {
    var res = [];
    csv = csv.split('\n');
    for (i=0; i<csv.length; i++) {
      var dipu = csv[i].split(',');
      if (dipu.length > 1) res.push( { "twitter": dipu[0], "partido": dipu[1] } );
    }
    return res;
  }

  function ordenarAleatorio(arreglo) {
    return arreglo.sort(function() { return 0.5 - Math.random();});
  }

  function generarMenu(menu) {
    var html = '';
    _.each(menu, function(opcion) {
      html += "\t\t"+'
'+opcion.titulo+'
'+"\n";
    });
    return html;
  }

  function generarHashtags(hashtags) {
    var html = '';
    if (hashtags.length == 1) {
      html = '#'+hashtags[0]+'';
    } else {
      html = '
'+
        '#'+hashtags[0]+''+
        ''+
        ''+
        'Toggle Dropdown'+
        ''+
        '
';
      for (i=1; i<hashtags.length; i++) {
        html += '
#'+hashtags[i]+'
';
      }
      html += '

';
    }
    return html;
  }

  function generarTweets(mensaje, hashtag, imagen, destinatarios) {
    var disponible = 140,
    voypor = 0,
    num_destinatarios = destinatarios.length,
    seleccion = '',
    html = '';

    while (voypor < num_destinatarios) {
	  disponible = 140-mensaje.length-hashtag.length-2;
	  html += "\n\t\t"+'
'+
      "\n\t\t"+'

'+
	  "\n\t\t"+'
';
      while ((voypor < num_destinatarios) && (disponible > destinatarios[voypor].length+2)) {
        html += '@'+destinatarios[voypor]+' '
        seleccion += '@'+destinatarios[voypor]+' ';
        disponible -= destinatarios[voypor].length+2;
        voypor++;
      }
      html += mensaje+' #'+hashtag+'
'+
      "\n\t\t"+'
Enviar
'+
      "\n\t\t"+'
';
      seleccion = '';
    }

    return html;
    //$('#diputados').html(html);
  }

  function activarEnvios() {
    $('.enviar').on('click',function(e) {
      var fila = $(this).parents('.twit')
        , menciones = _.compact(fila.find('a.diputwi').text().split('@'))
        , incremento = menciones.length
        , actuales = parseInt($('.num-enviados').text())
        , dir = $(this).attr('href')
        , winTop = (screen.height / 2) - (350 / 2)
        , winLeft = (screen.width / 2) - (520 / 2);
      if (actuales == 0) {
        alert ("Twitter puede considerar como spam el simple hecho de publicar varios tweets seguidos con menciones a perfiles que no te sigan.\n\nPara evitar que suspendan tu cuenta te recomendamos espaciar los tweets enviados con menciones todo lo posible e intercalar otros tweets.\n\n¡Que no te callen!");
      }
      e.preventDefault();
      window.open (dir, 'twitter', 'top='+winTop+',left='+winLeft+',toolbar=0,status=0,width=520,height=350');
      localStorage['queridodiputado-'+dameId()] = _.concat(localStorage['queridodiputado-'+dameId()].split(','), menciones);
      $('.num-enviados').text(actuales+incremento);
      $(fila).slideUp('slow');
    });
  };

  $('.empezar').on('click', function(e) {
    localStorage.removeItem('queridodiputado-'+dameId());
    location.reload();
  });

  $.getJSON('data/'+dameId()+'.json', function(json) {
    // generamos menu
    $('#menu').prepend(generarMenu(json.menu));
    // activamos botón "ver menciones"
    //$('a.hashtag').attr('href', 'https://twitter.com/search/realtime?q=%23'+json.hashtag+'&src=hash');
    $('#botonera').prepend(generarHashtags(json.hashtags));
    // cargamos la página de intro de la campaña
    $.ajax({url: json.intro, dataType: 'text'})
    .done(function(intro) {
      $('#info').prepend(marked(intro));
    });
    // cargamos todas las listas de destinatarios
    $.when.apply($, _.map(json.listas, function(url) {
      return $.ajax(url.enlace, {dataType: 'text'});
    })).done(function() {
      var destinatarios = []
        , enviados = localStorage['queridodiputado-'+dameId()];
      // si hay más de una lista, arguments = [[data,statusText,jqXHR],...]
      if (_.isArray(arguments[0])) {
        for (var i = 0; i < arguments.length; i++) {
          destinatarios = _.concat(destinatarios, _.map(dameDestinatarios(arguments[i][0]), 'twitter'));
        }
      // si hay solo una lista, arguments = [data, statusText,jqXHR]
      } else {
          destinatarios = _.concat(destinatarios, _.map(dameDestinatarios(arguments[0]), 'twitter'));
      }
      // limpiamos repetidos
      destinatarios = _.uniq(destinatarios);
      if (enviados) {
        enviados = _.compact(enviados.split(','));
      } else {
        enviados = [];
      }
      $('.num-destinatarios').text(destinatarios.length);
      $('.num-enviados').text(enviados.length);
      var diferencia = _.difference(destinatarios, enviados);
      $('#diputados').html(generarTweets(json.mensaje, json.hashtags[0], json.imagen, ordenarAleatorio(diferencia)));
      localStorage['queridodiputado-'+dameId()] = enviados;
      activarEnvios();
    }).fail( function (jqXHR, status, error) {
      alert(error);
    });
  });

});

<commit_msg>Ampliado el máximo de caracteres de cada tweet a 280<commit_after>$(function() {

  function dameId() {
    var id = window.location.search;
    if (id.indexOf('id=') > -1) {
      id=id.split('id=');
      id=parseInt(id[1]);
    } else {
      id=1;
    }
    return id;
  }

  function dameDestinatarios(csv) {
    var res = [];
    csv = csv.split('\n');
    for (i=0; i<csv.length; i++) {
      var dipu = csv[i].split(',');
      if (dipu.length > 1) res.push( { "twitter": dipu[0], "partido": dipu[1] } );
    }
    return res;
  }

  function ordenarAleatorio(arreglo) {
    return arreglo.sort(function() { return 0.5 - Math.random();});
  }

  function generarMenu(menu) {
    var html = '';
    _.each(menu, function(opcion) {
      html += "\t\t"+'
'+opcion.titulo+'
'+"\n";
    });
    return html;
  }

  function generarHashtags(hashtags) {
    var html = '';
    if (hashtags.length == 1) {
      html = '#'+hashtags[0]+'';
    } else {
      html = '
'+
        '#'+hashtags[0]+''+
        ''+
        ''+
        'Toggle Dropdown'+
        ''+
        '
';
      for (i=1; i<hashtags.length; i++) {
        html += '
#'+hashtags[i]+'
';
      }
      html += '

';
    }
    return html;
  }

  function generarTweets(mensaje, hashtag, imagen, destinatarios) {
    var disponible = 280,
    voypor = 0,
    num_destinatarios = destinatarios.length,
    seleccion = '',
    html = '';

    while (voypor < num_destinatarios) {
	  disponible = 280-mensaje.length-hashtag.length-2;
	  html += "\n\t\t"+'
'+
      "\n\t\t"+'

'+
	  "\n\t\t"+'
';
      while ((voypor < num_destinatarios) && (disponible > destinatarios[voypor].length+2)) {
        html += '@'+destinatarios[voypor]+' '
        seleccion += '@'+destinatarios[voypor]+' ';
        disponible -= destinatarios[voypor].length+2;
        voypor++;
      }
      html += mensaje+' #'+hashtag+'
'+
      "\n\t\t"+'
Enviar
'+
      "\n\t\t"+'
';
      seleccion = '';
    }

    return html;
    //$('#diputados').html(html);
  }

  function activarEnvios() {
    $('.enviar').on('click',function(e) {
      var fila = $(this).parents('.twit')
        , menciones = _.compact(fila.find('a.diputwi').text().split('@'))
        , incremento = menciones.length
        , actuales = parseInt($('.num-enviados').text())
        , dir = $(this).attr('href')
        , winTop = (screen.height / 2) - (350 / 2)
        , winLeft = (screen.width / 2) - (520 / 2);
      if (actuales == 0) {
        alert ("Twitter puede considerar como spam el simple hecho de publicar varios tweets seguidos con menciones a perfiles que no te sigan.\n\nPara evitar que suspendan tu cuenta te recomendamos espaciar los tweets enviados con menciones todo lo posible e intercalar otros tweets.\n\n¡Que no te callen!");
      }
      e.preventDefault();
      window.open (dir, 'twitter', 'top='+winTop+',left='+winLeft+',toolbar=0,status=0,width=520,height=350');
      localStorage['queridodiputado-'+dameId()] = _.concat(localStorage['queridodiputado-'+dameId()].split(','), menciones);
      $('.num-enviados').text(actuales+incremento);
      $(fila).slideUp('slow');
    });
  };

  $('.empezar').on('click', function(e) {
    localStorage.removeItem('queridodiputado-'+dameId());
    location.reload();
  });

  $.getJSON('data/'+dameId()+'.json', function(json) {
    // generamos menu
    $('#menu').prepend(generarMenu(json.menu));
    // activamos botón "ver menciones"
    //$('a.hashtag').attr('href', 'https://twitter.com/search/realtime?q=%23'+json.hashtag+'&src=hash');
    $('#botonera').prepend(generarHashtags(json.hashtags));
    // cargamos la página de intro de la campaña
    $.ajax({url: json.intro, dataType: 'text'})
    .done(function(intro) {
      $('#info').prepend(marked(intro));
    });
    // cargamos todas las listas de destinatarios
    $.when.apply($, _.map(json.listas, function(url) {
      return $.ajax(url.enlace, {dataType: 'text'});
    })).done(function() {
      var destinatarios = []
        , enviados = localStorage['queridodiputado-'+dameId()];
      // si hay más de una lista, arguments = [[data,statusText,jqXHR],...]
      if (_.isArray(arguments[0])) {
        for (var i = 0; i < arguments.length; i++) {
          destinatarios = _.concat(destinatarios, _.map(dameDestinatarios(arguments[i][0]), 'twitter'));
        }
      // si hay solo una lista, arguments = [data, statusText,jqXHR]
      } else {
          destinatarios = _.concat(destinatarios, _.map(dameDestinatarios(arguments[0]), 'twitter'));
      }
      // limpiamos repetidos
      destinatarios = _.uniq(destinatarios);
      if (enviados) {
        enviados = _.compact(enviados.split(','));
      } else {
        enviados = [];
      }
      $('.num-destinatarios').text(destinatarios.length);
      $('.num-enviados').text(enviados.length);
      var diferencia = _.difference(destinatarios, enviados);
      $('#diputados').html(generarTweets(json.mensaje, json.hashtags[0], json.imagen, ordenarAleatorio(diferencia)));
      localStorage['queridodiputado-'+dameId()] = enviados;
      activarEnvios();
    }).fail( function (jqXHR, status, error) {
      alert(error);
    });
  });

});

<|endoftext|>


<commit_before>import './main.sass'
import 'babel-polyfill'
import 'isomorphic-fetch'

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { Router } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import { updateStrings as updateTimeAgoStrings } from './vendor/time_ago_in_words'
import { persistStore } from 'redux-persist'
import localforage from 'localforage'
import store from './store'
import { browserHistory } from 'react-router'
import routes from './routes'

import MemoryStore from './vendor/memory_store'

import './vendor/embetter'
import './vendor/embetter_initializer'

updateTimeAgoStrings({ about: '' })

const APP_VERSION = '1.0.13'

const history = syncHistoryWithStore(browserHistory, store)
const element = (
  <Provider store={ store }>
    <Router history={ history } routes={ routes(store) } />
  </Provider>
)

const whitelist = ['authentication', 'editor', 'gui', 'json', 'profile']

const launchApplication = (storage) => {
  const persistor = persistStore(store, { storage, whitelist }, () => {
    ReactDOM.render(element, document.getElementById('root'))
  })

  // check and update current version and
  // only kill off the persisted reducers
  storage.getItem('APP_VERSION')
    .then((curVersion) => {
      if (curVersion && curVersion !== APP_VERSION) {
        // we can't use purgeAll since localforage
        // doesn't implement the getAllKeys method
        persistor.purge(whitelist)
      }
      storage.setItem('APP_VERSION', APP_VERSION)
    })
}

try {
  // Test access to indexedDB
  // if it fails, explicitly set up localStorage as
  // localForage's storage driver.  This prevents a situation where
  // firefox in private mode technically has indexedDB, but exceptions are thrown
  // when it's accessed
  const dbRequest = window.indexedDB.open('ello-webapp')
  dbRequest.onsuccess = () => {
    const storage = localforage.createInstance({ name: 'ello-webapp' })
    launchApplication(storage)
  }
  dbRequest.onerror = () => {
    const storage = localforage.createInstance({
      name: 'ello-webapp',
      driver: localforage.LOCALSTORAGE,
    })
    launchApplication(storage)
    return true
  }
} catch (e) {
  // If even localStorage fails, use an in-memory store
  const storage = MemoryStore
  launchApplication(storage)
}
<commit_msg>Aims to fix a bug with private pages not rendering<commit_after>import './main.sass'
import 'babel-polyfill'
import 'isomorphic-fetch'

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { Router } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import { updateStrings as updateTimeAgoStrings } from './vendor/time_ago_in_words'
import { persistStore } from 'redux-persist'
import localforage from 'localforage'
import store from './store'
import { browserHistory } from 'react-router'
import routes from './routes'

import MemoryStore from './vendor/memory_store'

import './vendor/embetter'
import './vendor/embetter_initializer'

updateTimeAgoStrings({ about: '' })

const APP_VERSION = '1.0.13'

const history = syncHistoryWithStore(browserHistory, store)
const element = (
  <Provider store={ store }>
    <Router history={ history } routes={ routes(store) } />
  </Provider>
)

const whitelist = ['authentication', 'editor', 'gui', 'json', 'profile']

const launchApplication = (storage) => {
  const persistor = persistStore(store, { storage, whitelist }, () => {
    ReactDOM.render(element, document.getElementById('root'))
  })

  // check and update current version and
  // only kill off the persisted reducers
  storage.getItem('APP_VERSION')
    .then((curVersion) => {
      if (curVersion && curVersion !== APP_VERSION) {
        // we can't use purgeAll since localforage
        // doesn't implement the getAllKeys method
        persistor.purge(whitelist)
      }
      storage.setItem('APP_VERSION', APP_VERSION)
    })
}

try {
  // Test access to indexedDB
  // if it fails, explicitly set up localStorage as
  // localForage's storage driver.  This prevents a situation where
  // firefox in private mode technically has indexedDB, but exceptions are thrown
  // when it's accessed
  const dbRequest = window.indexedDB.open('ello-webapp')
  dbRequest.onsuccess = () => {
    const storage = localforage.createInstance({ name: 'ello-webapp' })
    launchApplication(storage)
  }
  dbRequest.onerror = () => {
    const storage = localforage.createInstance({
      name: 'ello-webapp',
      driver: localforage.LOCALSTORAGE,
    })
    launchApplication(storage)
    return true
  }
  // call this again to get the handlers to
  // fire consistently in private browsers?
  dbRequest()
} catch (e) {
  // If even localStorage fails, use an in-memory store
  const storage = MemoryStore
  launchApplication(storage)
}
<|endoftext|>


<commit_before>////
/* jRumble v1.3 - http://jackrugile.com/jrumble - MIT License */
(function(f){f.fn.jrumble=function(g){var a=f.extend({x:2,y:2,rotation:1,speed:15,opacity:false,opacityMin:0.5},g);return this.each(function(){var b=f(this),h=a.x*2,i=a.y*2,k=a.rotation*2,g=a.speed===0?1:a.speed,m=a.opacity,n=a.opacityMin,l,j,o=function(){var e=Math.floor(Math.random()*(h+1))-h/2,a=Math.floor(Math.random()*(i+1))-i/2,c=Math.floor(Math.random()*(k+1))-k/2,d=m?Math.random()+n:1,e=e===0&&h!==0?Math.random()<0.5?1:-1:e,a=a===0&&i!==0?Math.random()<0.5?1:-1:a;b.css("display")==="inline"&&(l=true,b.css("display","inline-block"));b.css({position:"relative",left:e+"px",top:a+"px","-ms-filter":"progid:DXImageTransform.Microsoft.Alpha(Opacity="+d*100+")",filter:"alpha(opacity="+d*100+")","-moz-opacity":d,"-khtml-opacity":d,opacity:d,"-webkit-transform":"rotate("+c+"deg)","-moz-transform":"rotate("+c+"deg)","-ms-transform":"rotate("+c+"deg)","-o-transform":"rotate("+c+"deg)",transform:"rotate("+c+"deg)"})},p={left:0,top:0,"-ms-filter":"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)",filter:"alpha(opacity=100)","-moz-opacity":1,"-khtml-opacity":1,opacity:1,"-webkit-transform":"rotate(0deg)","-moz-transform":"rotate(0deg)","-ms-transform":"rotate(0deg)","-o-transform":"rotate(0deg)",transform:"rotate(0deg)"};b.bind({startRumble:function(a){a.stopPropagation();clearInterval(j);j=setInterval(o,g)},stopRumble:function(a){a.stopPropagation();clearInterval(j);l&&b.css("display","inline");b.css(p)}})})}})(jQuery);
////
//

//var _originalGameSessionCreate = SDK.GameSession.create;
var sesh = SDK.GameSession.getInstance();
var orig_PlayCardFromHandAction = SDK.PlayCardFromHandAction.prototype._execute;

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

for (var i=1; i<3; i++)  {
    var margin = i == 1 ? 150 : 800;
    $('#app-game-player'+i+' .user-details').append($('

'));
    $('#app-game-player'+i+' #z0r .progress').css({
        width:'200px',
        height:'30px',
        border:'3px solid red',
        'background-color': 'transparent'
    })
    .append(
        $('

').css({
            height:'100%',
            width:'0%',
            'background-color': 'blue'
        })
    );
}

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

var mechazorProgress = sesh.gameSetupData.players.map(function (player) {
    return {
        id: player.playerId,
        progress: 0
    };
});

var updateZ0rProgress = function (id, progress) {
    for (var i=0; i<mechazorProgress.length; i++) {
        if (mechazorProgress[i].id === id) {
            mechazorProgress[i].progress += progress;
            if (mechazorProgress[i].progress > 1) {
                return 0; // mechazor can't be built twice
            }
            var percent = mechazorProgress[i].progress * 100;
            var deviation = mechazorProgress[i].progress * 10;
            var playerNumber = i+1;

            $('#app-game-player'+playerNumber+' #z0r .progress')
                .jrumble({ x: deviation, y: deviation })
                .trigger('startRumble')
                .find('.filling')
                .animate({ width: percent+"%"});

            console.log('AlERT:  z0r pprogress for player '+playerNumber+' equals '+mechazorProgress[i].progress);
            if (mechazorProgress[i].progress === 1) {
                resetMechaz0r(i);
            }
            break;
        }
    }
    return 0;
};

var resetMechaz0r = function (id) {
    mechazorProgress[id].progress = 0;
    console.log('ALERT: reset mechaz0r progress for player ' + id);
    setTimeout(function() {
        //$('#app-game-player'+(id+1)+' #z0r .progress .filling').css({ width: "0%" });
        $('#app-game-player'+(id+1)+' #z0r .progress').trigger('stopRumble').hide();
    }, 3000);
    return 0;
};

var _origModAction = SDK.ApplyModifierAction.prototype._execute;
SDK.ApplyModifierAction.prototype._execute = function () {
    var args = arguments;

    console.log(this);
    var ownerId = this.ownerId;
    var modifier = this.modifierContextObject;

    if (modifier.type == "PlayerModifierMechazorBuildProgress") {
        updateZ0rProgress(ownerId, modifier.progressContribution);
    }

    return _origModAction.apply(this, args);
};
<commit_msg>put stuff in a closure<commit_after>/* jRumble v1.3 - http://jackrugile.com/jrumble - MIT License */
(function(f){f.fn.jrumble=function(g){var a=f.extend({x:2,y:2,rotation:1,speed:15,opacity:false,opacityMin:0.5},g);return this.each(function(){var b=f(this),h=a.x*2,i=a.y*2,k=a.rotation*2,g=a.speed===0?1:a.speed,m=a.opacity,n=a.opacityMin,l,j,o=function(){var e=Math.floor(Math.random()*(h+1))-h/2,a=Math.floor(Math.random()*(i+1))-i/2,c=Math.floor(Math.random()*(k+1))-k/2,d=m?Math.random()+n:1,e=e===0&&h!==0?Math.random()<0.5?1:-1:e,a=a===0&&i!==0?Math.random()<0.5?1:-1:a;b.css("display")==="inline"&&(l=true,b.css("display","inline-block"));b.css({position:"relative",left:e+"px",top:a+"px","-ms-filter":"progid:DXImageTransform.Microsoft.Alpha(Opacity="+d*100+")",filter:"alpha(opacity="+d*100+")","-moz-opacity":d,"-khtml-opacity":d,opacity:d,"-webkit-transform":"rotate("+c+"deg)","-moz-transform":"rotate("+c+"deg)","-ms-transform":"rotate("+c+"deg)","-o-transform":"rotate("+c+"deg)",transform:"rotate("+c+"deg)"})},p={left:0,top:0,"-ms-filter":"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)",filter:"alpha(opacity=100)","-moz-opacity":1,"-khtml-opacity":1,opacity:1,"-webkit-transform":"rotate(0deg)","-moz-transform":"rotate(0deg)","-ms-transform":"rotate(0deg)","-o-transform":"rotate(0deg)",transform:"rotate(0deg)"};b.bind({startRumble:function(a){a.stopPropagation();clearInterval(j);j=setInterval(o,g)},stopRumble:function(a){a.stopPropagation();clearInterval(j);l&&b.css("display","inline");b.css(p)}})})}})(jQuery);

$(function () {
    var mechazorProgress = [];

    var initUI = function () {
        console.log('starting ui');
        console.log($('#app-game-player1'));
        for (var i=1; i<3; i++)  {
            var margin = i == 1 ? 150 : 800;
            $('#app-game-player'+i+' .user-details').append($('

'));
            $('#app-game-player'+i+' #z0r .progress').css({
                width:'200px',
                height:'30px',
                border:'3px solid red',
                'background-color': 'transparent'
            })
            .append(
                $('

').css({
                    height:'100%',
                    width:'0%',
                    'background-color': 'blue'
                })
            );
        }
    };

    var initMechazorProgress = function (sesh) {
        mechazorProgress = sesh.gameSetupData.players.map(function (player) {
            return {
                id: player.playerId,
                progress: 0
            };
        });
    };

    var updateZ0rProgress = function (id, progress) {
        for (var i=0; i<mechazorProgress.length; i++) {
            if (mechazorProgress[i].id === id) {
                mechazorProgress[i].progress += progress;
                if (mechazorProgress[i].progress > 1) {
                    return 0; // mechazor can't be built twice
                }
                var percent = mechazorProgress[i].progress * 100;
                var deviation = mechazorProgress[i].progress * 10;
                var playerNumber = i+1;

                $('#app-game-player'+playerNumber+' #z0r .progress')
                    .jrumble({ x: deviation, y: deviation })
                    .trigger('startRumble')
                    .find('.filling')
                    .animate({ width: percent+"%"});

                if (mechazorProgress[i].progress === 1) {
                    resetMechaz0r(i);
                }
                break;
            }
        }
        return 0;
    };

    var resetMechaz0r = function (id) {
        setTimeout(function() {
            $('#app-game-player'+(id+1)+' #z0r .progress').trigger('stopRumble').hide();
        }, 3000);
        return 0;
    };

    var _originalApplyModifierAction = SDK.ApplyModifierAction.prototype._execute;
    SDK.ApplyModifierAction.prototype._execute = function () {
        var args = arguments;

        var ownerId = this.ownerId;
        var modifier = this.modifierContextObject;

        if (modifier.type == "PlayerModifierMechazorBuildProgress") {
            updateZ0rProgress(ownerId, modifier.progressContribution);
        }

        return _originalApplyModifierAction.apply(this, args);
    };

    var gameOverReset = function () {
        mechazorProgress = [];
    };

    var eb = EventBus.getInstance();
    window.Application = eb._events.show_codex[0].ctx;
    window.Application._originalStartGame = window.Application._startGame;
    window.Application._startGame = function () {
        var sesh = SDK.GameSession.current();
        var _oldSetStatus = sesh.setStatus;

        sesh.setStatus = function (status) {
            var args = arguments;

            console.log(status);

            if (status === 'active') {
                initMechazorProgress(sesh);
                initUI();
            }
            else if (status === 'over') {
                gameOverReset();
            }
            return _oldSetStatus.apply(this, args);
        };

        return window.Application._originalStartGame.apply(this, arguments);
    };
});
<|endoftext|>


<commit_before>// we want font-awesome to load as soon as possible to show the fa-spinner

import 'font-awesome/css/font-awesome.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import * as Bluebird from 'bluebird';
import 'babel-polyfill';
import config from './authConfig';
import '../static/styles.css';
// remove out if you don't want a Promise polyfill (remove also from webpack.config.js)
Bluebird.config({ warnings: { wForgottenReturn: false } });

export async function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .plugin(PLATFORM.moduleName('au-table'))
    .plugin(PLATFORM.moduleName('aurelia-validation'))
  // .plugin(PLATFORM.moduleName('aurelia-polymer'))
    .plugin(PLATFORM.moduleName('aurelia-auth'), (baseConfig) => {
      baseConfig.configure(config);
    });

  // Uncomment the line below to enable animation.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-animator-css'));
  // if the css animator is enabled, add swap-order="after" to all router-view elements

  // Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-html-import-template-loader'));

  aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));

  // await aurelia.start();
  // await aurelia.setRoot(PLATFORM.moduleName('app'));
}
<commit_msg>use babel 7 polyfill<commit_after>// we want font-awesome to load as soon as possible to show the fa-spinner

import 'font-awesome/css/font-awesome.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import * as Bluebird from 'bluebird';
import '@babel/polyfill';
import config from './authConfig';
import '../static/styles.css';
// remove out if you don't want a Promise polyfill (remove also from webpack.config.js)
Bluebird.config({ warnings: { wForgottenReturn: false } });

export async function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .plugin(PLATFORM.moduleName('au-table'))
    .plugin(PLATFORM.moduleName('aurelia-validation'))
  // .plugin(PLATFORM.moduleName('aurelia-polymer'))
    .plugin(PLATFORM.moduleName('aurelia-auth'), (baseConfig) => {
      baseConfig.configure(config);
    });

  // Uncomment the line below to enable animation.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-animator-css'));
  // if the css animator is enabled, add swap-order="after" to all router-view elements

  // Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-html-import-template-loader'));

  aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));

  // await aurelia.start();
  // await aurelia.setRoot(PLATFORM.moduleName('app'));
}
<|endoftext|>


<commit_before>/* eslint import/no-unresolved: 0 */
import { app } from 'electron';
import fse from 'fs-extra';
import { WindowManager, handleStartupEvent, setApplicationMenu } from './desktop';
import cnc from './cnc';
import pkg from './package.json';

let windowManager = null;

const main = () => {
    if (handleStartupEvent()) {
        return;
    }

    // https://github.com/electron/electron/blob/master/docs/api/app.md#appmakesingleinstancecallback
    const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
        // Someone tried to run a second instance, we should focus our window.
        if (!windowManager) {
            return;
        }

        const window = windowManager.getWindow();
        if (window) {
            if (window.isMinimized()) {
                window.restore();
            }
            window.focus();
        }
    });

    if (shouldQuit) {
        app.quit();
        return;
    }

    // Create the user data directory if it does not exist
    const userData = app.getPath('userData');
    fse.mkdirsSync(userData);

    app.on('ready', () => {
        cnc({ host: '127.0.0.1', port: 0 }, (err, server) => {
            if (err) {
                console.error('Error:', err);
                return;
            }

            const address = server.address();
            if (!address) {
                console.error('Unable to start the server:', address);
                return;
            }

            setApplicationMenu();

            windowManager = new WindowManager();
            windowManager.openWindow({
                title: `${pkg.name} ${pkg.version}`,
                url: `http://${address.address}:${address.port}`
            });
        });
    });
};

main();
<commit_msg>Use mkdirp.sync() instead of fse.mkdirsSync()<commit_after>/* eslint import/no-unresolved: 0 */
import { app } from 'electron';
import mkdirp from 'mkdirp';
import { WindowManager, handleStartupEvent, setApplicationMenu } from './desktop';
import cnc from './cnc';
import pkg from './package.json';

let windowManager = null;

const main = () => {
    if (handleStartupEvent()) {
        return;
    }

    // https://github.com/electron/electron/blob/master/docs/api/app.md#appmakesingleinstancecallback
    const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
        // Someone tried to run a second instance, we should focus our window.
        if (!windowManager) {
            return;
        }

        const window = windowManager.getWindow();
        if (window) {
            if (window.isMinimized()) {
                window.restore();
            }
            window.focus();
        }
    });

    if (shouldQuit) {
        app.quit();
        return;
    }

    // Create the user data directory if it does not exist
    const userData = app.getPath('userData');
    mkdirp.sync(userData);

    app.on('ready', () => {
        cnc({ host: '127.0.0.1', port: 0 }, (err, server) => {
            if (err) {
                console.error('Error:', err);
                return;
            }

            const address = server.address();
            if (!address) {
                console.error('Unable to start the server:', address);
                return;
            }

            setApplicationMenu();

            windowManager = new WindowManager();
            windowManager.openWindow({
                title: `${pkg.name} ${pkg.version}`,
                url: `http://${address.address}:${address.port}`
            });
        });
    });
};

main();
<|endoftext|>


<commit_before>'use strict';

require('require');
require('prototype_creep_startup_tasks');
require('prototype_creep_move');
require('prototype_roomPosition');
require('prototype_room_init');
require('prototype_room_costmatrix');
require('visualizer');
require('screepsplus');

if (config.profiler.enabled) {
  try {
    var profiler = require('screeps-profiler');
    profiler.enable();
  } catch (e) {
    console.log('screeps-profiler not found');
    config.profiler.enabled = false;
  }
}
brain.stats.init();

var main = function() {
  if (Game.cpu.bucket < Game.cpu.tickLimit * 2) {
    console.log('Skipping tick ' + Game.time + ' due to lack of CPU.');
    return;
  }

  brain.prepareMemory();
  brain.handleNextroom();
  brain.handleSquadmanager();
  brain.handleIncomingTransactions();
  brain.stats.addRoot();
  Memory.myRooms = _.map(_.filter(Game.rooms, r => r.execute()), r => r.name);

  if (config.visualizer.enabled && config.visualizer.refresh) {
    visualizer.render();
  }
  brain.stats.add(['cpu'], {
    used: Game.cpu.getUsed()
  });
};

module.exports.loop = function() {
  if (config.profiler.enabled) {
    profiler.wrap(function() {
      main();
    });
  } else {
    main();
  }
};
<commit_msg>Change check to check for Game.cpu.tickLimit<commit_after>'use strict';

require('require');
require('prototype_creep_startup_tasks');
require('prototype_creep_move');
require('prototype_roomPosition');
require('prototype_room_init');
require('prototype_room_costmatrix');
require('visualizer');
require('screepsplus');

if (config.profiler.enabled) {
  try {
    var profiler = require('screeps-profiler');
    profiler.enable();
  } catch (e) {
    console.log('screeps-profiler not found');
    config.profiler.enabled = false;
  }
}
brain.stats.init();

var main = function() {
  if (Game.cpu.bucket < Game.cpu.tickLimit) {
    console.log('Skipping tick ' + Game.time + ' due to lack of CPU.');
    return;
  }

  brain.prepareMemory();
  brain.handleNextroom();
  brain.handleSquadmanager();
  brain.handleIncomingTransactions();
  brain.stats.addRoot();
  Memory.myRooms = _.map(_.filter(Game.rooms, r => r.execute()), r => r.name);

  if (config.visualizer.enabled && config.visualizer.refresh) {
    visualizer.render();
  }
  brain.stats.add(['cpu'], {
    used: Game.cpu.getUsed()
  });
};

module.exports.loop = function() {
  if (config.profiler.enabled) {
    profiler.wrap(function() {
      main();
    });
  } else {
    main();
  }
};
<|endoftext|>


<commit_before>/**
 * @file This is the central "main process" node-only window/update manager
 * script file for PacnackePainter. This is loaded first and is always running
 * as long as the application runs.
 **/
"use strict";

var app = require('electron').app;  // Module to control application life.
var appPath = app.getAppPath() + '/';
var fs = require('fs-plus');
var _ = require('underscore');

// Module to create native browser window.
var BrowserWindow = require('electron').BrowserWindow;
var dialog = require('electron').dialog;
var i18n = require('i18next');

// Report crashes to our server.
//require('crash-reporter').start();

// Handle app startup with command line arguments from squirrel (windows).
function start() {
  // Process squirrel update/install command line.
  if (process.platform === 'win32') {
    var SquirrelUpdate = require('./squirrel-update');
    var squirrelCommand = process.argv[1];
    if (SquirrelUpdate.handleStartupEvent(app, squirrelCommand)) {
      // If we processed one, quit right after.
      return false;
    }
  }

  settingsInit();
  windowInit();
}

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;

/**
 * Initialize the settings, constants & defaults
 */
function settingsInit() {
  // Global application constants (set and referenced from here only!)
  // TODO: Gather more of these from around the app.
  app.constants = {
    pancakeShades: [
      '#ffea7e',
      '#e2bc15',
      '#a6720e',
      '#714a00'
    ],
    botSpeedMax: 6600, // Real world PancakeBot speed maximum.

    // Real world measurement of the griddle maximum dimensions in MM
    griddleSize: {
      width: 507.5,
      height: 267.7,
    },

    // Printable/drawable area in MM from furthest griddle edge.
    printableArea: {
      offset: {
        left: 36.22,
        top: 34.77,
        right: 42, // Used exclusively for GCODE X offset
      },
      width: 443,
      height: 210,
    },
  };

  // Global user configurable settings.
  var settingsFile = appPath + 'settings.json';
  app.settings = {
    v: {}, // Values are saved to/from here
    defaults: {
      window: {
        width: 980,
        height: 600,
        y: 'center',
        x: 'center'
      },
      lastFile: '',
      flatten: 2,          // Flatten curve value (smaller value = more points)
      shutoff: 25,          // Remaining line length threshold for pump shutoff
      startwait: 350,       // Time to wait for batter flow begin
      endwait: 250,         // Time to wait for batter flow at end of line
      changewait: 15,       // Number of seconds to wait between shade changes.
      botspeed: 70,         // Locked stepper speed percentage written to GCODE
      usecolorspeed: false, // Whether to use different speeds for colors.
      useshortest: true,   // Whether to travel sort the final layer.
      botspeedcolor1: 100,  // Light speed.
      botspeedcolor2: 80,   // Medium speed.
      botspeedcolor3: 80,   // Medium Dark speed.
      botspeedcolor4: 50,   // Dark speed.
      uselinefill: false,   // Whether to use line fill over shape fill.
      fillspacing: 10,      // Space between each trace fill line
      fillangle: 23,        // Angle of line for trace fill
      fillthresh: 27,       // Threshold to group zig zags
      shapefillwidth: 3     // Effective fill space.
    },
    clear: function() {
      fs.removeSync(settingsFile);
    },
    save: function() {
      fs.writeFileSync(settingsFile, JSON.stringify(this.v));
    },
    load: function() {
      this.v = {};
      try {
        if (fs.existsSync(settingsFile)) {
          this.v = JSON.parse(fs.readFileSync(settingsFile));
        }
      } catch(e) {}

      // Comb in defaults
      for(var i in this.defaults) {
        if (!_.has(this.v, i)) {
          this.v[i] = this.defaults[i];
        }
      }

      this.save(); // Resave when we're done loading.
    },
    reset: function() {
      this.clear();
      this.load();
    },
  };

  app.settings.load();
}

/**
 * Initialize the windows/attach menus
 */
function windowInit() {
  // Quit when all windows are closed (including OSX).
  app.on('window-all-closed', function() {
      app.quit();
  });

  // This method will be called when Electron has done all the initialization
  // and should be ready for creating menus & browser windows.
  app.on('ready', function() {
    i18n.init({
      ns: {
        namespaces: ['app', 'menus'],
        defaultNs: 'app'
      },
      // Path to find file
      resGetPath: appPath + 'locales/__lng__/__ns__-__lng__.json',
      // Path to store file
      resSetPath: appPath + 'locales/__lng__/__ns__-__lng__.json',
      sendMissingTo: 'fallback|current|all', // Send missing values to
      lng: 'en-US'
    }, function(){
      // Setup main window.
      var windowSettings = {
        minWidth: 680,
        minHeight: 420,
        width: app.settings.v.window.width,
        height: app.settings.v.window.height,
        resizable: true,
        icon: appPath + "resources/app.png",
        title: "PancakePainter",
        fullscreenable: false // Workaround for fullscreen OSX bug :'(
      };

      // Centered or fixed window position?
      if (app.settings.v.window.y === 'center') {
        windowSettings.center = true;
      } else {
        windowSettings.x = app.settings.v.window.x;
        windowSettings.y = app.settings.v.window.y;
      }

      // Create the main application window.
      mainWindow = new BrowserWindow(windowSettings);

      // Window wrapper for dialog (can't include module outside of this) :P
      mainWindow.dialog = function(options, callback) {
        return dialog['show' + options.t](mainWindow, options, callback);
      };

      // and load the index.html of the app.
      mainWindow.loadURL('file://' + __dirname + '/index.html');

      // Save Move/Resize back to file
      mainWindow.on('move', function(){
        var b = this.getBounds();
        app.settings.v.window.x = b.x;
        app.settings.v.window.y = b.y;
        app.settings.v.window.width = b.width;
        app.settings.v.window.height = b.height;
        app.settings.save();
      });

      // Emitted when the window is closed.
      mainWindow.on('closed', function() {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
      });
    });
  });
}

// Actually start initializing. We do this here to ensure we can completely exit
// initialization without loading any windows during Squirrel updates.
start();
<commit_msg>On Linux store user config in .config/PancakePainter/config.json<commit_after>/**
 * @file This is the central "main process" node-only window/update manager
 * script file for PacnackePainter. This is loaded first and is always running
 * as long as the application runs.
 **/
"use strict";
const path = require('path');

var app = require('electron').app;  // Module to control application life.
var appPath = app.getAppPath() + '/';
var fs = require('fs-plus');
var _ = require('underscore');

// Module to create native browser window.
var BrowserWindow = require('electron').BrowserWindow;
var dialog = require('electron').dialog;
var i18n = require('i18next');

// Report crashes to our server.
//require('crash-reporter').start();

// Handle app startup with command line arguments from squirrel (windows).
function start() {
  // Process squirrel update/install command line.
  if (process.platform === 'win32') {
    var SquirrelUpdate = require('./squirrel-update');
    var squirrelCommand = process.argv[1];
    if (SquirrelUpdate.handleStartupEvent(app, squirrelCommand)) {
      // If we processed one, quit right after.
      return false;
    }
  }

  settingsInit();
  windowInit();
}

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;

/**
 * Initialize the settings, constants & defaults
 */
function settingsInit() {
  // Global application constants (set and referenced from here only!)
  // TODO: Gather more of these from around the app.
  app.constants = {
    pancakeShades: [
      '#ffea7e',
      '#e2bc15',
      '#a6720e',
      '#714a00'
    ],
    botSpeedMax: 6600, // Real world PancakeBot speed maximum.

    // Real world measurement of the griddle maximum dimensions in MM
    griddleSize: {
      width: 507.5,
      height: 267.7,
    },

    // Printable/drawable area in MM from furthest griddle edge.
    printableArea: {
      offset: {
        left: 36.22,
        top: 34.77,
        right: 42, // Used exclusively for GCODE X offset
      },
      width: 443,
      height: 210,
    },
  };

  // Global user configurable settings.
  var settingsFile = appPath + 'settings.json';
  var userSettingsFile = path.join(process.env.HOME, '.config/PancakePainter/config.json');
  app.settings = {
    v: {}, // Values are saved to/from here
    defaults: {
      window: {
        width: 980,
        height: 600,
        y: 'center',
        x: 'center'
      },
      lastFile: '',
      flatten: 2,          // Flatten curve value (smaller value = more points)
      shutoff: 25,          // Remaining line length threshold for pump shutoff
      startwait: 350,       // Time to wait for batter flow begin
      endwait: 250,         // Time to wait for batter flow at end of line
      changewait: 15,       // Number of seconds to wait between shade changes.
      botspeed: 70,         // Locked stepper speed percentage written to GCODE
      usecolorspeed: false, // Whether to use different speeds for colors.
      useshortest: true,   // Whether to travel sort the final layer.
      botspeedcolor1: 100,  // Light speed.
      botspeedcolor2: 80,   // Medium speed.
      botspeedcolor3: 80,   // Medium Dark speed.
      botspeedcolor4: 50,   // Dark speed.
      uselinefill: false,   // Whether to use line fill over shape fill.
      fillspacing: 10,      // Space between each trace fill line
      fillangle: 23,        // Angle of line for trace fill
      fillthresh: 27,       // Threshold to group zig zags
      shapefillwidth: 3     // Effective fill space.
    },
    clear: function() {
      fs.removeSync(settingsFile);
    },
    save: function() {
      try {
        fs.writeFileSync(settingsFile, JSON.stringify(this.v));
      } catch (e) {
        fs.writeFileSync(userSettingsFile, JSON.stringify(this.v));
      }
    },
    load: function() {
      this.v = {};
      try {
        if (fs.existsSync(settingsFile)) {
          this.v = JSON.parse(fs.readFileSync(settingsFile));
        }
      } catch(e) {}

      // Comb in defaults
      for(var i in this.defaults) {
        if (!_.has(this.v, i)) {
          this.v[i] = this.defaults[i];
        }
      }

      // load user config
      var user_config = {};
      try {
        if (fs.existsSync(userSettingsFile)) {
          user_config = JSON.parse(fs.readFileSync(userSettingsFile));
        }
      } catch(e) {}
      for(var i in user_config) {
        this.v[i] = user_config[i];
      }

      this.save(); // Resave when we're done loading.
    },
    reset: function() {
      this.clear();
      this.load();
    },
  };

  app.settings.load();
}

/**
 * Initialize the windows/attach menus
 */
function windowInit() {
  // Quit when all windows are closed (including OSX).
  app.on('window-all-closed', function() {
      app.quit();
  });

  // This method will be called when Electron has done all the initialization
  // and should be ready for creating menus & browser windows.
  app.on('ready', function() {
    i18n.init({
      ns: {
        namespaces: ['app', 'menus'],
        defaultNs: 'app'
      },
      // Path to find file
      resGetPath: appPath + 'locales/__lng__/__ns__-__lng__.json',
      // Path to store file
      resSetPath: appPath + 'locales/__lng__/__ns__-__lng__.json',
      sendMissingTo: 'fallback|current|all', // Send missing values to
      lng: 'en-US'
    }, function(){
      // Setup main window.
      var windowSettings = {
        minWidth: 680,
        minHeight: 420,
        width: app.settings.v.window.width,
        height: app.settings.v.window.height,
        resizable: true,
        icon: appPath + "resources/app.png",
        title: "PancakePainter",
        fullscreenable: false // Workaround for fullscreen OSX bug :'(
      };

      // Centered or fixed window position?
      if (app.settings.v.window.y === 'center') {
        windowSettings.center = true;
      } else {
        windowSettings.x = app.settings.v.window.x;
        windowSettings.y = app.settings.v.window.y;
      }

      // Create the main application window.
      mainWindow = new BrowserWindow(windowSettings);

      // Window wrapper for dialog (can't include module outside of this) :P
      mainWindow.dialog = function(options, callback) {
        return dialog['show' + options.t](mainWindow, options, callback);
      };

      // and load the index.html of the app.
      mainWindow.loadURL('file://' + __dirname + '/index.html');

      // Save Move/Resize back to file
      mainWindow.on('move', function(){
        var b = this.getBounds();
        app.settings.v.window.x = b.x;
        app.settings.v.window.y = b.y;
        app.settings.v.window.width = b.width;
        app.settings.v.window.height = b.height;
        app.settings.save();
      });

      // Emitted when the window is closed.
      mainWindow.on('closed', function() {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
      });
    });
  });
}

// Actually start initializing. We do this here to ensure we can completely exit
// initialization without loading any windows during Squirrel updates.
start();
<|endoftext|>