<commit_before>module.exports = function(config) {
  var testWebpackConfig = require('./webpack.test.js');

  // Example set of browsers to run on Sauce Labs
  // Check out https://saucelabs.com/platforms for all browser/platform combos
  var customLaunchers = {
    sl_chrome: {
      base: 'SauceLabs',
      browserName: 'chrome',
      platform: 'Windows 7',
      version: '35'
    },
    sl_firefox: {
      base: 'SauceLabs',
      browserName: 'firefox',
      version: '30'
    },
    sl_ios_safari: {
      base: 'SauceLabs',
      browserName: 'iphone',
      platform: 'OS X 10.9',
      version: '7.1'
    },
    sl_ie_11: {
      base: 'SauceLabs',
      browserName: 'internet explorer',
      platform: 'Windows 8.1',
      version: '11'
    }
  }

  var cfg = {

    // base path that will be used to resolve all patterns (e.g. files, exclude)
    basePath: '',

    /*
     * Frameworks to use
     *
     * available frameworks: https://npmjs.org/browse/keyword/karma-adapter
     */
    frameworks: ['jasmine'],

    // list of files to exclude
    exclude: [ ],

    /*
     * list of files / patterns to load in the browser
     *
     * we are building the test environment in ./spec-bundle.js
     */
    files: [ { pattern: './config/spec-bundle.js', watched: false } ],

    /*
     * preprocess matching files before serving them to the browser
     * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
     */
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },

    // Webpack Config at ./webpack.test.js
    webpack: testWebpackConfig,

    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },

    // Webpack please don't spam the console when running in karma!
    webpackServer: { noInfo: true },

    /*
     * test results reporter to use
     *
     * possible values: 'dots', 'progress'
     * available reporters: https://npmjs.org/browse/keyword/karma-reporter
     */
    reporters: [ 'mocha', 'coverage' ],

    // web server port
    port: 9876,

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

    /*
     * level of logging
     * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
     */
    logLevel: config.LOG_INFO,

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

    /*
     * start these browsers
     * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
     */
    browsers: process.env.SAUCE_USERNAME [
      'Chrome'
    ],

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

  if (process.env.SAUCE_USERNAME) {
    cfg.browsers = Object.keys(customLaunchers);
    cfg.sauceLabs = {
        testName: 'Docker Swarm Wheelhouse Web App Unit Tests'
    };
    cfg.customLaunchers = customLaunchers;
    cfg.reporters = ['dots', 'saucelabs'];
  }

  config.set(cfg);
};
<commit_msg>sauce up the travis tests<commit_after>module.exports = function(config) {
  var testWebpackConfig = require('./webpack.test.js');

  // Example set of browsers to run on Sauce Labs
  // Check out https://saucelabs.com/platforms for all browser/platform combos
  var customLaunchers = {
    sl_chrome: {
      base: 'SauceLabs',
      browserName: 'chrome',
      platform: 'Windows 7',
      version: '35'
    },
    sl_firefox: {
      base: 'SauceLabs',
      browserName: 'firefox',
      version: '30'
    },
    sl_ios_safari: {
      base: 'SauceLabs',
      browserName: 'iphone',
      platform: 'OS X 10.9',
      version: '7.1'
    },
    sl_ie_11: {
      base: 'SauceLabs',
      browserName: 'internet explorer',
      platform: 'Windows 8.1',
      version: '11'
    }
  }

  var cfg = {

    // base path that will be used to resolve all patterns (e.g. files, exclude)
    basePath: '',

    /*
     * Frameworks to use
     *
     * available frameworks: https://npmjs.org/browse/keyword/karma-adapter
     */
    frameworks: ['jasmine'],

    // list of files to exclude
    exclude: [ ],

    /*
     * list of files / patterns to load in the browser
     *
     * we are building the test environment in ./spec-bundle.js
     */
    files: [ { pattern: './config/spec-bundle.js', watched: false } ],

    /*
     * preprocess matching files before serving them to the browser
     * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
     */
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },

    // Webpack Config at ./webpack.test.js
    webpack: testWebpackConfig,

    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },

    // Webpack please don't spam the console when running in karma!
    webpackServer: { noInfo: true },

    /*
     * test results reporter to use
     *
     * possible values: 'dots', 'progress'
     * available reporters: https://npmjs.org/browse/keyword/karma-reporter
     */
    reporters: [ 'mocha', 'coverage' ],

    // web server port
    port: 9876,

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

    /*
     * level of logging
     * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
     */
    logLevel: config.LOG_INFO,

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

    /*
     * start these browsers
     * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
     */
    browsers: [
      'Chrome'
    ],

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

  if (process.env.SAUCE_USERNAME) {
    cfg.browsers = Object.keys(customLaunchers);
    cfg.sauceLabs = {
        testName: 'Docker Swarm Wheelhouse Web App Unit Tests',
        tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        startConnect: false
    };
    cfg.customLaunchers = customLaunchers;
    cfg.reporters = ['dots', 'saucelabs'];
  }

  config.set(cfg);
};
<|endoftext|>


<commit_before>/**
 * Selectron assists in counting selection caret's offset in relation to
 * different DOM elements, and saving and restoring selection ranges. Saving
 * and restoring of selection/ranges will work across heavy DOM manipulation if used correctly.
 *
 * @module spytext/selectron
 */

/**
 * Position of a caret (start or end)
 *
 * @typedef {Object} Position
 * @property {Node} ref - Reference node to count `offset` from
 * @property {number} offset - Steps from start of `ref`
 */

/**
 * Positions of start and end caret
 *
 * @typedef {Object} Positions
 * @property {Position} start - Position of start caret
 * @property {Position} end - Position of end caret
 */

