<commit_before>'use strict';

var config = (() => {
	var sys = {
		impl: chrome.storage.local,
		get: (name, defaultVal) => new Promise((res) => {
			sys.impl.get(name, (confs) => {
				if (typeof name === "string") res((name in confs) ? confs[name] : defaultVal);
				else res(confs);
			});
		}),
		set: (n, v) => new Promise((res) => {
			var setObj = {};
			if (typeof n === "string") setObj[n] = v;
			else setObj = n;
			sys.impl.set(setObj, res);
		})
	};

	chrome.storage.local.get('sys.local', (items) => {
		if (!items['sys.local']) {
			sys.impl = chrome.storage.sync;
		}
	});

	return sys;
})()

function genID() {
	return (+ new Date()).toString(36) + (Math.random())
}

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

var box = { html: '', style: '' };
var styleDefault, styleUser;

Promise.all([
	window.fetch('box/style.css').then(res => res.text()),
	config.get("user.style", "")
]).then((styles) => {
	styleDefault = styles[0];
	styleUser = styles[1];
	box.style = styleDefault + styleUser;
})

function UpdateBoxHtml(html) {
	var h =
		html.replace(/(src|href)=(["'])(.+?)\2/g, (whole, a, quote, uri) => {
			if (/^\w+\:/.test(uri)) return whole;
			return a + '=' + quote + chrome.runtime.getURL((uri[0] === "/" ? uri : "/box/" + uri)) + quote;
		})
	box.html = h;
}
window.fetch('box/box.html').then(res => res.text()).then(UpdateBoxHtml)

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
	let resp = {};
	switch (msg.type || msg) {
		case "box":
			sendResponse(box)
			break
		case "loaded_mods":
			Object.keys(loaded_mods).forEach((modName) => {
				let mod = loaded_mods[modName]
				resp[modName] = {
					id: mod.id,
					profile: mod.profile
				}
			})
			sendResponse(resp)
			break
		case "conf":
			if (!msg.data) {
				//getting
				sendResponse(conf)
			} else {
				conf = msg.data
			}
			break
	}
})

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

var conf = {
	mods: []
}
var loaded_mods = {}  //a dict

function handleModuleResponse(msg) {
	if (msg.type === "instance") {
		console.log("module response!", msg)
		var infos = msg.instance.id.split("|") // 0: portID 1: reqID 2: order
		var port = port_cs[infos[0]]
		if (!port) return
		port.postMessage({
			id: infos[1],
			order: ~~infos[2],
			instance: msg.instance
		})
	}
}

function handleConnection(port) {
	if (port.name !== "module") return

	var inited = false;
	function onetimeCheck(message) {
		if (inited) return
		inited = true

		if (message.type !== 'profile') {
			port.disconnect()
			return
		}

		var profile = message.profile
		var id = port.sender.id + ":" + profile.id

		loaded_mods[id] = {
			id: id,
			port: port,
			profile: profile
		}

		//FIXME! DEBUG CODE! DO NOT PUBLISTH!
		conf.mods.push(id)

		port.onMessage.addListener(handleModuleResponse)
		port.onDisconnect.addListener(() => {
			delete loaded_mods[id]
		})
	}
	port.onMessage.addListener(onetimeCheck)
}

chrome.runtime.onConnect.addListener(handleConnection)
chrome.runtime.onConnectExternal.addListener(handleConnection)

function local_connect(prop) {
	var c2sListeners = []
	var s2cListeners = []

	var portForServer = {
		name: prop.name,
		sender: {
			id: chrome.runtime.id
		},
		onMessage: {
			addListener: (l) => { c2sListeners.push(l) }
		},
		onDisconnect: {
			addListener: (l) => { }
		},
		postMessage: (msg) => {
			s2cListeners.forEach(l => l(msg))
		}
	}
	handleConnection(portForServer)

	var port = {
		onMessage: {
			addListener: (l) => { s2cListeners.push(l) }
		},
		postMessage: (msg) => {
			c2sListeners.forEach(l => l(msg))
		}
	}
	return port;
}

//////////////////////////////////THIS PART IS FOR CONTENT SCRIPTS

var port_cs = {} //ports that content script created

chrome.runtime.onConnect.addListener((port) => {
	if (port.name !== "page") return
	var portID = genID()
	port_cs[portID] = port

	port.onDisconnect.addListener(() => {
		delete port_cs[portID]
	})
	port.onMessage.addListener((msg) => {
		conf.mods.forEach((mod_id, index) => {
			var mod = loaded_mods[mod_id]
			var instanceRequest = Object.assign(msg.info, {
				id: (portID + "|" + msg.id + "|" + index)
			})
			if (!mod) return

			mod.port.postMessage({
				type: "request",
				request: instanceRequest
			})
		})
	})
})
<commit_msg>Fix local order problem<commit_after>'use strict';

var config = (() => {
	var sys = {
		impl: chrome.storage.local,
		get: (name, defaultVal) => new Promise((res) => {
			sys.impl.get(name, (confs) => {
				if (typeof name === "string") res((name in confs) ? confs[name] : defaultVal);
				else res(confs);
			});
		}),
		set: (n, v) => new Promise((res) => {
			var setObj = {};
			if (typeof n === "string") setObj[n] = v;
			else setObj = n;
			sys.impl.set(setObj, res);
		})
	};

	chrome.storage.local.get('sys.local', (items) => {
		if (!items['sys.local']) {
			sys.impl = chrome.storage.sync;
		}
	});

	return sys;
})()

function genID() {
	return (+ new Date()).toString(36) + (Math.random())
}

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

var box = { html: '', style: '' };
var styleDefault, styleUser;

Promise.all([
	window.fetch('box/style.css').then(res => res.text()),
	config.get("user.style", "")
]).then((styles) => {
	styleDefault = styles[0];
	styleUser = styles[1];
	box.style = styleDefault + styleUser;
})

function UpdateBoxHtml(html) {
	var h =
		html.replace(/(src|href)=(["'])(.+?)\2/g, (whole, a, quote, uri) => {
			if (/^\w+\:/.test(uri)) return whole;
			return a + '=' + quote + chrome.runtime.getURL((uri[0] === "/" ? uri : "/box/" + uri)) + quote;
		})
	box.html = h;
}
window.fetch('box/box.html').then(res => res.text()).then(UpdateBoxHtml)

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
	let resp = {};
	switch (msg.type || msg) {
		case "box":
			sendResponse(box)
			break
		case "loaded_mods":
			Object.keys(loaded_mods).forEach((modName) => {
				let mod = loaded_mods[modName]
				resp[modName] = {
					id: mod.id,
					profile: mod.profile
				}
			})
			sendResponse(resp)
			break
		case "conf":
			if (!msg.data) {
				//getting
				sendResponse(conf)
			} else {
				conf = msg.data
			}
			break
	}
})

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

var conf = {
	mods: []
}
var loaded_mods = {}  //a dict

function handleModuleResponse(msg) {
	if (msg.type === "instance") {
		console.log("module response!", msg.instance.id, msg.instance)
		var infos = msg.instance.id.split("|") // 0: portID 1: reqID 2: order
		var port = port_cs[infos[0]]
		if (!port) return
		port.postMessage({
			id: infos[1],
			order: ~~infos[2],
			instance: msg.instance
		})
	}
}

function handleConnection(port) {
	if (port.name !== "module") return

	var inited = false;
	function onetimeCheck(message) {
		if (inited) return
		inited = true

		if (message.type !== 'profile') {
			port.disconnect()
			return
		}

		var profile = message.profile
		var id = port.sender.id + ":" + profile.id

		loaded_mods[id] = {
			id: id,
			port: port,
			profile: profile
		}

		//FIXME! DEBUG CODE! DO NOT PUBLISTH!
		conf.mods.push(id)

		port.onMessage.addListener(handleModuleResponse)
		port.onDisconnect.addListener(() => {
			delete loaded_mods[id]
		})
	}
	port.onMessage.addListener(onetimeCheck)
}

chrome.runtime.onConnect.addListener(handleConnection)
chrome.runtime.onConnectExternal.addListener(handleConnection)

function local_connect(prop) {
	var c2sListeners = []
	var s2cListeners = []

	var portForServer = {
		name: prop.name,
		sender: {
			id: chrome.runtime.id
		},
		onMessage: {
			addListener: (l) => { c2sListeners.push(l) }
		},
		onDisconnect: {
			addListener: (l) => { }
		},
		postMessage: (msg) => {
			s2cListeners.forEach(l => l(msg))
		}
	}
	handleConnection(portForServer)

	var port = {
		onMessage: {
			addListener: (l) => { s2cListeners.push(l) }
		},
		postMessage: (msg) => {
			c2sListeners.forEach(l => l(msg))
		}
	}
	return port;
}

//////////////////////////////////THIS PART IS FOR CONTENT SCRIPTS

var port_cs = {} //ports that content script created

chrome.runtime.onConnect.addListener((port) => {
	if (port.name !== "page") return
	var portID = genID()
	port_cs[portID] = port

	port.onDisconnect.addListener(() => {
		delete port_cs[portID]
	})
	port.onMessage.addListener((msg) => {
		let baseReq = JSON.stringify(msg.info)
		conf.mods.forEach((mod_id, index) => {
			let mod = loaded_mods[mod_id]
			let instanceRequest = JSON.parse(baseReq)
			instanceRequest.id = (portID + "|" + msg.id + "|" + index)
			instanceRequest.for = mod_id
			if (!mod) return

			console.log('dispatch', mod_id, instanceRequest);

			mod.port.postMessage({
				type: "request",
				request: instanceRequest
			})
		})
	})
})
<|endoftext|>