var blockTags = [ 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI' ];

/**
 * Tests whether `node` is a block element, ie if it is of nodeType 1
 * and its tagName is in `blockTags`.
 *
 * @param	{Node} node - The node to check if it is a block element
 * @return {boolean}
 */
function isBlock(node) {
	return node.nodeType === 1 && blockTags.indexOf(node.tagName) !== -1;
	//return node.nodeType === 1 && !getComputedStyle(node).display.match(/inline/);
}

/**
 * Uses a TreeWalker to traverse and count the offset from `root` to `ref`
 *
 * This is essentially the inverse of restore
 *
 * @static
 * @param	{Node} root - Element to count relative
 * @param	{Node} ref - Element to reach
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all steps
 * @return {number}	The total offset of the caret relative to element
 */
function count(root, ref, countAll) {
	var node,
		off = 0,
		tw,
		prev;

	if(root !== ref) {
		tw = document.createTreeWalker(root, NodeFilter.SHOW_ALL, null, false);

		while((node = tw.nextNode())) {
			var nodeType = node.nodeType;

			if(prev && (isBlock(node) || countAll && !(nodeType === 1 && prev === node.parentNode || prev === node.previousSibling)))
				off++;

			if(node === ref)
				break;

			if(node.nodeType === 3)
				off = off + node.textContent.length;

			prev = node;
		}
	}

	return off;
}

/**
 * Return the total offset for a caret (start or end) of a range relative to a
 * specific element
 *
 * @static
 * @param	{Element} element - Containing element to count offset relative to
 * @param	{string} [caret=start] - Parameter that determines whether we should fetch start or endContainer
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all elements
 * @return {number}	The total offset of the caret relative to `element`
 * @see count
 * @throws {TypeError} Throws an error if `element` is undefined
 */
function offset(element, caret, countAll) {
	if(!element) throw new TypeError('element needs to be defined');

	var rng = s().getRangeAt(0),
		ref = rng[(caret || 'start') + 'Container'],
		off = rng[(caret || 'start') + 'Offset'];

	return count(element, ref, countAll) + off;
}

/**
 * Uses `root` and `offset` to traverse the DOM to find the innermost element
 * where the caret should be placed.
 *
 * This is essentially the inverse of count
 *
 * @static
 * @param	{Element} root
 * @param	{number} offset
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all elements
 * @return {Position}
 */
function restore(root, offset, countAll) {
	var tw = document.createTreeWalker(root, NodeFilter.SHOW_ALL, null, false),
		prev,
		node;

	while(offset > 0 && (node = tw.nextNode())) {
		var nodetype = node.nodeType;

		if(prev && (isBlock(node) || countAll && !(nodeType === 1 && prev === node.parentNode || prev === node.previousSibling)))
			offset--;

		prev = node;

		if(node.nodeType === 3) {
			if(offset > node.textContent.length)
				offset = offset - node.textContent.length;
			else
				break;
		}
	}

	return {
		ref: prev || root,
		offset: offset
	};
}

var descendants = require('./descendants');

var s = window.getSelection;

module.exports = {
	restore: restore,

	count: count,

	offset: offset,

	/**
	 * Returns all elements contained by the current selection
	 *
	 * @param	{Element} element - Element to count relative
	 * @param	{Node[]|NodeList|string|number|function} [ufo] - Filters
	 * @param	{number} [levels] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @param	{boolean} [partlyContained] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @param	{boolean} [onlyDeepest] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @return {Node[]}	Array contained all contained nodes
	 */
	contained: function(element, ufo, levels, partlyContained, onlyDeepest) {
		var _selectron = this,
			nodes = [];

		if(ufo instanceof NodeList)
			// convert NodeList to Array
			ufo = _.toArray(ufo);

		// create array with all nodes to test if they are contained by the selection
		var check = _.isArray(ufo)? ufo : descendants(element, ufo, levels, onlyDeepest);

		// loop through all nodes to check
		check.forEach(function(node) {
			if(_selectron.contains(node, partlyContained))
				// node is contained by selection, add it to `nodes`
				nodes.push(node);
		});

		return nodes;
	},

	/**
	 * Tests whether `node` is contained by the current selection
	 *
	 * @param	{Node} node - Element to count relative
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 */
	contains: function(node, partlyContained) {
		// default, unoverridable behaviour of Selection.containsNode() for textNodes
		if(node.nodeType === 3) partlyContained = true;

		var sel = s();

		if(sel.containsNode) {
			// simply use Selection objects containsNode native function if it exists
			return sel.containsNode(node, partlyContained);
		} else {
			var rng = sel.getRangeAt(0),
				element = rng.commonAncestorContainer;

			if(element.nodeType !== 1) {
				element = element.parentNode;
			}

			if(element !== node && !$.contains(element, node))
				return false;

			var rangeStartOffset = offset(element, 'start', true),
				rangeEndOffset = offset(element, 'end', true),
				startOffset = count(element, node, true),
				endOffset = node.nodeType === 1 ? startOffset + count(node, null, true) + 2 : startOffset + node.textContent.length;

			return (startOffset >= rangeStartOffset && endOffset <= rangeEndOffset ||
					partlyContained && ((rangeStartOffset >= startOffset && rangeStartOffset <= endOffset) || (rangeEndOffset >= startOffset && rangeEndOffset <= endOffset)));

		}
	},

	/**
	 * Tests whether all `nodes` are contained by the current selection
	 *
	 * @param	{Node[]} nodes - nodes to test if they are contained
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 * @see contains
	 */
	containsEvery: function(nodes, partlyContained) {
		var that = this;

		return _.toArray(nodes).every(function(node) {
			return that.contains(node, partlyContained);
		});
	},

	/**
	 * Tests whether any of `nodes` are contained by the current selection
	 *
	 * @param	{Node[]} nodes - nodes to test if they are contained
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 * @see contains
	 */
	containsSome: function(nodes, partlyContained) {
		var that = this;

		return _.toArray(nodes).some(function(node) {
			return that.contains(node, partlyContained);
		});

	},

	normalize: function(element) {
		this.set(this.get(element));
	},

	/**
	 * Return the current selection's (first) range
	 *
	 * @return {Range}
	 */
	range: function() {
		// retrieve the current selection
		var sel = s();

		if(sel.rangeCount > 0)
			// selection has at least one range, return the first
			return sel.getRangeAt(0);
		else
			// selection has no range, return null
			return null;
	},

	/**
	 * Tests whether the caret is currently at the end of a block
	 *
	 * @return {boolean}
	 */
	isAtEnd: function() {
		var rng = this.range();

		var $block = $(rng.startContainer).closest(blockTags.join(','));
		var off = offset($block[0], 'start');

		return $block.text().length === 0 || off === count($block[0]) - count($block.children('UL,OL')[0]);
	},

	/**
	 * Get Positions of start and end caret of current selection
	 *
	 * @param {Element} [element=document.body] - The reference node (to count the offset from)
	 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all steps
	 * @return {Positions} ref element of both start and end Position will be `element`
	 */
	get: function(element, countAll) {
		element = element || document.body;

		return {
			start: {
				ref: element,
				offset: offset(element, 'start', countAll)
			},
			end: {
				ref: element,
				offset: offset(element, 'end', countAll)
			}
		};
	},

	/**
	 * Sets the current selection to contain `node`
	 *
	 * @param {Node} node - The node to select
	 */
	select: function(node) {
		var textNodes = node.nodeType === 3 ? [ node ] : descendants(node, 3);

		if(textNodes.length === 0) {
			this.set({ ref: node, offset: 0 });
		} else {
			var first = _.first(textNodes),
				last = _.last(textNodes);

			this.set({
				start: {
					ref: first,
					offset: 0
				},
				end: {
					ref: last,
					offset: last.textContent.length,
				}
			});
		}
	},

	/**
	 * Sets the selection to `position`
	 *
	 * @param {Position|Positions} position - If a Position, a collapsed range will be set with start and end caret set to `position`
	 */
	set: function(position) {
		if(position.ref) {
			position = {
				start: position
			};
		}

		position.start.offset = position.start.offset || 0;

		var start = position.start.offset === 0 ? position.start : restore(position.start.ref, position.start.offset);

		var end = position.end ? restore(position.end.ref, position.end.offset) : start,
			rng = document.createRange(),
			sel = s();

		rng.setStart(start.ref, start.offset);
		rng.setEnd(end.ref, end.offset);

		sel.removeAllRanges();
		sel.addRange(rng);
	}
};
<commit_msg>Count <BR> tags as a step.<commit_after>/**
 * Selectron assists in counting selection caret's offset in relation to
 * different DOM elements, and saving and restoring selection ranges. Saving
 * and restoring of selection/ranges will work across heavy DOM manipulation if used correctly.
 *
 * @module spytext/selectron
 */

/**
 * Position of a caret (start or end)
 *
 * @typedef {Object} Position
 * @property {Node} ref - Reference node to count `offset` from
 * @property {number} offset - Steps from start of `ref`
 */

/**
 * Positions of start and end caret
 *
 * @typedef {Object} Positions
 * @property {Position} start - Position of start caret
 * @property {Position} end - Position of end caret
 */

var blockTags = [ 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI' ];

/**
 * Tests whether `node` is a block element, ie if it is of nodeType 1
 * and its tagName is in `blockTags`.
 *
 * @param	{Node} node - The node to check if it is a block element
 * @return {boolean}
 */
function isBlock(node) {
	return node.nodeType === 1 && blockTags.indexOf(node.tagName) !== -1;
	//return node.nodeType === 1 && !getComputedStyle(node).display.match(/inline/);
}

/**
 * Uses a TreeWalker to traverse and count the offset from `root` to `ref`
 *
 * This is essentially the inverse of restore
 *
 * @static
 * @param	{Node} root - Element to count relative
 * @param	{Node} ref - Element to reach
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all steps
 * @return {number}	The total offset of the caret relative to element
 */
function count(root, ref, countAll) {
	var node,
		off = 0,
		tw,
		prev;

	if(root !== ref) {
		tw = document.createTreeWalker(root, NodeFilter.SHOW_ALL, null, false);

		while((node = tw.nextNode())) {
			var nodeType = node.nodeType;

			if(prev && (isBlock(node) || node.nodeName === 'BR' || countAll && !(nodeType === 1 && prev === node.parentNode || prev === node.previousSibling)))
				off++;

			if(node === ref)
				break;

			if(node.nodeType === 3)
				off = off + node.textContent.length;

			prev = node;
		}
	}

	return off;
}

/**
 * Return the total offset for a caret (start or end) of a range relative to a
 * specific element
 *
 * @static
 * @param	{Element} element - Containing element to count offset relative to
 * @param	{string} [caret=start] - Parameter that determines whether we should fetch start or endContainer
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all elements
 * @return {number}	The total offset of the caret relative to `element`
 * @see count
 * @throws {TypeError} Throws an error if `element` is undefined
 */
function offset(element, caret, countAll) {
	if(!element) throw new TypeError('element needs to be defined');

	var rng = s().getRangeAt(0),
		ref = rng[(caret || 'start') + 'Container'],
		off = rng[(caret || 'start') + 'Offset'];

	return count(element, ref, countAll) + off;
}

/**
 * Uses `root` and `offset` to traverse the DOM to find the innermost element
 * where the caret should be placed.
 *
 * This is essentially the inverse of count
 *
 * @static
 * @param	{Element} root
 * @param	{number} offset
 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all elements
 * @return {Position}
 */
function restore(root, offset, countAll) {
	var tw = document.createTreeWalker(root, NodeFilter.SHOW_ALL, null, false),
		prev,
		node;

	while(offset > 0 && (node = tw.nextNode())) {
		var nodetype = node.nodeType;

		if(prev && (isBlock(node) || node.nodeName === 'BR' || countAll && !(nodeType === 1 && prev === node.parentNode || prev === node.previousSibling)))
			offset--;

		prev = node;

		if(node.nodeType === 3) {
			if(offset > node.textContent.length)
				offset = offset - node.textContent.length;
			else
				break;
		}
	}

	return {
		ref: prev || root,
		offset: offset
	};
}

var descendants = require('./descendants');

var s = window.getSelection;

module.exports = {
	restore: restore,

	count: count,

	offset: offset,

	/**
	 * Returns all elements contained by the current selection
	 *
	 * @param	{Element} element - Element to count relative
	 * @param	{Node[]|NodeList|string|number|function} [ufo] - Filters
	 * @param	{number} [levels] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @param	{boolean} [partlyContained] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @param	{boolean} [onlyDeepest] - How many levels of descendants should be collected. If `levels` is not set, all levels will be traversed
	 * @return {Node[]}	Array contained all contained nodes
	 */
	contained: function(element, ufo, levels, partlyContained, onlyDeepest) {
		var _selectron = this,
			nodes = [];

		if(ufo instanceof NodeList)
			// convert NodeList to Array
			ufo = _.toArray(ufo);

		// create array with all nodes to test if they are contained by the selection
		var check = _.isArray(ufo)? ufo : descendants(element, ufo, levels, onlyDeepest);

		// loop through all nodes to check
		check.forEach(function(node) {
			if(_selectron.contains(node, partlyContained))
				// node is contained by selection, add it to `nodes`
				nodes.push(node);
		});

		return nodes;
	},

	/**
	 * Tests whether `node` is contained by the current selection
	 *
	 * @param	{Node} node - Element to count relative
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 */
	contains: function(node, partlyContained) {
		// default, unoverridable behaviour of Selection.containsNode() for textNodes
		if(node.nodeType === 3) partlyContained = true;

		var sel = s();

		if(sel.containsNode) {
			// simply use Selection objects containsNode native function if it exists
			return sel.containsNode(node, partlyContained);
		} else {
			var rng = sel.getRangeAt(0),
				element = rng.commonAncestorContainer;

			if(element.nodeType !== 1) {
				element = element.parentNode;
			}

			if(element !== node && !$.contains(element, node))
				return false;

			var rangeStartOffset = offset(element, 'start', true),
				rangeEndOffset = offset(element, 'end', true),
				startOffset = count(element, node, true),
				endOffset = node.nodeType === 1 ? startOffset + count(node, null, true) + 2 : startOffset + node.textContent.length;

			return (startOffset >= rangeStartOffset && endOffset <= rangeEndOffset ||
					partlyContained && ((rangeStartOffset >= startOffset && rangeStartOffset <= endOffset) || (rangeEndOffset >= startOffset && rangeEndOffset <= endOffset)));

		}
	},

	/**
	 * Tests whether all `nodes` are contained by the current selection
	 *
	 * @param	{Node[]} nodes - nodes to test if they are contained
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 * @see contains
	 */
	containsEvery: function(nodes, partlyContained) {
		var that = this;

		return _.toArray(nodes).every(function(node) {
			return that.contains(node, partlyContained);
		});
	},

	/**
	 * Tests whether any of `nodes` are contained by the current selection
	 *
	 * @param	{Node[]} nodes - nodes to test if they are contained
	 * @param	{boolean} [partlyContained] - Return nodes that are not completely contained by selection
	 * @return {boolean}
	 * @see contains
	 */
	containsSome: function(nodes, partlyContained) {
		var that = this;

		return _.toArray(nodes).some(function(node) {
			return that.contains(node, partlyContained);
		});

	},

	normalize: function(element) {
		this.set(this.get(element));
	},

	/**
	 * Return the current selection's (first) range
	 *
	 * @return {Range}
	 */
	range: function() {
		// retrieve the current selection
		var sel = s();

		if(sel.rangeCount > 0)
			// selection has at least one range, return the first
			return sel.getRangeAt(0);
		else
			// selection has no range, return null
			return null;
	},

	/**
	 * Tests whether the caret is currently at the end of a block
	 *
	 * @return {boolean}
	 */
	isAtEnd: function() {
		var rng = this.range();

		var $block = $(rng.startContainer).closest(blockTags.join(','));
		var off = offset($block[0], 'start');

		return $block.text().length === 0 || off === count($block[0]) - count($block.children('UL,OL')[0]);
	},

	/**
	 * Get Positions of start and end caret of current selection
	 *
	 * @param {Element} [element=document.body] - The reference node (to count the offset from)
	 * @param	{boolean} [countAll] - Boolean parameter to determine whether to count all steps
	 * @return {Positions} ref element of both start and end Position will be `element`
	 */
	get: function(element, countAll) {
		element = element || document.body;

		return {
			start: {
				ref: element,
				offset: offset(element, 'start', countAll)
			},
			end: {
				ref: element,
				offset: offset(element, 'end', countAll)
			}
		};
	},

	/**
	 * Sets the current selection to contain `node`
	 *
	 * @param {Node} node - The node to select
	 */
	select: function(node) {
		var textNodes = node.nodeType === 3 ? [ node ] : descendants(node, 3);

		if(textNodes.length === 0) {
			this.set({ ref: node, offset: 0 });
		} else {
			var first = _.first(textNodes),
				last = _.last(textNodes);

			this.set({
				start: {
					ref: first,
					offset: 0
				},
				end: {
					ref: last,
					offset: last.textContent.length,
				}
			});
		}
	},

	/**
	 * Sets the selection to `position`
	 *
	 * @param {Position|Positions} position - If a Position, a collapsed range will be set with start and end caret set to `position`
	 */
	set: function(position) {
		if(position.ref) {
			position = {
				start: position
			};
		}

		position.start.offset = position.start.offset || 0;

		var start = position.start.offset === 0 ? position.start : restore(position.start.ref, position.start.offset);

		var end = position.end ? restore(position.end.ref, position.end.offset) : start,
			rng = document.createRange(),
			sel = s();

		rng.setStart(start.ref, start.offset);
		rng.setEnd(end.ref, end.offset);

		sel.removeAllRanges();
		sel.addRange(rng);
	}
};
<|endoftext|>


<commit_before>// Karma configuration
module.exports = function(config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha', 'sinon-chai'],

        // list of files / patterns to load in the browser
        files: [
		    '../test/browser/**/*.js',
            '../test/shared/**/*.js'
        ],
        // list of files to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            '../test/shared/**/*.js': ['webpack'],
            '../test/browser/**/*.js': ['webpack'],
        },
        webpack: {
            devtool: 'source-map',
            module: {
                postLoaders: [{
                    test: /\.js$/,
                    exclude: /(test|node_modules|dist)\//,
                    loader: 'isparta-instrumenter-loader'
                }],
                loaders: [{
                    test: /\.js$/,
                    exclude: /(node_modules|bower_components)\//,
                    loader: 'babel-loader'
                }]
            }
        },

        webpackMiddleware: {
            noInfo: true
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['mocha', 'coverage'],

        coverageReporter: {
            reporters: [{
                type: 'html',
                dir: '../coverage'
            }, {
                type: 'text',
                dir: '../coverage'
            }, {
                type: 'lcov',
                dir: '../coverage'
            }]
        },

        browsers: ['Chrome'],
        // custom launchers
        customLaunchers: {
            Chrome_for_Travis_CI: {
                base: 'Chrome',
                flags: ['--no-sandbox']
            }
        },

        browserDisconnectTimeout: 10000,
        browserDisconnectTolerance: 2,
        // concurrency level how many browser should be started simultaneously
        concurrency: 4,
        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 100000,
        browserNoActivityTimeout: 30000,
        // enable / disable colors in the output (reporters and logs)
        colors: true,
        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,
        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: false,
        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true
    });
    if (process.env.TRAVIS) {

        // Use Chrome as default browser for Travis CI
        config.browsers = ['Chrome_for_Travis_CI'];
        // Used by Travis to push coveralls info corretly to example coveralls.io
        config.reporters = ['mocha', 'coverage', 'coveralls'];
        // Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
        config.browserNoActivityTimeout = 120000;
    }
};<commit_msg>improved coverage config settings<commit_after>// Karma configuration
module.exports = function(config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha', 'sinon-chai'],

        // list of files / patterns to load in the browser
        files: [
            '../test/browser/**/*.js',
            '../test/shared/**/*.js'
        ],
        // list of files to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            '../test/shared/**/*.js': ['webpack'],
            '../test/browser/**/*.js': ['webpack'],
        },
        webpack: {
            devtool: 'source-map',
            module: {
                postLoaders: [{
                    test: /\.js$/,
                    exclude: /(test|node_modules|dist)\//,
                    loader: 'isparta-instrumenter-loader'
                }],
                loaders: [{
                    test: /\.js$/,
                    exclude: /(node_modules|bower_components)\//,
                    loader: 'babel-loader'
                }]
            }
        },

        webpackMiddleware: {
            noInfo: true
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['mocha', 'coverage', 'coveralls'],

        coverageReporter: {
            type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
            dir: 'coverage/'
        },
        browsers: ['Chrome'],
        // custom launchers
        customLaunchers: {
            Chrome_for_Travis_CI: {
                base: 'Chrome',
                flags: ['--no-sandbox']
            }
        },

        browserDisconnectTimeout: 10000,
        browserDisconnectTolerance: 2,
        // concurrency level how many browser should be started simultaneously
        concurrency: 4,
        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 100000,
        browserNoActivityTimeout: 30000,
        // enable / disable colors in the output (reporters and logs)
        colors: true,
        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,
        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: false,
        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true
    });
    if (process.env.TRAVIS) {

        // Use Chrome as default browser for Travis CI
        config.browsers = ['Chrome_for_Travis_CI'];
        // Used by Travis to push coveralls info corretly to example coveralls.io
        config.reporters = ['mocha', 'coverage', 'coveralls'];
        // Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
        config.browserNoActivityTimeout = 120000;
    }
};<|endoftext|>


<commit_before>//	Mithril bindings.
//	Copyright (C) 2014 jsguy (Mikkel Bergmann)
//	MIT licensed
(function(context){
	context.m = context.m || {};

	//	Pub/Sub based extended properties
	context.m.p = function(value) {
		var self = this,
			subs = [],
			prevValue,
			delay = false,
			//  Send notifications to subscribers
			notify = function (value, prevValue) {
				var i;
				for (i = 0; i < subs.length; i += 1) {
					subs[i].func.apply(subs[i].context, [value, prevValue]);
				}
			},
			prop = function() {
				if (arguments.length) {
					value = arguments[0];
					if (prevValue !== value) {
						var tmpPrev = prevValue;
						prevValue = value;
						notify(value, tmpPrev);
					}
				}
				return value;
			};

		//	Allow push on arrays
		prop.push = function(val) {
			if(value.push && typeof value.length !== "undefined") {
				value.push(val);
			}
			prop(value);
		}

		//	Subscribe for when the value changes
		prop.subscribe = function (func, context) {
			subs.push({ func: func, context: context || self });
			return prop;
		};

		//	Allow property to not automatically render
		prop.delay = function(value) {
			delay = !!value;
			return prop;
		};

		//	Automatically update rendering when a value changes
		//	As mithril waits for a request animation frame, this should be ok.
		//	You can use .delay(true) to be able to manually handle updates
		prop.subscribe(function(val){
			if(!delay) {
				m.startComputation();
				m.endComputation();
			}
			return prop;
		});

		return prop;
	};

	//	Element function that applies out extended bindings
	context.m.e = function(element, attrs, children) {
		for (var name in attrs) {
			if (m.bindings[name]) {
				m.bindings[name].apply(attrs, [attrs[name]]);
				delete attrs[name];
			}
		}
		return m(element, attrs, children);
	};

	//	Add bindings method
	context.m.addBinding = function(name, func){
		context.m.bindings = context.m.bindings || {};
		context.m.bindings[name] = func;
	};

	//	Get the underlying value of a property
	context.m.unwrap = function(prop) {
		return (typeof prop == "function")? prop(): prop;
	};

	//	Bi-directional binding of value
	context.m.addBinding("value", function(prop) {
		if (typeof prop == "function") {
			this.value = prop();
			this.onchange = m.withAttr("value", prop);
		} else {
			this.value = prop;
		}
	});

	//	Bi-directional binding of checked property
	context.m.addBinding("checked", function(prop) {
		if (typeof prop == "function") {
			this.checked = prop();
			this.onchange = m.withAttr("checked", prop);
		} else {
			this.checked = prop;
		}
	});

	//	Add value bindings for various event types
	var events = ["Input", "Keyup", "Keypress"];
	for(var i = 0; i < events.length; i += 1) {
		var eve = events[i];
		(function(name, eve){
			//	Bi-directional binding of value
			context.m.addBinding(name, function(prop) {
				if (typeof prop == "function") {
					this.value = prop();
					this[eve] = m.withAttr("value", prop);
				} else {
					this.value = prop;
				}
			});
		}("value" + eve, "on" + eve.toLowerCase()));
	}

	//	Hide node
	context.m.addBinding("hide", function(prop){
		this.style = {
			display: context.m.unwrap(prop)? "none" : ""
		};
	});

	//	Toggle boolean value on click
	context.m.addBinding('toggle', function(prop){
		this.onclick = function(){
			var value = prop();
			prop(!value);
		}
	});

}(window));<commit_msg>Removable attributes are now definable<commit_after>//	Mithril bindings.
//	Copyright (C) 2014 jsguy (Mikkel Bergmann)
//	MIT licensed
(function(context){
	context.m = context.m || {};

	//	Pub/Sub based extended properties
	context.m.p = function(value) {
		var self = this,
			subs = [],
			prevValue,
			delay = false,
			//  Send notifications to subscribers
			notify = function (value, prevValue) {
				var i;
				for (i = 0; i < subs.length; i += 1) {
					subs[i].func.apply(subs[i].context, [value, prevValue]);
				}
			},
			prop = function() {
				if (arguments.length) {
					value = arguments[0];
					if (prevValue !== value) {
						var tmpPrev = prevValue;
						prevValue = value;
						notify(value, tmpPrev);
					}
				}
				return value;
			};

		//	Allow push on arrays
		prop.push = function(val) {
			if(value.push && typeof value.length !== "undefined") {
				value.push(val);
			}
			prop(value);
		}

		//	Subscribe for when the value changes
		prop.subscribe = function (func, context) {
			subs.push({ func: func, context: context || self });
			return prop;
		};

		//	Allow property to not automatically render
		prop.delay = function(value) {
			delay = !!value;
			return prop;
		};

		//	Automatically update rendering when a value changes
		//	As mithril waits for a request animation frame, this should be ok.
		//	You can use .delay(true) to be able to manually handle updates
		prop.subscribe(function(val){
			if(!delay) {
				m.startComputation();
				m.endComputation();
			}
			return prop;
		});

		return prop;
	};

	//	Element function that applies our extended bindings
	//	Note: certain attributes can be removed when applied
	context.m.e = function(element, attrs, children) {
		for (var name in attrs) {
			if (m.bindings[name]) {
				m.bindings[name].func.apply(attrs, [attrs[name]]);
				if(m.bindings[name].removeable) {
					delete attrs[name];
				}
			}
		}
		return m(element, attrs, children);
	};

	//	Add bindings method
	//	Non-standard attributes do not need to be rendered, eg: valueInput
	//	so they are set as removable
	context.m.addBinding = function(name, func, removeable){
		context.m.bindings = context.m.bindings || {};
		context.m.bindings[name] = { func: func, removeable: removeable };
	};

	//	Get the underlying value of a property
	context.m.unwrap = function(prop) {
		return (typeof prop == "function")? prop(): prop;
	};

	//	Bi-directional binding of value
	context.m.addBinding("value", function(prop) {
		if (typeof prop == "function") {
			this.value = prop();
			this.onchange = m.withAttr("value", prop);
		} else {
			this.value = prop;
		}
	});

	//	Bi-directional binding of checked property
	context.m.addBinding("checked", function(prop) {
		if (typeof prop == "function") {
			this.checked = prop();
			this.onchange = m.withAttr("checked", prop);
		} else {
			this.checked = prop;
		}
	});

	//	Add value bindings for various event types
	var events = ["Input", "Keyup", "Keypress"];
	for(var i = 0; i < events.length; i += 1) {
		var eve = events[i];
		(function(name, eve){
			//	Bi-directional binding of value
			context.m.addBinding(name, function(prop) {
				if (typeof prop == "function") {
					this.value = prop();
					this[eve] = m.withAttr("value", prop);
				} else {
					this.value = prop;
				}
			}, true);
		}("value" + eve, "on" + eve.toLowerCase()));
	}

	//	Hide node
	context.m.addBinding("hide", function(prop){
		this.style = {
			display: context.m.unwrap(prop)? "none" : ""
		};
	}, true);

	//	Toggle boolean value on click
	context.m.addBinding('toggle', function(prop){
		this.onclick = function(){
			var value = prop();
			prop(!value);
		}
	}, true);

}(window));<|endoftext|>