<commit_before>(function (angular) {
  "use strict";

  angular.module('echarts-ng').provider('$echarts', EchartsAssistanceProvider);

  /**
   * @constructor AdaptableMap
   *
   * @description - simple shim for ES6 Map, Do Not Use It directly
   */
  function AdaptableMap() {
    this.storage = {};
  }

  AdaptableMap.prototype.has = function (identity) {
    return this.storage.hasOwnProperty(identity);
  };

  AdaptableMap.prototype.get = function (identity) {
    return this.storage[identity];
  };

  AdaptableMap.prototype.set = function (identity, instance) {
    this.storage[identity] = instance;
  };

  AdaptableMap.prototype.delete = function (identity) {
    delete this.storage[identity];
  };

  Object.defineProperty(AdaptableMap.prototype, 'size', {
    enumerable: true,
    configurable: false,
    get: function() {
      return Object.keys(this.storage).length;
    }
  });

  /**
   * @ngdoc service
   * @name echarts-ng.service:$echartsProvider
   *
   * @description - echarts-ng util service
   */
  function EchartsAssistanceProvider() {
    var ctx = this;

    // base echarts options
    ctx.GLOBAL_OPTION = {
      theme: 'macarons',
      title: {
        left: 'center',
        top: 'top',
        padding: [20, 10, 10, 10]
      },
      backgroundColor: 'rgba(255, 255, 255, .5)',
      legend: {
        left: 'center',
        top: 'top',
        padding: [20, 10, 10, 10]
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      }
    };

    // modify base echarts options
    ctx.setGlobalOption = function (option) {
      angular.extend(ctx.GLOBAL_OPTION, option);
    };

    /**
     * @ngdoc service
     * @name echarts-ng.service:$echarts
     *
     * @requires $q
     * @requires $timeout
     *
     * @description - echarts-ng util method
     */
    ctx.$get = ['$q', '$timeout', function ($q, $timeout) {
      var assistance = {};

      /**
       * @ngdoc property
       * @name echarts-ng.service:storage
       *
       * @type {object}
       *
       * @description - storage for echarts instance
       */
      assistance.storage = angular.isDefined(Map) ? new Map() : new AdaptableMap();
      assistance.generateInstanceIdentity = generateInstanceIdentity;
      assistance.getEchartsGlobalOption = getEchartsGlobalOption;
      assistance.registerEchartsInstance = registerEchartsInstance;
      assistance.queryEchartsInstance = queryEchartsInstance;
      assistance.removeEchartsInstance = removeEchartsInstance;
      assistance.updateEchartsInstance = updateEchartsInstance;
      assistance.driftPaletteProperty = driftPaletteProperty;
      assistance.driftEchartsPalette = driftEchartsPalette;

      return assistance;

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#getEchartsGlobalOption
       *
       * @description - query the global base echarts option
       */
      function getEchartsGlobalOption() {
        return ctx.GLOBAL_OPTION;
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#generateInstanceIdentity
       *
       * @return {string}
       *
       * @description - generate unique id for different echarts instance
       */
      function generateInstanceIdentity() {
        return Math.random().toString(36).substr(2, 9);
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#registerEchartsInstance
       *
       * @param {string} identity - the identity generated before
       * @param {object} instance - the echarts instance
       *
       * @description - store the specific instance
       */
      function registerEchartsInstance(identity, instance) {
        assistance.storage.set(identity, instance);
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#queryEchartsInstance
       *
       * @param {string} identity - the unique instance id generated by {@link echarts-ng.service:$echarts#generateInstanceIdentity}
       * @return {promise<object>}
       *
       * @description - get the specific echarts instance for event bind or something else
       */
      function queryEchartsInstance(identity) {
        var deferred = $q.defer();

        $timeout(function () {
          if (assistance.storage.has(identity)) {
            deferred.resolve(assistance.storage.get(identity));
          } else {
            console.error('Echarts Identity Not Registered, Please Verify The Process');
            deferred.reject({errorDesc: 'Echarts Identity Not Registered, Please Verify The Process'});
          }
        }, 0);

        return deferred.promise;
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#removeEchartsInstance
       *
       * @param {string} identity - the unique instance id generated by {@link echarts-ng.service:$echarts#generateInstanceIdentity}
       *
       * @description - remove specific instance
       */
      function removeEchartsInstance(identity) {
        if (assistance.storage.has(identity)) {
          assistance.storage.delete(identity);
        }
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#updateEchartsInstance
       *
       * @param {string} identity - the identity generated before
       * @param {object} option - the echarts adaptable option
       *
       * @description - update the instance, switch between loading and draw
       */
      function updateEchartsInstance(identity, option) {
        var instance = assistance.storage.get(identity);

        if (angular.isUndefined(instance)) {
          console.warn("The instance not registered. Probably the exception belongs to the directive wrap");
          return;
        }

        if (angular.isObject(option) && angular.isArray(option.series) && option.series.length) {
          instance.hideLoading();
          instance.setOption(option);
        } else {
          instance.clear();
          instance.showLoading();
        }
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#driftEchartsPalette
       *
       * @param {array} instance - the echarts instance
       *
       * @description - drift the palette, improve echarts appearance when multiple similar instance but can't implode
       */
      function driftEchartsPalette(instance) {
        var option = instance.getOption()
          , originPalette = angular.copy(option.color)
          , palette = driftPaletteProperty(originPalette, assistance.storage.size);

        instance.setOption({color: palette});
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#driftPaletteProperty
       *
       * @param {array} palette - the palette which echarts make use of.
       * @param {number} offset - the palette offset
       *
       * @description - implement for drift the palette
       */
      function driftPaletteProperty(palette, offset) {
        var relative
          , clip
          , length = palette.length;

        relative = offset < length ? offset : offset % length;
        clip = palette.splice(0, relative);

        return palette.concat(clip);
      }
    }];
  }
})(angular);<commit_msg>调整视图区域配置<commit_after>(function (angular) {
  "use strict";

  angular.module('echarts-ng').provider('$echarts', EchartsAssistanceProvider);

  /**
   * @constructor AdaptableMap
   *
   * @description - simple shim for ES6 Map, Do Not Use It directly
   */
  function AdaptableMap() {
    this.storage = {};
  }

  AdaptableMap.prototype.has = function (identity) {
    return this.storage.hasOwnProperty(identity);
  };

  AdaptableMap.prototype.get = function (identity) {
    return this.storage[identity];
  };

  AdaptableMap.prototype.set = function (identity, instance) {
    this.storage[identity] = instance;
  };

  AdaptableMap.prototype.delete = function (identity) {
    delete this.storage[identity];
  };

  Object.defineProperty(AdaptableMap.prototype, 'size', {
    enumerable: true,
    configurable: false,
    get: function() {
      return Object.keys(this.storage).length;
    }
  });

  /**
   * @ngdoc service
   * @name echarts-ng.service:$echartsProvider
   *
   * @description - echarts-ng util service
   */
  function EchartsAssistanceProvider() {
    var ctx = this;

    // base echarts options
    ctx.GLOBAL_OPTION = {
      theme: 'macarons',
      title: {
        left: 'center',
        top: 'top',
        padding: [20, 10, 10, 10]
      },
      grid: {
        top: '15%',
        left: '5%',
        right: '5%',
        bottom: '5%',
        containLabel: true
      },
      backgroundColor: 'rgba(255, 255, 255, .5)',
      legend: {
        left: 'center',
        top: 'top',
        padding: [20, 10, 10, 10]
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      }
    };

    // modify base echarts options
    ctx.setGlobalOption = function (option) {
      angular.extend(ctx.GLOBAL_OPTION, option);
    };

    /**
     * @ngdoc service
     * @name echarts-ng.service:$echarts
     *
     * @requires $q
     * @requires $timeout
     *
     * @description - echarts-ng util method
     */
    ctx.$get = ['$q', '$timeout', function ($q, $timeout) {
      var assistance = {};

      /**
       * @ngdoc property
       * @name echarts-ng.service:storage
       *
       * @type {object}
       *
       * @description - storage for echarts instance
       */
      assistance.storage = angular.isDefined(Map) ? new Map() : new AdaptableMap();
      assistance.generateInstanceIdentity = generateInstanceIdentity;
      assistance.getEchartsGlobalOption = getEchartsGlobalOption;
      assistance.registerEchartsInstance = registerEchartsInstance;
      assistance.queryEchartsInstance = queryEchartsInstance;
      assistance.removeEchartsInstance = removeEchartsInstance;
      assistance.updateEchartsInstance = updateEchartsInstance;
      assistance.driftPaletteProperty = driftPaletteProperty;
      assistance.driftEchartsPalette = driftEchartsPalette;

      return assistance;

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#getEchartsGlobalOption
       *
       * @description - query the global base echarts option
       */
      function getEchartsGlobalOption() {
        return ctx.GLOBAL_OPTION;
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#generateInstanceIdentity
       *
       * @return {string}
       *
       * @description - generate unique id for different echarts instance
       */
      function generateInstanceIdentity() {
        return Math.random().toString(36).substr(2, 9);
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#registerEchartsInstance
       *
       * @param {string} identity - the identity generated before
       * @param {object} instance - the echarts instance
       *
       * @description - store the specific instance
       */
      function registerEchartsInstance(identity, instance) {
        assistance.storage.set(identity, instance);
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#queryEchartsInstance
       *
       * @param {string} identity - the unique instance id generated by {@link echarts-ng.service:$echarts#generateInstanceIdentity}
       * @return {promise<object>}
       *
       * @description - get the specific echarts instance for event bind or something else
       */
      function queryEchartsInstance(identity) {
        var deferred = $q.defer();

        $timeout(function () {
          if (assistance.storage.has(identity)) {
            deferred.resolve(assistance.storage.get(identity));
          } else {
            console.error('Echarts Identity Not Registered, Please Verify The Process');
            deferred.reject({errorDesc: 'Echarts Identity Not Registered, Please Verify The Process'});
          }
        }, 0);

        return deferred.promise;
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#removeEchartsInstance
       *
       * @param {string} identity - the unique instance id generated by {@link echarts-ng.service:$echarts#generateInstanceIdentity}
       *
       * @description - remove specific instance
       */
      function removeEchartsInstance(identity) {
        if (assistance.storage.has(identity)) {
          assistance.storage.delete(identity);
        }
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#updateEchartsInstance
       *
       * @param {string} identity - the identity generated before
       * @param {object} option - the echarts adaptable option
       *
       * @description - update the instance, switch between loading and draw
       */
      function updateEchartsInstance(identity, option) {
        var instance = assistance.storage.get(identity);

        if (angular.isUndefined(instance)) {
          console.warn("The instance not registered. Probably the exception belongs to the directive wrap");
          return;
        }

        if (angular.isObject(option) && angular.isArray(option.series) && option.series.length) {
          instance.hideLoading();
          instance.setOption(option);
        } else {
          instance.clear();
          instance.showLoading();
        }
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#driftEchartsPalette
       *
       * @param {array} instance - the echarts instance
       *
       * @description - drift the palette, improve echarts appearance when multiple similar instance but can't implode
       */
      function driftEchartsPalette(instance) {
        var option = instance.getOption()
          , originPalette = angular.copy(option.color)
          , palette = driftPaletteProperty(originPalette, assistance.storage.size);

        instance.setOption({color: palette});
      }

      /**
       * @ngdoc method
       * @methodOf echarts-ng.service:$echarts
       * @name echarts-ng.service:$echarts#driftPaletteProperty
       *
       * @param {array} palette - the palette which echarts make use of.
       * @param {number} offset - the palette offset
       *
       * @description - implement for drift the palette
       */
      function driftPaletteProperty(palette, offset) {
        var relative
          , clip
          , length = palette.length;

        relative = offset < length ? offset : offset % length;
        clip = palette.splice(0, relative);

        return palette.concat(clip);
      }
    }];
  }
})(angular);<|endoftext|>


<commit_before>/**
 * @fileoverview Ensure async hooks are resolved in QUnit tests.
 * @author Kevin Partington
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var eslint = require("eslint").linter,
    ESLintTester = require("eslint-tester");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

var eslintTester = new ESLintTester(eslint);

eslintTester.addRuleTest("lib/rules/resolve-async", {

    valid: [
        // stop()/start()
        "test('name', function () { stop(); start(); });",
        "asyncTest('name', function () { start(); });",
        "QUnit.test('name', function () { stop(); start(); });",
        "QUnit.asyncTest('name', function () { start(); });",
        "test('name', function () { QUnit.stop(); QUnit.start(); });",
        "asyncTest('name', function () { QUnit.start(); });",
        "QUnit.test('name', function () { QUnit.stop(); QUnit.start(); });",
        "QUnit.asyncTest('name', function () { QUnit.start(); });",

        // assert.async()
        "test('name', function (assert) { var done = assert.async(); done(); });",
        "QUnit.test('name', function (assert) { var done = assert.async(); done(); });",
        "test('name', function (assert) { var done; done = assert.async(); done(); });",
        "QUnit.test('name', function (assert) { var done; done = assert.async(); done(); });"
    ],

    invalid: [
        // stop()/start()
        {
            code: "asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },

        // assert.async()
        {
            code: "test('name', function (assert) { var done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function (assert) { var done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function (assert) { var done; done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function (assert) { var done; done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        }
    ]

});
<commit_msg>More unit tests for multiple stop() calls.<commit_after>/**
 * @fileoverview Ensure async hooks are resolved in QUnit tests.
 * @author Kevin Partington
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var eslint = require("eslint").linter,
    ESLintTester = require("eslint-tester");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

var eslintTester = new ESLintTester(eslint);

eslintTester.addRuleTest("lib/rules/resolve-async", {

    valid: [
        // stop()/start()
        "test('name', function () { stop(); start(); });",
        "asyncTest('name', function () { start(); });",
        "QUnit.test('name', function () { stop(); start(); });",
        "QUnit.asyncTest('name', function () { start(); });",
        "test('name', function () { QUnit.stop(); QUnit.start(); });",
        "asyncTest('name', function () { QUnit.start(); });",
        "QUnit.test('name', function () { QUnit.stop(); QUnit.start(); });",
        "QUnit.asyncTest('name', function () { QUnit.start(); });",

        // assert.async()
        "test('name', function (assert) { var done = assert.async(); done(); });",
        "QUnit.test('name', function (assert) { var done = assert.async(); done(); });",
        "test('name', function (assert) { var done; done = assert.async(); done(); });",
        "QUnit.test('name', function (assert) { var done; done = assert.async(); done(); });"
    ],

    invalid: [
        // stop()/start()
        {
            code: "asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () {});",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 1 more start() calls",
                type: "CallExpression"
            }]
        },

        // Multiple start() calls needed
        {
            code: "asyncTest('name', function () { stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { stop(); stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { QUnit.stop(); stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () { stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { stop(); stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { stop(); QUnit.stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "asyncTest('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function () { QUnit.stop(); QUnit.stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.asyncTest('name', function () { QUnit.stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function () { QUnit.stop(); QUnit.stop(); });",
            errors: [{
                message: "Need 2 more start() calls",
                type: "CallExpression"
            }]
        },

        // assert.async()
        {
            code: "test('name', function (assert) { var done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function (assert) { var done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "test('name', function (assert) { var done; done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        },
        {
            code: "QUnit.test('name', function (assert) { var done; done = assert.async(); });",
            errors: [{
                message: "Async callback \"done\" is not called",
                type: "CallExpression"
            }]
        }
    ]

});
<|endoftext|>


<commit_before>import fetch from 'isomorphic-fetch';
import {retrieve} from './index';

export const REQUEST_RMS = 'REQUEST_RMS';
export const RECEIVE_RMS = 'RECEIVE_RMS';
export const SELECT_RMS = 'SELECT_RMS';

function shouldFetchRMS(state) {
  const rms = state.recordMatchingSystems;
  if (rms.length === 0 && ! rms.isFetching) {
    return true;
  } else {
    return false;
  }
}

export function fetchRMSIfNeeded() {
  return (dispatch, getState) => {
    if (shouldFetchRMS(getState())) {
      dispatch({type: REQUEST_RMS});
      return dispatch(retrieve(RECEIVE_RMS, '/RecordMatchSystemInterface'));
    }
  };
}

export function createRMS(rms) {
  return (dispatch) => {
    fetch('/RecordMatchSystemInterface', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST',
      body: JSON.stringify(rms)
    });
    return dispatch(retrieve(RECEIVE_RMS, '/RecordMatchSystemInterface'));
  };
}

export function selectRMS(rms) {
  return (dispatch) => {
    return dispatch({type: SELECT_RMS, recordMatchingSystem: rms});
  };
}
<commit_msg>Removing unnecessary dispatch<commit_after>import fetch from 'isomorphic-fetch';
import {retrieve} from './index';

export const REQUEST_RMS = 'REQUEST_RMS';
export const RECEIVE_RMS = 'RECEIVE_RMS';
export const SELECT_RMS = 'SELECT_RMS';

function shouldFetchRMS(state) {
  const rms = state.recordMatchingSystems;
  if (rms.length === 0 && ! rms.isFetching) {
    return true;
  } else {
    return false;
  }
}

export function fetchRMSIfNeeded() {
  return (dispatch, getState) => {
    if (shouldFetchRMS(getState())) {
      dispatch({type: REQUEST_RMS});
      return dispatch(retrieve(RECEIVE_RMS, '/RecordMatchSystemInterface'));
    }
  };
}

export function createRMS(rms) {
  return (dispatch) => {
    fetch('/RecordMatchSystemInterface', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST',
      body: JSON.stringify(rms)
    });
    return dispatch(retrieve(RECEIVE_RMS, '/RecordMatchSystemInterface'));
  };
}

export function selectRMS(rms) {
  return {type: SELECT_RMS, recordMatchingSystem: rms};
}
<|endoftext|>


<commit_before>module.exports = {
    assets: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'fonts/**/*',
                'images/**/*',
                'favicon.ico',
                'styles/css/*.css'
            ]
        },{
            expand: true,
            dot: true,
            cwd: 'node_modules/superdesk-core/',
            dest: '<%= distDir %>',
            src: [
                'scripts/**/*.html',
            ]
        }]
    },
    locales: {
        files: [
            {
                expand: true,
                cwd: process.cwd(),
                src: ['node_modules/angular-i18n/angular-locale_*.js'],
                dest: '<%= distDir %>/locales/',
                flatten: true,
                filter: 'isFile'
            }
        ]
    },
    index: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [ 'index.html' ]
        }]
    },
    sirTrevor: {
        files: [{
            expand: true,
            dot: true,
            cwd: 'node_modules/sir-trevor/',
            dest: '<%= distDir %>',
            src: [ 'sir-trevor.js', 'sir-trevor.css' ]
        }]
    },
    tmp: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= tmpDir %>',
            dest: '<%= distDir %>',
            src: [
                'scripts/lb-templates.js'
            ]
        }]
    },
    docs: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>/docs',
            dest: '<%= distDir %>',
            src: [
                'views/**/*.{html,css,jpg,jpeg,png,gif,json}'
            ]
        },
        {
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'docs/images/**/*.{jpg,jpeg,png,gif}'
            ]
        }]
    },
    js: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'scripts/config.js'
            ]
        }]
    },
    fonts: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'fonts/sd_icons.woff',
                'fonts/sd_icons.eot',
                'fonts/sd_icons.svg',
                'fonts/sd_icons.ttf'
            ]
        }]
    //},
    //bower: {
    //    files: [{
    //        expand: true,
    //        dot: true,
    //        cwd: '<%= distDir %>',
    //        dest: '<%= bowerDir %>',
    //        src: [
    //            'images/**',
    //            'styles/css/bootstrap.css',
    //            'styles/css/app.css',
    //            'scripts/vendor.js',
    //            'scripts/superdesk-core.js',
    //            'scripts/superdesk.js',
    //            'scripts/vendor-docs.js',
    //            'scripts/superdesk-docs-core.js',
    //            'scripts/superdesk-docs-main.js'
    //        ]
    //    }]
    }
};
<commit_msg>Removed comments<commit_after>module.exports = {
    assets: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'fonts/**/*',
                'images/**/*',
                'favicon.ico',
                'styles/css/*.css'
            ]
        },{
            expand: true,
            dot: true,
            cwd: 'node_modules/superdesk-core/',
            dest: '<%= distDir %>',
            src: [
                'scripts/**/*.html',
            ]
        }]
    },
    locales: {
        files: [
            {
                expand: true,
                cwd: process.cwd(),
                src: ['node_modules/angular-i18n/angular-locale_*.js'],
                dest: '<%= distDir %>/locales/',
                flatten: true,
                filter: 'isFile'
            }
        ]
    },
    index: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [ 'index.html' ]
        }]
    },
    sirTrevor: {
        files: [{
            expand: true,
            dot: true,
            cwd: 'node_modules/sir-trevor/',
            dest: '<%= distDir %>',
            src: [ 'sir-trevor.js', 'sir-trevor.css' ]
        }]
    },
    tmp: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= tmpDir %>',
            dest: '<%= distDir %>',
            src: [
                'scripts/lb-templates.js'
            ]
        }]
    },
    docs: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>/docs',
            dest: '<%= distDir %>',
            src: [
                'views/**/*.{html,css,jpg,jpeg,png,gif,json}'
            ]
        },
        {
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'docs/images/**/*.{jpg,jpeg,png,gif}'
            ]
        }]
    },
    js: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'scripts/config.js'
            ]
        }]
    },
    fonts: {
        files: [{
            expand: true,
            dot: true,
            cwd: '<%= appDir %>',
            dest: '<%= distDir %>',
            src: [
                'fonts/sd_icons.woff',
                'fonts/sd_icons.eot',
                'fonts/sd_icons.svg',
                'fonts/sd_icons.ttf'
            ]
        }]
    }
};
<|endoftext|>