<commit_before>function html_ajax_load() {
    return '

';
}
function tableFixLayout() {
    var w = $('.sonata-ba-list table.table').addClass('table-hover').width() + 71;
    if (w > 110) {
        $('#container').css('min-width', w + 'px');
    }
}

function init_home_page() {
    $(function () {
        $('#clientList').tablesorter({
            cancelSelection:false
        });
        $('#clientList').columnFilters({
            wildCard:false,
            underline:true,
            alternateRowClassNames:['rowa', 'rowb']
        });

        var $btn = $('<button rel="tooltip" title="Oter filtre" style="margin-right:10px;" class="btn" id="emptyColumnFilters"></button>');
        $('.sonata-ba-list .table .filterColumns td:first').prepend($btn);
        $('#clientList .filterColumns td:first').prepend($btn);
        $btn.tooltip();

        $("#emptyColumnFilters").click(function(){
            $(this).parent().parent().find("._filterText").val("").keyup();
        });
    });
    $(function () {
        var $table = $('#clientList tbody:first');
        $table.find('tr').css('cursor', 'pointer').click(function () {
            var objectid = $(this).children(':last').attr('objectid');
            if (objectid) {
                location.href = editObjectAbstractUrl.replace("__id__", objectid);
            }
        });
    });
    $(function () {
        $('#show_hide_all_clients').click(function () {
            if ($.cookie('show_all_clients')) {
                $.removeCookie('show_all_clients', { path:'/' });
            }
            else {
                $.cookie('show_all_clients', $.cookie('PHPSESSID'), { path:'/' });
            }
            location.reload();
        });
    });
}

$(function () {
    $('input#username[name="_username"]').focus();
    if ($.cookie('show_all_clients') != $.cookie('PHPSESSID')){
        $.removeCookie('show_all_clients', { path:'/' });
    }
});

function add_label_required(field) {

    if (field.text().indexOf('*') < 0) {
        field.text(field.text() + '*');
    }
}

function rm_label_required(field) {
    field.text(field.text().replace('*', ''));
}

function formatDate(date, format){
    var val = {
        'd': date.getDate(),
        'm': date.getMonth() + 1,
        'yy': date.getFullYear().toString().substring(2),
        'yyyy': date.getFullYear()
    };
    val['dd'] = (val.d < 10 ? '0' : '') + val.d;
    val['mm'] = (val.m < 10 ? '0' : '') + val.m;

    var parts = ['yyyy', 'mm', 'dd', 'yy', 'm', 'd'];

    for (var p in parts){
        format = format.replace(parts[p], val[parts[p]]);
    }

    return format;
}<commit_msg>Feature #1042 :: Client Operations - Dynamic filters<commit_after>function html_ajax_load() {
    return '

';
}
function tableFixLayout() {
    var w = $('.sonata-ba-list table.table').addClass('table-hover').width() + 71;
    if (w > 110) {
        $('#container').css('min-width', w + 'px');
    }
}

function init_home_page() {
    $(function () {
        $('#clientList').tablesorter({
            cancelSelection:false
        });
        $('#clientList').columnFilters({
            wildCard:false,
            underline:true,
            alternateRowClassNames:['rowa', 'rowb']
        });

        var $btn = $('<button rel="tooltip" title="Oter filtre" style="margin-right:10px;" class="btn" id="emptyColumnFilters"></button>');
        $('#clientList .filterColumns td:first').prepend($btn);
        $btn.tooltip();

        $("#emptyColumnFilters").click(function(){
            $(this).parent().parent().find("._filterText").val("").keyup();
        });
    });
    $(function () {
        var $table = $('#clientList tbody:first');
        $table.find('tr').css('cursor', 'pointer').click(function () {
            var objectid = $(this).children(':last').attr('objectid');
            if (objectid) {
                location.href = editObjectAbstractUrl.replace("__id__", objectid);
            }
        });
    });
    $(function () {
        $('#show_hide_all_clients').click(function () {
            if ($.cookie('show_all_clients')) {
                $.removeCookie('show_all_clients', { path:'/' });
            }
            else {
                $.cookie('show_all_clients', $.cookie('PHPSESSID'), { path:'/' });
            }
            location.reload();
        });
    });
}

$(function () {
    $('input#username[name="_username"]').focus();
    if ($.cookie('show_all_clients') != $.cookie('PHPSESSID')){
        $.removeCookie('show_all_clients', { path:'/' });
    }
});

function add_label_required(field) {

    if (field.text().indexOf('*') < 0) {
        field.text(field.text() + '*');
    }
}

function rm_label_required(field) {
    field.text(field.text().replace('*', ''));
}

function formatDate(date, format){
    var val = {
        'd': date.getDate(),
        'm': date.getMonth() + 1,
        'yy': date.getFullYear().toString().substring(2),
        'yyyy': date.getFullYear()
    };
    val['dd'] = (val.d < 10 ? '0' : '') + val.d;
    val['mm'] = (val.m < 10 ? '0' : '') + val.m;

    var parts = ['yyyy', 'mm', 'dd', 'yy', 'm', 'd'];

    for (var p in parts){
        format = format.replace(parts[p], val[parts[p]]);
    }

    return format;
}<|endoftext|>


<commit_before>/*
 *
 * mads - version 2
 * Copyright (c) 2015, Ninjoe
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * https://en.wikipedia.org/wiki/MIT_License
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
 *
 */
var mads = function() {
    /* Get Tracker */
    if (typeof custTracker == 'undefined' && typeof rma != 'undefined') {
        this.custTracker = rma.customize.custTracker;
    } else if (typeof custTracker != 'undefined') {
        this.custTracker = custTracker;
    } else {
        this.custTracker = [];
    }

    /* Unique ID on each initialise */
    this.id = this.uniqId();

    /* Tracked tracker */
    this.tracked = [];

    /* Body Tag */
    this.bodyTag = document.getElementsByTagName('body')[0];

    /* Head Tag */
    this.headTag = document.getElementsByTagName('head')[0];

    /* RMA Widget - Content Area */
    this.contentTag = document.getElementById('rma-widget');

    /* URL Path */
    this.path = typeof rma != 'undefined' ? rma.customize.src : '';
};

/* Generate unique ID */
mads.prototype.uniqId = function() {
    return new Date().getTime();
}

/* Link Opner */
mads.prototype.linkOpener = function(url) {

    if (typeof url != "undefined" && url != "") {
        if (typeof mraid !== 'undefined') {
            mraid.open(url);
        } else {
            window.open(url);
        }
    }
}

/* tracker */
mads.prototype.tracker = function(type, name) { console.log(type);

    /*
     * name is used to make sure that particular tracker is tracked for only once
     * there might have the same type in different location, so it will need the name to differentiate them
     */
    name = name || type;

    if (typeof this.custTracker != 'undefined' && this.custTracker != '' && this.tracked.indexOf(name) == -1) {
        for (var i = 0; i < this.custTracker.length; i++) {
            var img = document.createElement('img');
            img.src = this.custTracker[i] + type + '&' + this.id;
            img.style.display = 'none';
            this.bodyTag.appendChild(img);

            this.tracked.push(name);
        }
    }
};

/* Load JS File */
mads.prototype.loadJs = function(js, callback) {
    var script = document.createElement('script');
    script.src = js;

    if (typeof callback != 'undefined') {
        script.onload = callback;
    }

    this.headTag.appendChild(script);
}

/* Load CSS File */
mads.prototype.loadCss = function(href) {
    var link = document.createElement('link');
    link.href = href;
    link.setAttribute('type', 'text/css');
    link.setAttribute('rel', 'stylesheet');

    this.headTag.appendChild(link);
}

/*
 *
 * Unit Testing for mads
 *
 */
var testunit = function() {
    var app = new mads();

    app.loadCss(app.path + 'css/style.css');

    var contentHtml = function() {
        app.contentTag.innerHTML = '

 \

 \

 \

 \
             \

 \

 \
        \
         \

 \

 \
             \
             \

 \

 \
             \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \
           \
           \

 \

 \
             \

 \

 \
             \

 \

 \

 \

 \
         \
             \
         \

 '
        ;
    };
    var animation = function() {
        var wipeLoad = function() {
            var animationWithCont = function() {
                var tl = TweenMax;
                tl.to(".finger", 0.5, {
                    delay: 0.3,
                    left: "30%"
                });
                tl.to(".finger", 0.5, {
                    delay: 0.7,
                    left: "70%"
                });
                tl.to(".finger", 0.5, {
                    delay: 1.2,
                    left: "30%"
                });
                tl.to(".finger", 0.5, {
                    delay: 1.7,
                    left: "70%"
                });
                tl.to(".finger", 0.5, {
                    delay: 2.2,
                    left: "50%"
                });
                var w = function opac() {
                    tl.to(".textOnPunctir", 0.5, {
                        delay: 0,
                        opacity: "0"
                    });
                    app.tracker('wipe');
                };
                var q = function explosion() {

                    tl.to(".secondBg", 0.5, {
                        delay: 0.3,
                        opacity: "1"
                    });
                    tl.to(".punctir2", 0.5, {
                        delay: 0.3,
                        background: "none"
                    });
                    tl.to(".hashtag", 0.4, {
                        delay: 0.3,
                        opacity: "1"
                    });
                    tl.to(".confeti", 0.4, {
                        delay: 0.7,
                        opacity: "1"
                    });
                    /*bubble*/
                    tl.to(".bubble", 1.8, {
                        delay: 1.9,
                        opacity: "1"
                    });
                    tl.to(".b1", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        y: "-150px",
                        x: "78px",
                        width: "53px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b2", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        zIndex: "3",
                        x: "-14px",
                        y: "-135px",
                        width: "47px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b3", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-45px",
                        y: "-210px",
                        width: "42px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b4", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-220px",
                        width: "22px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b5", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-15px",
                        y: "-120px",
                        width: "41px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b6", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-255px",
                        width: "26px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b7", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-75px",
                        width: "26px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b8", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-20px",
                        y: "-200px",
                        width: "52px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b9", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-80px",
                        y: "-140px",
                        width: "34px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b10", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "35px",
                        y: "-160px",
                        width: "27px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b11", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "25px",
                        y: "-195px",
                        width: "23px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b12", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-10px",
                        y: "-250px",
                        width: "19px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b13", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "14px",
                        y: "-230px",
                        width: "13px",
                        ease: Power0.easeNone
                    });
                    tl.to(".confeti2", 3.9, {
                        delay: 0.7,
                        opacity: "1"
                    });
                    tl.to(".button", 3.5, {
                        delay: 1.5,
                        opacity: "1"
                    });
                    // tl.to(".findBtn", 0.5, {delay:1.5, width:"144px", marginTop:"-4px", marginLeft:"-73px",  height:"47px"});
                    tl.to(".findBtn", 0.3, {
                        delay: 2.0,
                        width: "134px",
                        marginTop: "0px",
                        marginLeft: "5px",
                        height: "37px"
                    });
                    tl.to(".logo", 1, {
                        delay: 0.5,
                        top: "20px",
                        width: "100px",
                        marginLeft: "-50px"
                    });
                    tl.to(".newMagnum, .belgianChocolate", 1.3, {
                        delay: 1.7,
                        opacity: "1"
                    });

                    function clickVes() {
                        /* @NOTE disable click ad to landing page */
                        /*
                        $("#rma-widget").attr("class", "sssq");
                        $(".sssq").css("cursor", "pointer")
                        $(".sssq").click(function() {
                            app.linkOpener('https://www.facebook.com/MagnumMalaysia');
                            app.tracker("site")
                        })
                        */
                        /* @NOTE find btn */
                        $('.findBtn').on('click', function (e) {
                            app.linkOpener('https://www.facebook.com/MagnumMalaysia');
                            app.tracker("site")
                        });

                        /* @NOTE store btn */
                        $('.storeBtn').on('click', function (e) {qqqq();
                            $(".popUpMap").css("display","block");
                            $(".overlayMap").css("display","block");
                            $('.popUpMap').addClass('cur');
                        });

                        $(".cancelModal, .overlayMap").click(function() {
                            $(".popUpMap").css("display","none");
                            $(".overlayMap").css("display","none");
                        });
                    }
                    setTimeout(clickVes, 2000);
                }
                $(".punctir2").click(function() {
                    w();
                })
                $(".punctir2").on("touchstart", function() {
                    w();
                })
                $(".punctir2").mousedown(function() {
                    w();
                })

                $("#redux").eraser({
                    completeRatio: .8,
                    completeFunction: function() {
                        $("#redux").css("opacity", "0");
                        w();
                        q();
                    }
                });

            }; /*-----*/
            contentHtml();
            app.loadJs(app.path + 'js/gmap.js');
            app.loadJs(app.path + 'js/wipe.js', animationWithCont);
        };
        app.loadJs(app.path + 'js/tweenmax.js', wipeLoad)
    };

    app.loadJs(app.path + 'js/jquery.js', animation);
    app.loadJs('https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=geometry&async=2&callback=MapApiLoaded');

}