<commit_before>const Dispatcher = require('./dispatcher')

const middleware = ['forward', 'replay', 'response']

const events = [
  'error', 'proxyReq', 'proxyRes',
  'route:error', 'route:missing',
  'proxy:response', 'proxy:retry',
  'proxy:error', 'replay:start',
  'replay:error', 'replay:end',
  'replay:stop', 'replay:retry'
]

exports = module.exports = function routeHandler(rocky, route) {
  const dispatcher = new Dispatcher(rocky, route)

  // Propagate route events to the global event bus
  propagateEvents(rocky, route)

  // Propagate middleware to global scope
  propagateMiddleware(rocky, route)

  return dispatcher.dispatch.bind(dispatcher)
}

exports.events = events
exports.middleware = middleware

function propagateEvents(rocky, route) {
  events.forEach(function (event) {
    route.on(event, function () {
      const args = Array.apply(null, arguments)
      rocky.emit.apply(rocky, [ event ].concat(args))
    })
  })
}

function propagateMiddleware(rocky, route) {
  middleware.forEach(function (type) {
    route.useFor(type, function (req, res, next) {
      rocky.mw.run(type, req, res, next)
    })
  })
}
<commit_msg>refactor(dispatcher): expose dispatcher in route instance<commit_after>const Dispatcher = require('./dispatcher')