function MapApiLoaded() {

}

testunit();<commit_msg>store tracker<commit_after>/*
 *
 * mads - version 2
 * Copyright (c) 2015, Ninjoe
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * https://en.wikipedia.org/wiki/MIT_License
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
 *
 */
var mads = function() {
    /* Get Tracker */
    if (typeof custTracker == 'undefined' && typeof rma != 'undefined') {
        this.custTracker = rma.customize.custTracker;
    } else if (typeof custTracker != 'undefined') {
        this.custTracker = custTracker;
    } else {
        this.custTracker = [];
    }

    /* Unique ID on each initialise */
    this.id = this.uniqId();

    /* Tracked tracker */
    this.tracked = [];

    /* Body Tag */
    this.bodyTag = document.getElementsByTagName('body')[0];

    /* Head Tag */
    this.headTag = document.getElementsByTagName('head')[0];

    /* RMA Widget - Content Area */
    this.contentTag = document.getElementById('rma-widget');

    /* URL Path */
    this.path = typeof rma != 'undefined' ? rma.customize.src : '';
};

/* Generate unique ID */
mads.prototype.uniqId = function() {
    return new Date().getTime();
}

/* Link Opner */
mads.prototype.linkOpener = function(url) {

    if (typeof url != "undefined" && url != "") {
        if (typeof mraid !== 'undefined') {
            mraid.open(url);
        } else {
            window.open(url);
        }
    }
}

/* tracker */
mads.prototype.tracker = function(type, name) { console.log(type);

    /*
     * name is used to make sure that particular tracker is tracked for only once
     * there might have the same type in different location, so it will need the name to differentiate them
     */
    name = name || type;

    if (typeof this.custTracker != 'undefined' && this.custTracker != '' && this.tracked.indexOf(name) == -1) {
        for (var i = 0; i < this.custTracker.length; i++) {
            var img = document.createElement('img');
            img.src = this.custTracker[i] + type + '&' + this.id;
            img.style.display = 'none';
            this.bodyTag.appendChild(img);

            this.tracked.push(name);
        }
    }
};

/* Load JS File */
mads.prototype.loadJs = function(js, callback) {
    var script = document.createElement('script');
    script.src = js;

    if (typeof callback != 'undefined') {
        script.onload = callback;
    }

    this.headTag.appendChild(script);
}

/* Load CSS File */
mads.prototype.loadCss = function(href) {
    var link = document.createElement('link');
    link.href = href;
    link.setAttribute('type', 'text/css');
    link.setAttribute('rel', 'stylesheet');

    this.headTag.appendChild(link);
}

/*
 *
 * Unit Testing for mads
 *
 */
var testunit = function() {
    var app = new mads();

    app.loadCss(app.path + 'css/style.css');

    var contentHtml = function() {
        app.contentTag.innerHTML = '

 \

 \

 \

 \
             \

 \

 \
        \
         \

 \

 \
             \
             \

 \

 \
             \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \

 \
           \
           \

 \

 \
             \

 \

 \
             \

 \

 \

 \

 \
         \
             \
         \

 '
        ;
    };
    var animation = function() {
        var wipeLoad = function() {
            var animationWithCont = function() {
                var tl = TweenMax;
                tl.to(".finger", 0.5, {
                    delay: 0.3,
                    left: "30%"
                });
                tl.to(".finger", 0.5, {
                    delay: 0.7,
                    left: "70%"
                });
                tl.to(".finger", 0.5, {
                    delay: 1.2,
                    left: "30%"
                });
                tl.to(".finger", 0.5, {
                    delay: 1.7,
                    left: "70%"
                });
                tl.to(".finger", 0.5, {
                    delay: 2.2,
                    left: "50%"
                });
                var w = function opac() {
                    tl.to(".textOnPunctir", 0.5, {
                        delay: 0,
                        opacity: "0"
                    });
                    app.tracker('wipe');
                };
                var q = function explosion() {

                    tl.to(".secondBg", 0.5, {
                        delay: 0.3,
                        opacity: "1"
                    });
                    tl.to(".punctir2", 0.5, {
                        delay: 0.3,
                        background: "none"
                    });
                    tl.to(".hashtag", 0.4, {
                        delay: 0.3,
                        opacity: "1"
                    });
                    tl.to(".confeti", 0.4, {
                        delay: 0.7,
                        opacity: "1"
                    });
                    /*bubble*/
                    tl.to(".bubble", 1.8, {
                        delay: 1.9,
                        opacity: "1"
                    });
                    tl.to(".b1", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        y: "-150px",
                        x: "78px",
                        width: "53px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b2", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        zIndex: "3",
                        x: "-14px",
                        y: "-135px",
                        width: "47px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b3", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-45px",
                        y: "-210px",
                        width: "42px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b4", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-220px",
                        width: "22px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b5", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-15px",
                        y: "-120px",
                        width: "41px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b6", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-255px",
                        width: "26px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b7", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-40px",
                        y: "-75px",
                        width: "26px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b8", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-20px",
                        y: "-200px",
                        width: "52px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b9", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-80px",
                        y: "-140px",
                        width: "34px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b10", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "35px",
                        y: "-160px",
                        width: "27px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b11", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "25px",
                        y: "-195px",
                        width: "23px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b12", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "-10px",
                        y: "-250px",
                        width: "19px",
                        ease: Power0.easeNone
                    });
                    tl.to(".b13", 7.0, {
                        delay: 0.5,
                        opacity: "1",
                        x: "14px",
                        y: "-230px",
                        width: "13px",
                        ease: Power0.easeNone
                    });
                    tl.to(".confeti2", 3.9, {
                        delay: 0.7,
                        opacity: "1"
                    });
                    tl.to(".button", 3.5, {
                        delay: 1.5,
                        opacity: "1"
                    });
                    // tl.to(".findBtn", 0.5, {delay:1.5, width:"144px", marginTop:"-4px", marginLeft:"-73px",  height:"47px"});
                    tl.to(".findBtn", 0.3, {
                        delay: 2.0,
                        width: "134px",
                        marginTop: "0px",
                        marginLeft: "5px",
                        height: "37px"
                    });
                    tl.to(".logo", 1, {
                        delay: 0.5,
                        top: "20px",
                        width: "100px",
                        marginLeft: "-50px"
                    });
                    tl.to(".newMagnum, .belgianChocolate", 1.3, {
                        delay: 1.7,
                        opacity: "1"
                    });

                    function clickVes() {
                        /* @NOTE disable click ad to landing page */
                        /*
                        $("#rma-widget").attr("class", "sssq");
                        $(".sssq").css("cursor", "pointer")
                        $(".sssq").click(function() {
                            app.linkOpener('https://www.facebook.com/MagnumMalaysia');
                            app.tracker("site")
                        })
                        */
                        /* @NOTE find btn */
                        $('.findBtn').on('click', function (e) {
                            app.linkOpener('https://www.facebook.com/MagnumMalaysia');
                            app.tracker("site")
                        });

                        /* @NOTE store btn */
                        $('.storeBtn').on('click', function (e) {
                            app.tracker('store');
                            qqqq();
                            $(".popUpMap").css("display","block");
                            $(".overlayMap").css("display","block");
                            $('.popUpMap').addClass('cur');
                        });

                        $(".cancelModal, .overlayMap").click(function() {
                            $(".popUpMap").css("display","none");
                            $(".overlayMap").css("display","none");
                        });
                    }
                    setTimeout(clickVes, 2000);
                }
                $(".punctir2").click(function() {
                    w();
                })
                $(".punctir2").on("touchstart", function() {
                    w();
                })
                $(".punctir2").mousedown(function() {
                    w();
                })

                $("#redux").eraser({
                    completeRatio: .8,
                    completeFunction: function() {
                        $("#redux").css("opacity", "0");
                        w();
                        q();
                    }
                });

            }; /*-----*/
            contentHtml();
            app.loadJs(app.path + 'js/gmap.js');
            app.loadJs(app.path + 'js/wipe.js', animationWithCont);
        };
        app.loadJs(app.path + 'js/tweenmax.js', wipeLoad)
    };

    app.loadJs(app.path + 'js/jquery.js', animation);
    app.loadJs('https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=geometry&async=2&callback=MapApiLoaded');

}