const middleware = ['forward', 'replay', 'response']

const events = [
  'error', 'proxyReq', 'proxyRes',
  'route:error', 'route:missing',
  'proxy:response', 'proxy:retry',
  'proxy:error', 'replay:start',
  'replay:error', 'replay:end',
  'replay:stop', 'replay:retry'
]

exports = module.exports = function routeHandler(rocky, route) {
  const dispatcher = new Dispatcher(rocky, route)

  // Expose the dispatcher in the route instance, useful for hacking purposes
  route.dispatcher = dispatcher

  // Propagate route events to the global event bus
  propagateEvents(rocky, route)

  // Propagate middleware to global scope
  propagateMiddleware(rocky, route)

  return dispatcher.dispatch.bind(dispatcher)
}

exports.events = events
exports.middleware = middleware

function propagateEvents(rocky, route) {
  events.forEach(function (event) {
    route.on(event, function () {
      const args = Array.apply(null, arguments)
      rocky.emit.apply(rocky, [ event ].concat(args))
    })
  })
}

function propagateMiddleware(rocky, route) {
  middleware.forEach(function (type) {
    route.useFor(type, function (req, res, next) {
      rocky.mw.run(type, req, res, next)
    })
  })
}
<|endoftext|>


<commit_before>import assert from 'assert'
const TYPE_TO_PREFIX = {
  municipality: 'K',
  borough: 'B',
  county: 'F',
  commerceRegion: 'N'
}

const PREFIX_TO_TYPE = Object.keys(TYPE_TO_PREFIX).reduce((acc, key) => {
  acc[TYPE_TO_PREFIX[key]] = key
  return acc
}, {})

const REGION_TYPE_TO_ID_FIELD_MAPPING = {
  municipality: 'kommuneNr',
  county: 'fylkeNr',
  commerceRegion: 'naringsregionNr',
  borough: 'bydelNr'
}

export function split(region) {
  return [region.substring(0, 1).toUpperCase(), region.substring(1)]
}

export function prefixify(region) {
  assert(TYPE_TO_PREFIX[region.type], `No prefix registered for region type ${region.type}`)
  return TYPE_TO_PREFIX[region.type] + region.code
}

export function getHeaderKey(region) {
  assert(REGION_TYPE_TO_ID_FIELD_MAPPING[region.type], `No mapping from region type ${region.type} to header key found`)
  return REGION_TYPE_TO_ID_FIELD_MAPPING[region.type]
}

export function typeForPrefix(prefix) {
  return PREFIX_TO_TYPE[prefix.toUpperCase()]
}

export function regionByCode(code, type, regions) {
  return regions.filter(region => (region.code == code) && region.type == type)[0]
}

export function regionsByParent(parentType, parentCode, regions) {
  return regions.filter(region => region[parentType] == parentCode)
}
<commit_msg>Implement similarMunicipalities method<commit_after>import assert from 'assert'
import similarMunicipalities from '../data/similarMunicipalities'

const TYPE_TO_PREFIX = {
  municipality: 'K',
  borough: 'B',
  county: 'F',
  commerceRegion: 'N'
}

const PREFIX_TO_TYPE = Object.keys(TYPE_TO_PREFIX).reduce((acc, key) => {
  acc[TYPE_TO_PREFIX[key]] = key
  return acc
}, {})

const REGION_TYPE_TO_ID_FIELD_MAPPING = {
  municipality: 'kommuneNr',
  county: 'fylkeNr',
  commerceRegion: 'naringsregionNr',
  borough: 'bydelNr'
}

export function split(region) {
  return [region.substring(0, 1).toUpperCase(), region.substring(1)]
}

export function prefixify(region) {
  assert(TYPE_TO_PREFIX[region.type], `No prefix registered for region type ${region.type}`)
  return TYPE_TO_PREFIX[region.type] + region.code
}

export function getHeaderKey(region) {
  assert(REGION_TYPE_TO_ID_FIELD_MAPPING[region.type], `No mapping from region type ${region.type} to header key found`)
  return REGION_TYPE_TO_ID_FIELD_MAPPING[region.type]
}

export function typeForPrefix(prefix) {
  return PREFIX_TO_TYPE[prefix.toUpperCase()]
}

export function regionByCode(code, type, regions) {
  return regions.filter(region => (region.code == code) && region.type == type)[0]
}

export function regionsByParent(parentType, parentCode, regions) {
  return regions.filter(region => region[parentType] == parentCode)
}

export function comparableMunicipalities(region, regions) {
  if (region.type != 'municipality') {
    return null
  }
  const matching = similarMunicipalities.find(thing => thing.code == region.code)
  assert(matching, `No similar municipalities for region ${region.name} asdf`)
  return matching.similar.map(code => {
    return regionByCode(code, 'municipality', regions)
  })
}
<|endoftext|>


<commit_before>function(doc) {
    // !code util/mvp.js
    // !code util/danger_signs.js
    if(isChildVisitForm(doc)) {
        var indicators = get_indicators(doc),
            meta = doc.form.meta;
        var indicator_keys = new Array();
        if (indicators.child_dob && indicators.child_dob.value) {
            // birthdate found, is child under 5?
            var age = get_age_from_dob(indicators.child_dob.value, meta.timeEnd);
            if (age < 1825*MS_IN_DAY) {
                indicator_keys.push("under5");

                var fever_medication = indicators.fever_medication.value,
                    diarrhea_medication = indicators.diarrhea_medication.value,
                    rdt_result = indicators.rdt_result.value,
                    referral_type = indicators.referral_type.value;

                var rdt_test_received = (rdt_result === 'positive' || rdt_result === 'negative'),
                    rdt_test_positive = (rdt_result === 'positive'),
                    rdt_test_negative = (rdt_result === 'negative'),
                    rdt_not_available = (rdt_result === 'rdt_not_available' || rdt_result === 'rdt_not_conducted'),
                    uncomplicated_fever = false,
                    complicated_fever = false,
                    diarrhea_only = false,
                    antimalarial_received = (fever_medication && (fever_medication.indexOf('anti_malarial') >= 0
                                                                    || fever_medication.indexOf('coartem') >= 0)),
                    diarrhea_medication_received = (diarrhea_medication && diarrhea_medication.indexOf('ors') >= 0),
                    zinc_received = (diarrhea_medication && diarrhea_medication.indexOf('zinc') >= 0);

                try {
                    var danger_signs = get_danger_signs(indicators.immediate_danger_sign.value);
                    if (danger_signs.indexOf('fever') >= 0) {
                        if (danger_signs.length === 1) {
                            uncomplicated_fever = true;
                        } else {
                            complicated_fever = true;
                        }
                    }
                    if (danger_signs.indexOf('diarrhea') >= 0 && danger_signs.length === 1) {
                        diarrhea_only = true;
                    }
                    if (danger_signs.length > 0) {
                        indicator_keys.push("under5_danger_signs");
                    }
                } catch (err) {
                    log('did not process danger signs');
                    log(err);
                }

                var category = "",
                    category_keys = new Array();
                if (uncomplicated_fever && meta.timeEnd) {
                    category = "under5_fever ";
                    if (rdt_test_received)
                        category_keys.push('rdt_test_received');
                    if (rdt_test_positive)
                        category_keys.push('rdt_test_positive');
                    else if (rdt_test_negative)
                        category_keys.push('rdt_test_negative');
                    if (antimalarial_received) {
                        category_keys.push('anti_malarial');
                    }

                    if (rdt_not_available) {
                        indicator_keys.push(category+"rdt_not_available");
                    }

                } else if (complicated_fever && meta.timeEnd) {
                    category = "under5_complicated_fever ";

                    var valid_referrals = ['emergency', 'basic', 'convenient'];

                    if (doc.form.patient_available.referral_given === 'yes' ||
                        (referral_type && valid_referrals.indexOf(referral_type) >= 0)) {
                        category_keys.push('referred');
                    }

                } else if (diarrhea_only && meta.timeEnd) {
                    category = "under5_diarrhea ";

                    if (diarrhea_medication_received)
                        category_keys.push('ors');
                    if (zinc_received)
                        indicator_keys.push(category+"zinc");
                }

                if (category) {
                    var emit_string = "";
                    for (var k in category_keys) {
                        emit_string += category_keys[k] + " ";
                        indicator_keys.push(category+emit_string.trim());
                    }
                    indicator_keys.push(category.trim());
                }
                var visit_date = new Date(meta.timeEnd);

                emit_standard(doc, visit_date, indicator_keys, []);
            }
        }
    }
}
<commit_msg>indicator spec change<commit_after>function(doc) {
    // !code util/mvp.js
    // !code util/danger_signs.js
    if(isChildVisitForm(doc)) {
        var indicators = get_indicators(doc),
            meta = doc.form.meta;
        var indicator_keys = new Array();
        if (indicators.child_dob && indicators.child_dob.value) {
            // birthdate found, is child under 5?
            var age = get_age_from_dob(indicators.child_dob.value, meta.timeEnd);
            if (age < 1825*MS_IN_DAY) {
                indicator_keys.push("under5");

                var fever_medication = indicators.fever_medication.value,
                    diarrhea_medication = indicators.diarrhea_medication.value,
                    rdt_result = indicators.rdt_result.value,
                    referral_type = indicators.referral_type.value;

                var rdt_test_received = (rdt_result === 'positive' || rdt_result === 'negative'),
                    rdt_test_positive = (rdt_result === 'positive'),
                    rdt_test_negative = (rdt_result === 'negative'),
                    rdt_not_available = (rdt_result === 'rdt_not_available' || rdt_result === 'rdt_not_conducted'),
                    uncomplicated_fever = false,
                    complicated_fever = false,
                    diarrhea_only = false,
                    antimalarial_received = (fever_medication && (fever_medication.indexOf('anti_malarial') >= 0
                                                                    || fever_medication.indexOf('coartem') >= 0)),
                    diarrhea_medication_received = (diarrhea_medication && diarrhea_medication.indexOf('ors') >= 0),
                    zinc_received = (diarrhea_medication && diarrhea_medication.indexOf('zinc') >= 0);

                try {
                    var danger_signs = get_danger_signs(indicators.immediate_danger_sign.value),
                        emergency_signs = get_danger_signs(indicators.emergency_danger_sign.value);
                    if (danger_signs.indexOf('fever') >= 0) {
                        if (danger_signs.length === 1) {
                            uncomplicated_fever = true;
                        } else {
                            complicated_fever = true;
                        }
                    }
                    if (danger_signs.indexOf('diarrhea') >= 0 && danger_signs.length === 1) {
                        diarrhea_only = true;
                    }
                    if (danger_signs.length > 0 || emergency_signs.length > 0) {
                        indicator_keys.push("under5_danger_signs");
                    }
                } catch (err) {
                    log('did not process danger signs');
                    log(err);
                }

                var category = "",
                    category_keys = new Array();
                if (uncomplicated_fever && meta.timeEnd) {
                    category = "under5_fever ";
                    if (rdt_test_received)
                        category_keys.push('rdt_test_received');
                    if (rdt_test_positive)
                        category_keys.push('rdt_test_positive');
                    else if (rdt_test_negative)
                        category_keys.push('rdt_test_negative');
                    if (antimalarial_received) {
                        category_keys.push('anti_malarial');
                    }

                    if (rdt_not_available) {
                        indicator_keys.push(category+"rdt_not_available");
                    }

                } else if (complicated_fever && meta.timeEnd) {
                    category = "under5_complicated_fever ";

                    var valid_referrals = ['emergency', 'basic', 'convenient'];

                    if (doc.form.patient_available.referral_given === 'yes' ||
                        (referral_type && valid_referrals.indexOf(referral_type) >= 0)) {
                        category_keys.push('referred');
                    }

                } else if (diarrhea_only && meta.timeEnd) {
                    category = "under5_diarrhea ";

                    if (diarrhea_medication_received)
                        category_keys.push('ors');
                    if (zinc_received)
                        indicator_keys.push(category+"zinc");
                }

                if (category) {
                    var emit_string = "";
                    for (var k in category_keys) {
                        emit_string += category_keys[k] + " ";
                        indicator_keys.push(category+emit_string.trim());
                    }
                    indicator_keys.push(category.trim());
                }
                var visit_date = new Date(meta.timeEnd);

                emit_standard(doc, visit_date, indicator_keys, []);
            }
        }
    }
}
<|endoftext|>