function MapApiLoaded() {

}

testunit();<|endoftext|>


<commit_before>$(function(){

	$('.ajax-task-complete').on({
		click: function(e) {
			e.preventDefault();
			var $href = $(this).attr('href');

			// console.log("$href: " + $href); // /1/edit-complete

			$('

').load($href+' form', function(){

				// set form
				var $form = $(this).children('form');

				// set checkbox
				var $cb = $form.find('input[type="checkbox"]');

				// toggle
				$cb.prop('checked', !$cb.prop('checked'));

				// form action url
				var $url = $form.attr('action');

				//console.log("url: " + $url); // /1/update-complete

				// set data
				var $data = $form.serialize();

				console.log("data: " + $data); // _method=PUT&dev_taskbundle_taskcomplete%5Bcomplete%5D=1&dev_taskbundle_taskcomplete%

				$.ajax({
					url: $url,
					data: $data,
					method: 'post',
					dataType: 'json',
					cache: false,
					success: function(obj) {
						console.log('success');

						var $tic = $('#task-complete-' + obj.id + ' .ajax-task-complete');

						if (obj.complete) {
							$tic.text('X');
						} else {
							$tic.text('O')
						}
					},
					complete: function(obj) {
						console.log('complete!');
					},
					error: function(err) {
						console.log(err);
					}
				});
			});
		}
	});

	// http://www.appelsiini.net/projects/jeditable
 	$('.taskedit').editable("/web/app_dev.php/task/inline-edit", {
 		indicator: '',
 		tooltip: "Haga clic para editar...",
 		submitdata: {
 			_method: "post",
 			id: $(this).attr('id'),
 			value: $(this).html()
 		}
 	});

 	$('.listedit').editable("/web/app_dev.php/list/inline-edit", {
 		submitdata: {
 			_method: "post",
 			id: $(this).attr('id'),
 			value: $(this).html()
 		},
 		indicator: '',
 		tooltip: 'Haz click aquí para editar',
 	});

 	$('.listcreate').editable("inline-create", {
 		submitdata: {
 			_method: "post",
 			value: $(this).html()
 		},
 		indicator: '',
 		tooltip: 'Haz click aquí para editar',
 	});

});<commit_msg>main.js<commit_after>$(function(){

	$('.ajax-task-complete').on({
		click: function(e) {
			e.preventDefault();
			var $href = $(this).attr('href');

			// console.log("$href: " + $href); // /1/edit-complete

			$('

').load($href+' form', function(){

				// set form
				var $form = $(this).children('form');

				// set checkbox
				var $cb = $form.find('input[type="checkbox"]');

				// toggle
				$cb.prop('checked', !$cb.prop('checked'));

				// form action url
				var $url = $form.attr('action');

				//console.log("url: " + $url); // /1/update-complete

				// set data
				var $data = $form.serialize();

				console.log("data: " + $data); // _method=PUT&dev_taskbundle_taskcomplete%5Bcomplete%5D=1&dev_taskbundle_taskcomplete%

				$.ajax({
					url: $url,
					data: $data,
					method: 'post',
					dataType: 'json',
					cache: false,
					success: function(obj) {
						console.log('success');

						var $tic = $('#task-complete-' + obj.id + ' .ajax-task-complete');

						if (obj.complete) {
							$tic.text('X');
						} else {
							$tic.text('O')
						}
					},
					complete: function(obj) {
						console.log('complete!');
					},
					error: function(err) {
						console.log(err);
					}
				});
			});
		}
	});

	// http://www.appelsiini.net/projects/jeditable
 	$('.listcreate').editable("inline-create", {
 		submitdata: {
 			_method: "post",
 			value: $(this).html()
 		},
 		indicator: '',
 		tooltip: 'Haz click aquí para editar',
 		callback: function() {
 			location.href = '';
 		}
 	});

 	$('.itemcreate').editable("item-create", {
 		submitdata: {
 			_method: "post",
 			value: $(this).html()
 		},
 		indicator: '',
 		tooltip: 'Haz click aquí para editar',
 		callback: function() {
 			location.href = '';
 		}
 	});

 	$('.taskedit').editable("inline-edit", {
 		indicator: '',
 		tooltip: "Haga clic para editar...",
 		submitdata: {
 			_method: "post",
 			id: $(this).attr('id'),
 			value: $(this).html()
 		}
 	});

 	$('.listedit').editable("inline-edit", {
 		submitdata: {
 			_method: "post",
 			id: $(this).attr('id'),
 			value: $(this).html()
 		},
 		indicator: '',
 		tooltip: 'Haz click aquí para editar',
 	});

});<|endoftext|>


<commit_before>const fs = require('fs');

const mysql_real_escape_string = (str) => {
    console.log(str);
    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function(char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\" + char; // prepends a backslash to backslash, percent,
                // and double/single quotes
        }
    });
};

module.exports = (x) => {
    let flat = [{
            "name": "ns_vid",
            "value": x.ns_vid || null,
            "type": "string"
        },
        {
            "name": "ns_utc",
            "value": x.ns_utc || null,
            "type": "number"
        },
        {
            "name": "date",
            "value": x.date || null,
            "type": "string"
        },
        // {
        //     "name": "agent",
        //     "value": x.agent || null,
        //     "type": "string"
        // },
        {
            "name": "ip",
            "value": x.ip || null,
            "type": "string"
        },
        {
            "name": "screen_resolution",
            "value": x.screen_resolution || null,
            "type": "string"
        },
        {
            "name": "ns_v_platform",
            "value": x.ns_v_platform || null,
            "type": "string"
        },
        {
            "name": "ns_jspageurl",
            "value": x.ns_jspageurl || null,
            "type": "string"
        },
        {
            "name": "referrer",
            "value": x.referrer || null,
            "type": "string"
        },
        {
            "name": "type",
            "value": x.type || null,
            "type": "string"
        },
        {
            "name": "bbc_name",
            "value": x.name || null,
            "type": "string"
        },
        {
            "name": "bbc_section",
            "value": x.section || null,
            "type": "string"
        },
        {
            "name": "bbc_page_type",
            "value": x.page_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_type",
            "value": x.app_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_name",
            "value": x.app_name || null,
            "type": "string"
        },
        {
            "name": "bbc_service_name",
            "value": x.bbc_site || null,
            "type": "string"
        },
        {
            "name": "bbc_referring_object",
            "value": x.referring_object || null,
            "type": "string"
        },
        {
            "name": "bbc_action_name",
            "value": x.action_name || null,
            "type": "string"
        },
        {
            "name": "bbc_action_type",
            "value": x.action_type || null,
            "type": "string"
        },
        {
            "name": "bbc_postid",
            "value": x.postID || null,
            "type": "string"
        },
        {
            "name": "bbc_ocid",
            "value": x.ocid || null,
            "type": "string"
        },
        {
            "name": "bbc_cps_asset_id",
            "value": x.cps_asset_id || null,
            "type": "string"
        },
        {
            "name": "bbc_app_name",
            "value": x.app && x.app.name || null,
            "type": "string"
        },
        {
            "name": "bbc_app_major",
            "value": x.app && x.app.major || null,
            "type": "number"
        },
        {
            "name": "bbc_app_minor",
            "value": x.app && x.app.minor || null,
            "type": "number"
        },
        {
            "name": "loc_range_lat",
            "value": x.loc && x.loc.ll[0] || null,
            "type": "number"
        },
        {
            "name": "loc_range_long",
            "value": x.loc && x.loc.ll[1] || null,
            "type": "number"
        },
        {
            "name": "loc_country",
            "value": x.loc && x.loc.country || null,
            "type": "string"
        },
        {
            "name": "loc_region",
            "value": x.loc && x.loc.region || null,
            "type": "string"
        },
        {
            "name": "loc_city",
            "value": x.loc && x.loc.city || null,
            "type": "string"
        },
        {
            "name": "loc_cont",
            "value": x.loc && x.loc.cont || null,
            "type": "string"
        },
        {
            "name": "ua_family",
            "value": x.ua && x.ua.family || null,
            "type": "string"
        },
        {
            "name": "ua_major",
            "value": x.ua && x.ua.major || null,
            "type": "number"
        },
        {
            "name": "ua_minor",
            "value": x.ua && x.ua.minor || null,
            "type": "number"
        },
        {
            "name": "ua_patch",
            "value": x.ua && x.ua.patch || null,
            "type": "number"
        },
        {
            "name": "ua_device_family",
            "value": x.ua && x.ua.device && x.ua.device.family || null,
            "type": "string"
        },
        {
            "name": "ua_device_major",
            "value": x.ua && x.ua.device && x.ua.device.major || null,
            "type": "number"
        },
        {
            "name": "ua_device_minor",
            "value": x.ua && x.ua.device && x.ua.device.minor || null,
            "type": "number"
        },
        {
            "name": "ua_device_patch",
            "value": x.ua && x.ua.device && x.ua.device.patch || null,
            "type": "number"
        },
        {
            "name": "ua_os_family",
            "value": x.ua && x.ua.os && x.ua.os.family || null,
            "type": "string"
        },
        {
            "name": "ua_os_major",
            "value": x.ua && x.ua.os && x.ua.os.major || null,
            "type": "number"
        },
        {
            "name": "ua_os_minor",
            "value": x.ua && x.ua.os && x.ua.os.minor || null,
            "type": "number"
        },
        {
            "name": "ua_os_patch",
            "value": x.ua && x.ua.os && x.ua.os.patch || null,
            "type": "number"
        },
        {
            "name": "rp_type",
            "value": x.rp && x.rp.type || null,
            "type": "string"
        },
        {
            "name": "rp_name",
            "value": x.rp && x.rp.name || null,
            "type": "string"
        },
        {
            "name": "rp_host",
            "value": x.rp && x.rp.host || null,
            "type": "string"
        },
        {
            "name": "rp_page",
            "value": x.rp && x.rp.page || null,
            "type": "string"
        },
        {
            "name": "rp_search",
            "value": x.rp && x.rp.search || null,
            "type": "string"
        }
    ];

    let line = '';
    let i = 0;
    for (let row in flat) {
        if (i === 0) {
            if (flat[row].value === null) {
                line += 'NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += "'" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                line += Number(flat[row].value);
            }
        } else {
            if (flat[row].value === null) {
                line += ', NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += ", '" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                line += ', ' + Number(flat[row].value);
            }
        }
        i++;
    }
    line += '\n';
    fs.appendFileSync('./temp.csv', line);
    return null;
};<commit_msg>removed console log<commit_after>const fs = require('fs');