<commit_before>(function () {
  'use strict';

  /**
   * Config
   */

  var BASE_URL = 'http://battlelog.battlefield.com/';
  var UPDATES_PATH = 'updates/';
  var COMCENTER_PATH = 'comcenter/sync/';
  var NOTIFICATIONS_PATH = 'updates/loadNotifications/';
  var colorOffline = [63, 59, 61, 255];
  var colorOnline  = [120, 199, 83, 255];
  var colorIngame  = [96, 192, 246, 255];
  var soundBleep = 'UI_Bleep_Notification.ogg';
  // Test
  var BASE_URL_TEST = 'https://raw.githubusercontent.com/Narno/Battlelog-Notifier/master/test/fixtures/';
  var COMCENTER_PATH_TEST_ONLINE = 'comcenter/sync/online.json';
  var COMCENTER_PATH_TEST_INGAME = 'comcenter/sync/ingame.json';
  var NOTIFICATIONS_PATH_TEST_3 = 'updates/loadNotifications/3.json';
  //var BASE_URL = BASE_URL_TEST;
  //var COMCENTER_PATH = COMCENTER_PATH_TEST_INGAME;
  //var NOTIFICATIONS_PATH = NOTIFICATIONS_PATH_TEST_3;

  /**
   * Main functions
   */

  // Settings
  // @too should move
  var Settings = (function () {
    var defaults = {
      game: 'bf4',
      iconShowOffline: false,
      iconShowOnline: true,
      iconShowIngame: true,
      notifUpdatesIsActivated: false,
      notifUpdatesFrequency: 5,
      notifUpdatesIsSound: true,
      notifFriendsIsActivated: false,
    };

    var settings = {
      storage: {
        get: function (name) {
          var item = localStorage.getItem(name);
          if (item === null) {
            return ({}.hasOwnProperty.call(defaults, name) ? defaults[name] : void 0);
          } else if (item === 'true' || item === 'false') {
            return (item === 'true');
          }
          return item;
        },
        set: localStorage.setItem.bind(localStorage)
      }
    };

    return settings;
  })();

  // Friends count function
  window.FriendsCount = function (callback) {
    xhr('GET', getFriendsUrlJson(Settings.storage.get('game')), function (data) {
      var key;
      var friendsCount = 0;
      var friendsOnlineCount = 0;
      var friendsIngameCount = 0;
      var count = '0';
      var status;
      var statusLabel;

      if (data === false) {
        callback(false);
      }

      try {
        var json = JSON.parse(data);
        if (json.type == 'success') {
          if (json.data.originavailable) {
            // count friends
            for(key in json.data.friendscomcenter) {
              if(json.data.friendscomcenter.hasOwnProperty(key)) {
                friendsCount++;
                if (json.data.friendscomcenter[key].presence.isOnline) {
                  friendsOnlineCount++;
                }
                if (json.data.friendscomcenter[key].presence.isPlaying) {
                  friendsIngameCount++;
                }
              }
            }
            if (friendsIngameCount > 0) {
              count = friendsIngameCount.toString();
              status = 'ingame';
              statusLabel = chrome.i18n.getMessage('statusIngame');
            } else {
              if (friendsOnlineCount > 0) {
                count = friendsOnlineCount.toString();
                status = 'online';
                statusLabel = chrome.i18n.getMessage('statusOnline');
              } else {
                count = friendsCount.toString();
                status = 'offline';
                statusLabel = chrome.i18n.getMessage('statusOffline');
              }
            }
            // desktop notification
            // @todo move code
            if (Settings.storage.get('notifFriendsIsActivated')) {
              if (Settings.storage.get('countIngame') !== null) {
                var friendsIngameCountPrev = Settings.storage.get('countIngame');
                if (friendsIngameCount > friendsIngameCountPrev) {
                  renderFriendsNotification(friendsIngameCount.toString(), chrome.i18n.getMessage('statusIngame'));
                }
              }
              if (friendsIngameCount > 0) {
                Settings.storage.set('countIngame', friendsIngameCount);
              }
              if (Settings.storage.get('countOnline') !== null) {
                var friendsOnlineCountPrev = Settings.storage.get('countOnline');
                if (friendsOnlineCount > friendsOnlineCountPrev) {
                  renderFriendsNotification((friendsOnlineCount - friendsIngameCount).toString(), chrome.i18n.getMessage('statusOnline'));
                }
              }
              if (friendsOnlineCount > 0) {
                Settings.storage.set('countOnline', friendsOnlineCount);
              }
            }
            //
          // EA Origin not available
          } else {
            count = '0';
            status = 'offline';
            statusLabel = chrome.i18n.getMessage('statusOffline');
          }
          callback(count, status, statusLabel);
        } else {
          callback(false);
        }
      } catch (e) {
        console.error("Parsing error:", e);
        callback(false);
        return;
      }
    });
  };

  // Notifications count function
  window.NotificationsCount = function (callback) {
    xhr('GET', getNotificationsUrlJson(Settings.storage.get('game')), function (data) {
      var count = '0';

      if (data === false) {
        callback(false);
      }

      var json = JSON.parse(data);
      if (json.type == 'success') {
        count = json.data.numUnread.toString();
        callback(count);
      } else {
        callback(false);
      }
    });
  };

  // update badge
  function updateBadge() {
    var color, badgeText = true;
    new FriendsCount(function (count, status, statusLabel) {
      if (count !== false) {
        switch(status) {
          case 'ingame':
            color = colorIngame;
            if (!Settings.storage.get('iconShowIngame')) {
              count = '0';
              badgeText = false;
            }
            break;
          case 'online':
            color = colorOnline;
            if (!Settings.storage.get('iconShowOnline')) {
              count = '0';
              badgeText = false;
            }
            break;
          case 'offline':
            color = colorOffline;
            if (!Settings.storage.get('iconShowOffline')) {
              count = '0';
              badgeText = false;
            }
            break;
        }
        if (badgeText) {
          renderBadge((count !== '0' ? count : ''), color, chrome.i18n.getMessage('browserActionDefaultTitle', [count, statusLabel]));
        } else {
          renderBadge('', color, '');
        }
      } else {
        renderBadge('?', [190, 190, 190, 230], chrome.i18n.getMessage('browserActionErrorTitle'));
      }
    });
  }

  function showNotificationUpdates() {
    var sound = false;
    if (!chrome.notifications || !Settings.storage.get('notifUpdatesIsActivated')) {
      return;
    }
    if (Settings.storage.get('notifUpdatesIsSound')) {
      sound = true;
    }
    new NotificationsCount(function (count) {
      if (count !== false && count > 0) {
        renderUpdatesNotification(count, sound);
      }
    });
  }

  /**
   * Helpers
   */

  // XHR helper function
  var xhr = function () {
    var xhr = new XMLHttpRequest();
    return function(method, url, callback) {
      xhr.onreadystatechange = function () {
        // request finished and response is ready
        if (xhr.readyState === 4) {
          if (xhr.status !== 200) {
            callback(false);
          }
          callback(xhr.responseText);
        }
      };
      xhr.open(method, url);
      xhr.send();
    };
  }();

  function getHomeUrl(game) {
    return BASE_URL + game + '/';
  }
  function getUpdateUrl(game) {
    return BASE_URL + game + '/' + UPDATES_PATH;
  }
  function getFriendsUrlJson(game) {
    return BASE_URL + game + '/' + COMCENTER_PATH;
  }
  function getNotificationsUrlJson(game) {
    return BASE_URL + game + '/' + NOTIFICATIONS_PATH;
  }

  // badge renderer
  function renderBadge(badge, color, title) {
    chrome.browserAction.setBadgeText({
      text: badge
    });
    chrome.browserAction.setBadgeBackgroundColor({
      color: color
    });
    chrome.browserAction.setTitle({
      title: title
    });
  }

  // updates notitifcation renderer
  function renderUpdatesNotification(count, sound) {
    var opt = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationUpdatesTitle'),
      message: chrome.i18n.getMessage('notificationUpdatesMessage', [count]),
      iconUrl: "icon-48.png",
      buttons: [
        { title: chrome.i18n.getMessage('notificationButton2Title') },
      ]
    };
    var optOpera = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationUpdatesTitle'),
      message: chrome.i18n.getMessage('notificationUpdatesMessage', [count]),
      iconUrl: "icon-48.png"
    };
    var notification = chrome.notifications.create('showNotificationUpdates', opt, function() {
      if (sound) {
        playSound();
      }
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        if (chrome.runtime.lastError.message == "Adding buttons to notifications is not supported.") {
          var notification = chrome.notifications.create('showNotificationUpdates', optOpera, function() {});
        }
        return;
      }
    });
  }

  // friends notitifcation renderer
  function renderFriendsNotification(count, status) {
    var opt = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationFriendsTitle'),
      message: chrome.i18n.getMessage('notificationFriendsMessage', [count, status]),
      iconUrl: "icon-48.png"
    };
    var notification = chrome.notifications.create('friendsNotification' + status, opt, function(id) {
      setTimeout(function() {
        chrome.notifications.clear(id);
      }, 4000);
    });
  }

  function playSound() {
    var notifAudio = new Audio();
    notifAudio.src = soundBleep;
    notifAudio.play();
  }

  function isBattlelogUrl(url) {
    return url.indexOf(getHomeUrl(Settings.storage.get('game'))) === 0;
  }

  function isBattlelogUpdatesUrl(url) {
    return url.indexOf(getUpdateUrl(Settings.storage.get('game'))) === 0;
  }

  function openBattlelogHomeInTab(flag) {
    // check if Battle is already open
    chrome.tabs.getAllInWindow(undefined, function(tabs) {
      for (var i = 0, tab; tab = tabs[i]; i++) {
        if (tab.url && isBattlelogUrl(tab.url)) {
          chrome.tabs.update(tab.id, {selected: true}, function(tab) {
            if (flag) {
              clickOnFlag();
            }
          });
          return;
        }
      }
      chrome.tabs.create({url: getHomeUrl(Settings.storage.get('game'))}, function(tab) {
        if (flag) {
          clickOnFlag();
        }
      });
    });
  }

  function openBattlelogUpdatesInTab() {
    // check if Battlelog is already open
    chrome.tabs.getAllInWindow(undefined, function(tabs) {
      for (var i = 0, tab; tab = tabs[i]; i++) {
        if (tab.url && isBattlelogUpdatesUrl(tab.url)) {
          chrome.tabs.update(tab.id, {selected: true});
          return;
        }
      }
      chrome.tabs.create({url: getUpdateUrl(Settings.storage.get('game'))});
    });
  }

  function clickOnFlag() {
    chrome.tabs.executeScript({
      file: 'vendor/zepto.min.js',
      runAt: 'document_end'
    }, function() {
      chrome.tabs.executeScript({
        code: "$('#updates-icon').click();",
        runAt: 'document_end'
      });
    });
  }

  /**
   * Events
   */

  // alarms
  chrome.alarms.create('badge', {periodInMinutes: 1});
  if (Settings.storage.get('notifUpdatesIsActivated') && Settings.storage.get('notifUpdatesFrequency')) {
    chrome.alarms.create('notification', {periodInMinutes: parseInt(Settings.storage.get('notifUpdatesFrequency'))});
  }
  chrome.alarms.onAlarm.addListener(function (alarm) {
    if (alarm.name == 'badge') {
      chrome.runtime.sendMessage({do: 'update_badge'});
    }
    if (alarm.name == 'notification') {
      showNotificationUpdates();
    }
  });

  // browser action
  chrome.browserAction.onClicked.addListener(function () {
    chrome.runtime.sendMessage({do: 'update_badge'});
    chrome.runtime.sendMessage({do: 'show_updates_notification'});
    openBattlelogHomeInTab();
  });

  if (chrome.notifications) {
    // notification action
    chrome.notifications.onClicked.addListener(function (notificationId) {
      if (notificationId == 'showNotificationUpdates') {
        chrome.notifications.clear(notificationId);
        openBattlelogHomeInTab(true);
      }
    });
    // notification button(s) action
    chrome.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
      if (notificationId == 'showNotificationUpdates') {
        switch (buttonIndex) {
          case 0:
            chrome.notifications.clear(notificationId);
            openBattlelogUpdatesInTab();
            break;
        }
      }
    });
  }

  // check if new version is available
  chrome.runtime.onUpdateAvailable.addListener(function (details) {
    var manifest = chrome.runtime.getManifest();
    console.log(manifest.name + " updating to v" + details.version);
    chrome.runtime.reload();
  });
  // check whether new version is installed
  chrome.runtime.onInstalled.addListener(function (details) {
    var manifest = chrome.runtime.getManifest();
    if (details.reason == 'install') {
      console.log(manifest.name + " first install (v" + manifest.version + ")");
    } else if (details.reason == 'update') {
      console.log(manifest.name + " updated from v" + details.previousVersion + " to v" + manifest.version);
    }
    chrome.runtime.sendMessage({do: 'update_badge'});
    chrome.tabs.create({url: chrome.extension.getURL('options.html')});
  });

  // on message update badge
  chrome.runtime.onMessage.addListener(function (message, sender, response) {
    switch (message.do) {
      case 'update_badge':
        updateBadge();
        break;
      case 'show_updates_notification':
        showNotificationUpdates();
        break;
      case 'show_updates_notification_test':
        var sound = false;
        if (!chrome.notifications) {
          return;
        }
        if (Settings.storage.get('notifUpdatesIsSound')) {
          sound = true;
        }
        console.log('sound? ' + sound);
        renderUpdatesNotification(Math.floor((Math.random()*10)+1), sound);
        break;
      case 'show_friends_notification_test':
        if (!chrome.notifications) {
          return;
        }
        var statusArray = [
          chrome.i18n.getMessage('statusIngame'),
          chrome.i18n.getMessage('statusOnline')
        ];
        renderFriendsNotification(Math.floor((Math.random()*10)+1), statusArray[Math.floor(Math.random()*statusArray.length)]);
        break;
    }
  });
})();<commit_msg>Fixing "onInstalled" event handler.<commit_after>(function () {
  'use strict';

  /**
   * Config
   */

  var BASE_URL = 'http://battlelog.battlefield.com/';
  var UPDATES_PATH = 'updates/';
  var COMCENTER_PATH = 'comcenter/sync/';
  var NOTIFICATIONS_PATH = 'updates/loadNotifications/';
  var colorOffline = [63, 59, 61, 255];
  var colorOnline  = [120, 199, 83, 255];
  var colorIngame  = [96, 192, 246, 255];
  var soundBleep = 'UI_Bleep_Notification.ogg';
  // Test
  var BASE_URL_TEST = 'https://raw.githubusercontent.com/Narno/Battlelog-Notifier/master/test/fixtures/';
  var COMCENTER_PATH_TEST_ONLINE = 'comcenter/sync/online.json';
  var COMCENTER_PATH_TEST_INGAME = 'comcenter/sync/ingame.json';
  var NOTIFICATIONS_PATH_TEST_3 = 'updates/loadNotifications/3.json';
  //var BASE_URL = BASE_URL_TEST;
  //var COMCENTER_PATH = COMCENTER_PATH_TEST_INGAME;
  //var NOTIFICATIONS_PATH = NOTIFICATIONS_PATH_TEST_3;

  /**
   * Main functions
   */

  // Settings
  // @too should move
  var Settings = (function () {
    var defaults = {
      game: 'bf4',
      iconShowOffline: false,
      iconShowOnline: true,
      iconShowIngame: true,
      notifUpdatesIsActivated: false,
      notifUpdatesFrequency: 5,
      notifUpdatesIsSound: true,
      notifFriendsIsActivated: false,
    };

    var settings = {
      storage: {
        get: function (name) {
          var item = localStorage.getItem(name);
          if (item === null) {
            return ({}.hasOwnProperty.call(defaults, name) ? defaults[name] : void 0);
          } else if (item === 'true' || item === 'false') {
            return (item === 'true');
          }
          return item;
        },
        set: localStorage.setItem.bind(localStorage)
      }
    };

    return settings;
  })();

  // Friends count function
  window.FriendsCount = function (callback) {
    xhr('GET', getFriendsUrlJson(Settings.storage.get('game')), function (data) {
      var key;
      var friendsCount = 0;
      var friendsOnlineCount = 0;
      var friendsIngameCount = 0;
      var count = '0';
      var status;
      var statusLabel;

      if (data === false) {
        callback(false);
      }

      try {
        var json = JSON.parse(data);
        if (json.type == 'success') {
          if (json.data.originavailable) {
            // count friends
            for(key in json.data.friendscomcenter) {
              if(json.data.friendscomcenter.hasOwnProperty(key)) {
                friendsCount++;
                if (json.data.friendscomcenter[key].presence.isOnline) {
                  friendsOnlineCount++;
                }
                if (json.data.friendscomcenter[key].presence.isPlaying) {
                  friendsIngameCount++;
                }
              }
            }
            if (friendsIngameCount > 0) {
              count = friendsIngameCount.toString();
              status = 'ingame';
              statusLabel = chrome.i18n.getMessage('statusIngame');
            } else {
              if (friendsOnlineCount > 0) {
                count = friendsOnlineCount.toString();
                status = 'online';
                statusLabel = chrome.i18n.getMessage('statusOnline');
              } else {
                count = friendsCount.toString();
                status = 'offline';
                statusLabel = chrome.i18n.getMessage('statusOffline');
              }
            }
            // desktop notification
            // @todo move code
            if (Settings.storage.get('notifFriendsIsActivated')) {
              if (Settings.storage.get('countIngame') !== null) {
                var friendsIngameCountPrev = Settings.storage.get('countIngame');
                if (friendsIngameCount > friendsIngameCountPrev) {
                  renderFriendsNotification(friendsIngameCount.toString(), chrome.i18n.getMessage('statusIngame'));
                }
              }
              if (friendsIngameCount > 0) {
                Settings.storage.set('countIngame', friendsIngameCount);
              }
              if (Settings.storage.get('countOnline') !== null) {
                var friendsOnlineCountPrev = Settings.storage.get('countOnline');
                if (friendsOnlineCount > friendsOnlineCountPrev) {
                  renderFriendsNotification((friendsOnlineCount - friendsIngameCount).toString(), chrome.i18n.getMessage('statusOnline'));
                }
              }
              if (friendsOnlineCount > 0) {
                Settings.storage.set('countOnline', friendsOnlineCount);
              }
            }
            //
          // EA Origin not available
          } else {
            count = '0';
            status = 'offline';
            statusLabel = chrome.i18n.getMessage('statusOffline');
          }
          callback(count, status, statusLabel);
        } else {
          callback(false);
        }
      } catch (e) {
        console.error("Parsing error:", e);
        callback(false);
        return;
      }
    });
  };

  // Notifications count function
  window.NotificationsCount = function (callback) {
    xhr('GET', getNotificationsUrlJson(Settings.storage.get('game')), function (data) {
      var count = '0';

      if (data === false) {
        callback(false);
      }

      var json = JSON.parse(data);
      if (json.type == 'success') {
        count = json.data.numUnread.toString();
        callback(count);
      } else {
        callback(false);
      }
    });
  };

  // update badge
  function updateBadge() {
    var color, badgeText = true;
    new FriendsCount(function (count, status, statusLabel) {
      if (count !== false) {
        switch(status) {
          case 'ingame':
            color = colorIngame;
            if (!Settings.storage.get('iconShowIngame')) {
              count = '0';
              badgeText = false;
            }
            break;
          case 'online':
            color = colorOnline;
            if (!Settings.storage.get('iconShowOnline')) {
              count = '0';
              badgeText = false;
            }
            break;
          case 'offline':
            color = colorOffline;
            if (!Settings.storage.get('iconShowOffline')) {
              count = '0';
              badgeText = false;
            }
            break;
        }
        if (badgeText) {
          renderBadge((count !== '0' ? count : ''), color, chrome.i18n.getMessage('browserActionDefaultTitle', [count, statusLabel]));
        } else {
          renderBadge('', color, '');
        }
      } else {
        renderBadge('?', [190, 190, 190, 230], chrome.i18n.getMessage('browserActionErrorTitle'));
      }
    });
  }

  function showNotificationUpdates() {
    var sound = false;
    if (!chrome.notifications || !Settings.storage.get('notifUpdatesIsActivated')) {
      return;
    }
    if (Settings.storage.get('notifUpdatesIsSound')) {
      sound = true;
    }
    new NotificationsCount(function (count) {
      if (count !== false && count > 0) {
        renderUpdatesNotification(count, sound);
      }
    });
  }

  /**
   * Helpers
   */

  // XHR helper function
  var xhr = function () {
    var xhr = new XMLHttpRequest();
    return function(method, url, callback) {
      xhr.onreadystatechange = function () {
        // request finished and response is ready
        if (xhr.readyState === 4) {
          if (xhr.status !== 200) {
            callback(false);
          }
          callback(xhr.responseText);
        }
      };
      xhr.open(method, url);
      xhr.send();
    };
  }();

  function getHomeUrl(game) {
    return BASE_URL + game + '/';
  }
  function getUpdateUrl(game) {
    return BASE_URL + game + '/' + UPDATES_PATH;
  }
  function getFriendsUrlJson(game) {
    return BASE_URL + game + '/' + COMCENTER_PATH;
  }
  function getNotificationsUrlJson(game) {
    return BASE_URL + game + '/' + NOTIFICATIONS_PATH;
  }

  // badge renderer
  function renderBadge(badge, color, title) {
    chrome.browserAction.setBadgeText({
      text: badge
    });
    chrome.browserAction.setBadgeBackgroundColor({
      color: color
    });
    chrome.browserAction.setTitle({
      title: title
    });
  }

  // updates notitifcation renderer
  function renderUpdatesNotification(count, sound) {
    var opt = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationUpdatesTitle'),
      message: chrome.i18n.getMessage('notificationUpdatesMessage', [count]),
      iconUrl: "icon-48.png",
      buttons: [
        { title: chrome.i18n.getMessage('notificationButton2Title') },
      ]
    };
    var optOpera = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationUpdatesTitle'),
      message: chrome.i18n.getMessage('notificationUpdatesMessage', [count]),
      iconUrl: "icon-48.png"
    };
    var notification = chrome.notifications.create('showNotificationUpdates', opt, function() {
      if (sound) {
        playSound();
      }
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        if (chrome.runtime.lastError.message == "Adding buttons to notifications is not supported.") {
          var notification = chrome.notifications.create('showNotificationUpdates', optOpera, function() {});
        }
        return;
      }
    });
  }

  // friends notitifcation renderer
  function renderFriendsNotification(count, status) {
    var opt = {
      type: "basic",
      title: chrome.i18n.getMessage('notificationFriendsTitle'),
      message: chrome.i18n.getMessage('notificationFriendsMessage', [count, status]),
      iconUrl: "icon-48.png"
    };
    var notification = chrome.notifications.create('friendsNotification' + status, opt, function(id) {
      setTimeout(function() {
        chrome.notifications.clear(id);
      }, 4000);
    });
  }

  function playSound() {
    var notifAudio = new Audio();
    notifAudio.src = soundBleep;
    notifAudio.play();
  }

  function isBattlelogUrl(url) {
    return url.indexOf(getHomeUrl(Settings.storage.get('game'))) === 0;
  }

  function isBattlelogUpdatesUrl(url) {
    return url.indexOf(getUpdateUrl(Settings.storage.get('game'))) === 0;
  }

  function openBattlelogHomeInTab(flag) {
    // check if Battle is already open
    chrome.tabs.getAllInWindow(undefined, function(tabs) {
      for (var i = 0, tab; tab = tabs[i]; i++) {
        if (tab.url && isBattlelogUrl(tab.url)) {
          chrome.tabs.update(tab.id, {selected: true}, function(tab) {
            if (flag) {
              clickOnFlag();
            }
          });
          return;
        }
      }
      chrome.tabs.create({url: getHomeUrl(Settings.storage.get('game'))}, function(tab) {
        if (flag) {
          clickOnFlag();
        }
      });
    });
  }

  function openBattlelogUpdatesInTab() {
    // check if Battlelog is already open
    chrome.tabs.getAllInWindow(undefined, function(tabs) {
      for (var i = 0, tab; tab = tabs[i]; i++) {
        if (tab.url && isBattlelogUpdatesUrl(tab.url)) {
          chrome.tabs.update(tab.id, {selected: true});
          return;
        }
      }
      chrome.tabs.create({url: getUpdateUrl(Settings.storage.get('game'))});
    });
  }

  function clickOnFlag() {
    chrome.tabs.executeScript({
      file: 'vendor/zepto.min.js',
      runAt: 'document_end'
    }, function() {
      chrome.tabs.executeScript({
        code: "$('#updates-icon').click();",
        runAt: 'document_end'
      });
    });
  }

  /**
   * Events
   */

  // alarms
  chrome.alarms.create('badge', {periodInMinutes: 1});
  if (Settings.storage.get('notifUpdatesIsActivated') && Settings.storage.get('notifUpdatesFrequency')) {
    chrome.alarms.create('notification', {periodInMinutes: parseInt(Settings.storage.get('notifUpdatesFrequency'))});
  }
  chrome.alarms.onAlarm.addListener(function (alarm) {
    if (alarm.name == 'badge') {
      chrome.runtime.sendMessage({do: 'update_badge'});
    }
    if (alarm.name == 'notification') {
      showNotificationUpdates();
    }
  });

  // browser action
  chrome.browserAction.onClicked.addListener(function () {
    chrome.runtime.sendMessage({do: 'update_badge'});
    chrome.runtime.sendMessage({do: 'show_updates_notification'});
    openBattlelogHomeInTab();
  });

  if (chrome.notifications) {
    // notification action
    chrome.notifications.onClicked.addListener(function (notificationId) {
      if (notificationId == 'showNotificationUpdates') {
        chrome.notifications.clear(notificationId);
        openBattlelogHomeInTab(true);
      }
    });
    // notification button(s) action
    chrome.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
      if (notificationId == 'showNotificationUpdates') {
        switch (buttonIndex) {
          case 0:
            chrome.notifications.clear(notificationId);
            openBattlelogUpdatesInTab();
            break;
        }
      }
    });
  }

  // check if new version is available
  chrome.runtime.onUpdateAvailable.addListener(function (details) {
    var manifest = chrome.runtime.getManifest();
    console.log(manifest.name + " updating to v" + details.version);
    chrome.runtime.reload();
  });
  // check whether new version is installed
  chrome.runtime.onInstalled.addListener(function (details) {
    var manifest = chrome.runtime.getManifest();
    switch (details.reason) {
      case 'install':
        console.log(manifest.name + " first install (v" + manifest.version + ")");
        chrome.tabs.create({url: chrome.extension.getURL('options.html')});
      case 'update':
        console.log(manifest.name + " updated from v" + details.previousVersion + " to v" + manifest.version);
      default:
        chrome.runtime.sendMessage({do: 'update_badge'});
    }
  });

  // on message update badge
  chrome.runtime.onMessage.addListener(function (message, sender, response) {
    switch (message.do) {
      case 'update_badge':
        updateBadge();
        break;
      case 'show_updates_notification':
        showNotificationUpdates();
        break;
      case 'show_updates_notification_test':
        var sound = false;
        if (!chrome.notifications) {
          return;
        }
        if (Settings.storage.get('notifUpdatesIsSound')) {
          sound = true;
        }
        console.log('sound? ' + sound);
        renderUpdatesNotification(Math.floor((Math.random()*10)+1), sound);
        break;
      case 'show_friends_notification_test':
        if (!chrome.notifications) {
          return;
        }
        var statusArray = [
          chrome.i18n.getMessage('statusIngame'),
          chrome.i18n.getMessage('statusOnline')
        ];
        renderFriendsNotification(Math.floor((Math.random()*10)+1), statusArray[Math.floor(Math.random()*statusArray.length)]);
        break;
    }
  });
})();<|endoftext|>


<commit_before>import { window, document } from 'ssr-window';

const Support = (function Support() {
  const testDiv = document.createElement('div');
  return {
    touch: (window.Modernizr && window.Modernizr.touch === true) || (function checkTouch() {
      return !!((window.navigator.maxTouchPoints > 0) || ('ontouchstart' in window) || (window.DocumentTouch && document instanceof window.DocumentTouch));
    }()),

    pointerEvents: !!(window.navigator.pointerEnabled || window.PointerEvent || ('maxTouchPoints' in window.navigator)),
    prefixedPointerEvents: !!window.navigator.msPointerEnabled,

    transition: (function checkTransition() {
      const style = testDiv.style;
      return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style);
    }()),
    transforms3d: (window.Modernizr && window.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {
      const style = testDiv.style;
      return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style);
    }()),

    flexbox: (function checkFlexbox() {
      const style = testDiv.style;
      const styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
      for (let i = 0; i < styles.length; i += 1) {
        if (styles[i] in style) return true;
      }
      return false;
    }()),

    observer: (function checkObserver() {
      return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
    }()),

    passiveListener: (function checkPassiveListener() {
      let supportsPassive = false;
      try {
        const opts = Object.defineProperty({}, 'passive', {
          // eslint-disable-next-line
          get() {
            supportsPassive = true;
          },
        });
        window.addEventListener('testPassiveListener', null, opts);
      } catch (e) {
        // No support
      }
      return supportsPassive;
    }()),

    gestures: (function checkGestures() {
      return 'ongesturestart' in window;
    }()),
  };
}());