const mysql_real_escape_string = (str) => {
    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function(char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\" + char; // prepends a backslash to backslash, percent,
                // and double/single quotes
        }
    });
};

module.exports = (x) => {
    let flat = [{
            "name": "ns_vid",
            "value": x.ns_vid || null,
            "type": "string"
        },
        {
            "name": "ns_utc",
            "value": x.ns_utc || null,
            "type": "number"
        },
        {
            "name": "date",
            "value": x.date || null,
            "type": "string"
        },
        // {
        //     "name": "agent",
        //     "value": x.agent || null,
        //     "type": "string"
        // },
        {
            "name": "ip",
            "value": x.ip || null,
            "type": "string"
        },
        {
            "name": "screen_resolution",
            "value": x.screen_resolution || null,
            "type": "string"
        },
        {
            "name": "ns_v_platform",
            "value": x.ns_v_platform || null,
            "type": "string"
        },
        {
            "name": "ns_jspageurl",
            "value": x.ns_jspageurl || null,
            "type": "string"
        },
        {
            "name": "referrer",
            "value": x.referrer || null,
            "type": "string"
        },
        {
            "name": "type",
            "value": x.type || null,
            "type": "string"
        },
        {
            "name": "bbc_name",
            "value": x.name || null,
            "type": "string"
        },
        {
            "name": "bbc_section",
            "value": x.section || null,
            "type": "string"
        },
        {
            "name": "bbc_page_type",
            "value": x.page_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_type",
            "value": x.app_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_name",
            "value": x.app_name || null,
            "type": "string"
        },
        {
            "name": "bbc_service_name",
            "value": x.bbc_site || null,
            "type": "string"
        },
        {
            "name": "bbc_referring_object",
            "value": x.referring_object || null,
            "type": "string"
        },
        {
            "name": "bbc_action_name",
            "value": x.action_name || null,
            "type": "string"
        },
        {
            "name": "bbc_action_type",
            "value": x.action_type || null,
            "type": "string"
        },
        {
            "name": "bbc_postid",
            "value": x.postID || null,
            "type": "string"
        },
        {
            "name": "bbc_ocid",
            "value": x.ocid || null,
            "type": "string"
        },
        {
            "name": "bbc_cps_asset_id",
            "value": x.cps_asset_id || null,
            "type": "string"
        },
        {
            "name": "bbc_app_name",
            "value": x.app && x.app.name || null,
            "type": "string"
        },
        {
            "name": "bbc_app_major",
            "value": x.app && x.app.major || null,
            "type": "number"
        },
        {
            "name": "bbc_app_minor",
            "value": x.app && x.app.minor || null,
            "type": "number"
        },
        {
            "name": "loc_range_lat",
            "value": x.loc && x.loc.ll[0] || null,
            "type": "number"
        },
        {
            "name": "loc_range_long",
            "value": x.loc && x.loc.ll[1] || null,
            "type": "number"
        },
        {
            "name": "loc_country",
            "value": x.loc && x.loc.country || null,
            "type": "string"
        },
        {
            "name": "loc_region",
            "value": x.loc && x.loc.region || null,
            "type": "string"
        },
        {
            "name": "loc_city",
            "value": x.loc && x.loc.city || null,
            "type": "string"
        },
        {
            "name": "loc_cont",
            "value": x.loc && x.loc.cont || null,
            "type": "string"
        },
        {
            "name": "ua_family",
            "value": x.ua && x.ua.family || null,
            "type": "string"
        },
        {
            "name": "ua_major",
            "value": x.ua && x.ua.major || null,
            "type": "number"
        },
        {
            "name": "ua_minor",
            "value": x.ua && x.ua.minor || null,
            "type": "number"
        },
        {
            "name": "ua_patch",
            "value": x.ua && x.ua.patch || null,
            "type": "number"
        },
        {
            "name": "ua_device_family",
            "value": x.ua && x.ua.device && x.ua.device.family || null,
            "type": "string"
        },
        {
            "name": "ua_device_major",
            "value": x.ua && x.ua.device && x.ua.device.major || null,
            "type": "number"
        },
        {
            "name": "ua_device_minor",
            "value": x.ua && x.ua.device && x.ua.device.minor || null,
            "type": "number"
        },
        {
            "name": "ua_device_patch",
            "value": x.ua && x.ua.device && x.ua.device.patch || null,
            "type": "number"
        },
        {
            "name": "ua_os_family",
            "value": x.ua && x.ua.os && x.ua.os.family || null,
            "type": "string"
        },
        {
            "name": "ua_os_major",
            "value": x.ua && x.ua.os && x.ua.os.major || null,
            "type": "number"
        },
        {
            "name": "ua_os_minor",
            "value": x.ua && x.ua.os && x.ua.os.minor || null,
            "type": "number"
        },
        {
            "name": "ua_os_patch",
            "value": x.ua && x.ua.os && x.ua.os.patch || null,
            "type": "number"
        },
        {
            "name": "rp_type",
            "value": x.rp && x.rp.type || null,
            "type": "string"
        },
        {
            "name": "rp_name",
            "value": x.rp && x.rp.name || null,
            "type": "string"
        },
        {
            "name": "rp_host",
            "value": x.rp && x.rp.host || null,
            "type": "string"
        },
        {
            "name": "rp_page",
            "value": x.rp && x.rp.page || null,
            "type": "string"
        },
        {
            "name": "rp_search",
            "value": x.rp && x.rp.search || null,
            "type": "string"
        }
    ];

    let line = '';
    let i = 0;
    for (let row in flat) {
        if (i === 0) {
            if (flat[row].value === null) {
                line += 'NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += "'" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                line += Number(flat[row].value);
            }
        } else {
            if (flat[row].value === null) {
                line += ', NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += ", '" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                line += ', ' + Number(flat[row].value);
            }
        }
        i++;
    }
    line += '\n';
    fs.appendFileSync('./temp.csv', line);
    return null;
};<|endoftext|>


<commit_before>module.exports = async function (shifter, writable, splice) {
    for await (const objects of shifter.iterator(splice || 64)) {
        const buffer = Buffer.from(objects.map(object => JSON.stringify(object)).join('\n')} + '\n')
        if (! await writable.write([ buffer ])) {
            break
        }
    }
    writable.end()
}
<commit_msg>Fix `serialize.js` tidy.<commit_after>module.exports = async function (shifter, writable, splice) {
    for await (const objects of shifter.iterator(splice || 64)) {
        const buffer = Buffer.from(objects.map(object => JSON.stringify(object)).join('\n') + '\n')
        if (! await writable.write([ buffer ])) {
            break
        }
    }
    writable.end()
}
<|endoftext|>