export default Support;
<commit_msg>fix: support pointerEvents<commit_after>import { window, document } from 'ssr-window';

const Support = (function Support() {
  const testDiv = document.createElement('div');
  return {
    touch: (window.Modernizr && window.Modernizr.touch === true) || (function checkTouch() {
      return !!((window.navigator.maxTouchPoints > 0) || ('ontouchstart' in window) || (window.DocumentTouch && document instanceof window.DocumentTouch));
    }()),

    pointerEvents: !!(window.navigator.pointerEnabled || window.PointerEvent || ('maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints > 0)),
    prefixedPointerEvents: !!window.navigator.msPointerEnabled,

    transition: (function checkTransition() {
      const style = testDiv.style;
      return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style);
    }()),
    transforms3d: (window.Modernizr && window.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {
      const style = testDiv.style;
      return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style);
    }()),

    flexbox: (function checkFlexbox() {
      const style = testDiv.style;
      const styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
      for (let i = 0; i < styles.length; i += 1) {
        if (styles[i] in style) return true;
      }
      return false;
    }()),

    observer: (function checkObserver() {
      return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
    }()),

    passiveListener: (function checkPassiveListener() {
      let supportsPassive = false;
      try {
        const opts = Object.defineProperty({}, 'passive', {
          // eslint-disable-next-line
          get() {
            supportsPassive = true;
          },
        });
        window.addEventListener('testPassiveListener', null, opts);
      } catch (e) {
        // No support
      }
      return supportsPassive;
    }()),

    gestures: (function checkGestures() {
      return 'ongesturestart' in window;
    }()),
  };
}());

export default Support;
<|endoftext|>