function mergeYamls(file1, file2) {
  const obj1 = yaml.safeLoad(fileToString(file1), { schema: yamlfiles.YAML_FILES_SCHEMA });
  const obj2 = yaml.safeLoad(fileToString(file2), { schema: yamlfiles.YAML_FILES_SCHEMA });

  return yaml.safeDump(merge({}, obj1, obj2));
}

function mergeYamls ( file1 , file2 ) { const obj1 = yaml . safeLoad ( fileToString ( file1 ) , { schema : yamlfiles . YAML_FILES_SCHEMA } ) ; const obj2 = yaml . safeLoad ( fileToString ( file2 ) , { schema : yamlfiles . YAML_FILES_SCHEMA } ) ; return yaml . safeDump ( merge ( { } , obj1 , obj2 ) ) ; }

Merges two yaml files. The merge is done using lodash.merge
and it happens recursively. Meaning that values of file2 will
replace values of file 1 if they have the same key.

@param {String} file1 Yaml path to file 1 or file 1 string
@param {String} file2 Yaml path to file 2 or file 2 string
@returns {String} Merged Yaml file in string format

Merges two yaml files . The merge is done using lodash . merge and it happens recursively . Meaning that values of file2 will replace values of file 1 if they have the same key .


function loadKesOverride(kesFolder, kesClass = 'kes.js') {
  let kesOverridePath = path.resolve(kesFolder, kesClass);
  let KesOverride;

  try {
    KesOverride = require(kesOverridePath);
  }
  catch (e) {
    // If the Kes override file exists, then the error occured when
    // trying to parse the file, so re-throw and prevent Kes from
    // going further.
    const fileExists = fs.existsSync(kesOverridePath);
    if (fileExists) {
      throw e;
    }

    console.log(`No Kes override found at ${kesOverridePath}, continuing`);
  }

  return KesOverride;
}

Attempt to load a Kes override class.

Throw the error if it is something other than that the Kes override
class does not exist.

@param {string} kesFolder - The folder to look in for a Kes override class
@param {string} kesClass - The path/filename to look for as a Kes override class
@returns {Class} - A Kes override class


function determineKesClass(options, Kes) {
  let KesOverride;

  // If there is a kes class specified, use that
  const kesClass = get(options, 'kesClass');
  if (kesClass) {
    KesOverride = loadKesOverride(process.cwd(), kesClass);
  }
  else {
    let kesFolder;

    // Check if there is kes.js in the kes folder
    if (options.kesFolder) {
      kesFolder = options.kesFolder;
    }
    else {
      kesFolder = path.join(process.cwd(), '.kes');
    }
    KesOverride = loadKesOverride(kesFolder);

    // If the first Kes override didn't load, check if there is
    // a kes.js in the template folder.
    if (!KesOverride) {
      const template = get(options, 'template', '/path/to/nowhere');
      kesFolder = path.join(process.cwd(), template);
      KesOverride = loadKesOverride(kesFolder);
    }
  }

  return KesOverride || Kes;
}

Based on the information passed from the CLI by the commander
module this function determines whether to use the default Kes class
or use the override class provided by the user

@param {object} options The options passed by the commander library
@param {Class} Kes the default kes class
@returns {Class} Kes class


function failure(e) {
  if (e.message) {
    console.log(e.message);
  }
  else {
    console.log(e);
  }
  process.exit(1);
}

function failure ( e ) { if ( e . message ) { console . log ( e . message ) ; } else { console . log ( e ) ; } process . exit ( 1 ) ; }

In case of error logs the error and exit with error 1
@param {Error} e error object


function getSystemBucket(config) {
  let bucket = get(config, 'buckets.internal');
  if (bucket && typeof bucket === 'string') {
    return bucket;
  }

  bucket = get(config, 'system_bucket');
  if (bucket && typeof bucket === 'string') {
    return bucket;
  }
  return undefined;
}

function getSystemBucket ( config ) { let bucket = get ( config , 'buckets.internal' ) ; if ( bucket && typeof bucket === 'string' ) { return bucket ; } bucket = get ( config , 'system_bucket' ) ; if ( bucket && typeof bucket === 'string' ) { return bucket ; } return undefined ; }

Discover and returns the system bucket used for deployment

@param {Object} config - cumulus config object
@returns {string} name of the bucket


function buildNestedCfs(config, KesClass, options) {
  const limit = pLimit(1);
  if (config.nested_templates) {
    const nested = config.nested_templates;
    console.log('Nested templates are found!');
    const ps = Object.keys(nested).map((name) => limit(() => {
      console.log(`Compiling nested template for ${name}`);

      const newOptions = Object.assign({}, options);
      newOptions.cfFile = nested[name].cfFile;
      newOptions.configFile = nested[name].configFile;

      // no templates are used in nested stacks
      delete newOptions.template;
      delete newOptions.deployment;

      // use the parent stackname
      newOptions.stack = config.stack;
      newOptions.parent = config;
      const nestedConfig = new Config(newOptions);

      // get the bucket name from the parent
      if (!nestedConfig.bucket) {
        nestedConfig.bucket = utils.getSystemBucket(config);
      }

      // add nested deployment name
      nestedConfig.nested_cf_name = name;

      const kes = new KesClass(nestedConfig);
      return kes.uploadCF().then((uri) => {
        config.nested_templates[name].url = uri;
      });
    }));
    return Promise.all(ps)
      .then(() => config)
      .catch(utils.failure);
  }
  return Promise.resolve(config);
}

Builds templates nested in the main template
using the specified config and cf file paths

@param {object} config Kes config object
@param {object} KesClass the Kes Class
@param {object} options The options passed by the commander library
@return {Promise} returns a promise of an updated Kes config object


function buildCf(options, cmd) {
  const KesClass = utils.determineKesClass(options, Kes);
  let parentConfig;
  try {
    parentConfig = new Config(options);
  }
  catch (e) {
    return Promise.reject(e);
  }

  return buildNestedCfs(parentConfig, KesClass, options).then((config) => {
    const kes = new KesClass(config);
    switch (cmd) {
      case 'create':
        deprecate('"kes cf create" command is deprecated. Use "kes cf deploy" instead');
        return kes.createStack();
      case 'update':
        deprecate('"kes cf update" command is deprecated. Use "kes cf deploy" instead');
        return kes.updateStack();
      case 'upsert':
        deprecate('"kes cf upsert" command is deprecated. Use "kes cf deploy" instead');
        return kes.upsertStack();
      case 'deploy':
        return kes.deployStack();
      case 'validate':
        return kes.validateTemplate();
      case 'compile':
        return kes.compileCF();
      case 'delete':
        return kes.deleteStack();
      default:
        console.log('Wrong choice. Accepted arguments: [create|update|upsert|deploy|validate|compile]');
    }
  });
}

Builds, uploads and deploy a Cloudformation based on options passed
from the commander library

@param {object} options Options passed by the commander library
@param {string} cmd the argument selected in the CLI, e.g. deploy, update, etc.
@return {undefined}

Builds uploads and deploy a Cloudformation based on options passed from the commander library


function buildLambda(options, cmd) {
  if (cmd) {
    const KesClass = utils.determineKesClass(options, Kes);
    const config = new Config(options);
    const kes = new KesClass(config);
    kes.updateSingleLambda(cmd).then(r => utils.success(r)).catch(e => utils.failure(e));
  }
  else {
    utils.failure(new Error('Lambda name is missing'));
  }
}

function
buildLambda
(
options
,
cmd
)
{
if
(
cmd
)
{
const
KesClass
=
utils
.
determineKesClass
(
options
,
Kes
)
;
const
config
=
new
Config
(
options
)
;
const
kes
=
new
KesClass
(
config
)
;
kes
.
updateSingleLambda
(
cmd
)
.
then
(
r
=>
utils
.
success
(
r
)
)
.
catch
(
e
=>
utils
.
failure
(
e
)
)
;
}
else
{
utils
.
failure
(
new
Error
(
'Lambda name is missing'
)
)
;
}
}

Builds and uploads a lambda function based on the options passed by the commander
@param {object} options Options passed by the commander library
@param {string} cmd the argument selected in the CLI, e.g. lambda name
@return {undefined}


function sendResponse(event, context, responseStatus, responseData) {
  const responseBody = JSON.stringify({
    Status: responseStatus,
    Reason: 'See the details in CloudWatch Log Stream: ' + context.logStreamName,
    PhysicalResourceId: context.logStreamName,
    StackId: event.StackId,
    RequestId: event.RequestId,
    LogicalResourceId: event.LogicalResourceId,
    Data: responseData
  });

  console.log('RESPONSE BODY:\n', responseBody);

  const https = require('https');
  const url = require('url');

  const parsedUrl = url.parse(event.ResponseURL);
  const options = {
    hostname: parsedUrl.hostname,
    port: 443,
    path: parsedUrl.path,
    method: 'PUT',
    headers: {
      'content-type': '',
      'content-length': responseBody.length
    }
  };

  console.log('SENDING RESPONSE...\n');

  const request = https.request(options, function(response) {
    console.log('STATUS: ' + response.statusCode);
    console.log('HEADERS: ' + JSON.stringify(response.headers));
    // Tell AWS Lambda that the function execution is done
    context.done();
  });

  request.on('error', function(error) {
    console.log('sendResponse Error:' + error);
    // Tell AWS Lambda that the function execution is done
    context.done();
  });

  // write data to request body
  request.write(responseBody);
  request.end();
}

Send response to the pre - signed S3 URL


function optionsToString(options) {
    return Object.keys(options)
        .map(function processOption(key) {
            return key + "=" + options[key];
        })
        .join(",");
}

function optionsToString ( options ) { return Object . keys ( options ) . map ( function processOption ( key ) { return key + "=" + options [ key ] ; } ) . join ( "," ) ; }

Return options converted to a string

@param  {Object} options
@return {String}


function assign(target) {
    var sources = Array.prototype.slice.call(arguments, 1);

    function assignArgument(previous, source) {
        Object.keys(source).forEach(function assignItem(key) {
            previous[key] = source[key]; // eslint-disable-line no-param-reassign
        });

        return previous;
    }

    return sources.reduce(assignArgument, target);
}

Polyfill Object.assign

@param  {Object} target
@param  {Object} source1 ...
@return {Object}


function openPopupWithPost(url, postData, name, options) {
    var form = document.createElement("form");
    var win;

    form.setAttribute("method", "post");
    form.setAttribute("action", url);
    form.setAttribute("target", name);

    Object.keys(postData).forEach(function addFormItem(key) {
        var input = document.createElement("input");
        input.type = "hidden";
        input.name = key;
        input.value = postData[key];
        form.appendChild(input);
    });

    document.body.appendChild(form);

    win = window.open("/", name, options);
    win.document.write("Loading...");

    form.submit();
    document.body.removeChild(form);

    return win;
}

function openPopupWithPost ( url , postData , name , options ) { var form = document . createElement ( "form" ) ; var win ; form . setAttribute ( "method" , "post" ) ; form . setAttribute ( "action" , url ) ; form . setAttribute ( "target" , name ) ; Object . keys ( postData ) . forEach ( function addFormItem ( key ) { var input = document . createElement ( "input" ) ; input . type = "hidden" ; input . name = key ; input . value = postData [ key ] ; form . appendChild ( input ) ; } ) ; document . body . appendChild ( form ) ; win = window . open ( "/" , name , options ) ; win . document . write ( "Loading..." ) ; form . submit ( ) ; document . body . removeChild ( form ) ; return win ; }

Create a form element, add hidden inputs for all the post data
and post it into a newly opened popup

@param  {String} url
@param  {Object} postData
@param  {String} name
@param  {Object} options
@return {Object}

Create a form element add hidden inputs for all the post data and post it into a newly opened popup


function popupExecute(execute, url, name, options, callback) {
    var popupName = name || defaultPopupName();
    var popupOptions = optionsResolveCentered(assign({}, defaultOptions, options));
    var popupCallback = callback || function noop() {};
    var optionsString = optionsToString(popupOptions);
    var win = execute(url, popupName, optionsString);
    var isMessageSent = false;
    var interval;

    function popupCallbackOnce(err, data) {
        if (!isMessageSent) {
            isMessageSent = true;
            popupCallback(err, data);
        }
    }

    function onMessage(message) {
        var data = message ? message.data : undefined;

        if (data) {
            popupCallbackOnce(undefined, data);
            window.removeEventListener("message", onMessage);
        }
    }

    window.addEventListener("message", onMessage, false);

    if (win) {
        interval = setInterval(function closePopupCallback() {
            if (win == null || win.closed) {
                setTimeout(function delayWindowClosing() {
                    clearInterval(interval);
                    popupCallbackOnce(new Error("Popup closed"));
                }, 500);
            }
        }, 100);
    } else {
        popupCallbackOnce(new Error("Popup blocked"));
    }

    return win;
}

function
popupExecute
(
execute
,
url
,
name
,
options
,
callback
)
{
var
popupName
=
name
||
defaultPopupName
(
)
;
var
popupOptions
=
optionsResolveCentered
(
assign
(
{
}
,
defaultOptions
,
options
)
)
;
var
popupCallback
=
callback
||
function
noop
(
)
{
}
;
var
optionsString
=
optionsToString
(
popupOptions
)
;
var
win
=
execute
(
url
,
popupName
,
optionsString
)
;
var
isMessageSent
=
false
;
var
interval
;
function
popupCallbackOnce
(
err
,
data
)
{
if
(
!
isMessageSent
)
{
isMessageSent
=
true
;
popupCallback
(
err
,
data
)
;
}
}
function
onMessage
(
message
)
{
var
data
=
message
message
.
data
:
undefined
;
if
(
data
)
{
popupCallbackOnce
(
undefined
,
data
)
;
window
.
removeEventListener
(
"message"
,
onMessage
)
;
}
}
window
.
addEventListener
(
"message"
,
onMessage
,
false
)
;
if
(
win
)
{
interval
=
setInterval
(
function
closePopupCallback
(
)
{
if
(
win
==
||
win
.
closed
)
{
setTimeout
(
function
delayWindowClosing
(
)
{
clearInterval
(
interval
)
;
popupCallbackOnce
(
new
Error
(
"Popup closed"
)
)
;
}
,
500
)
;
}
}
,
100
)
;
}
else
{
popupCallbackOnce
(
new
Error
(
"Popup blocked"
)
)
;
}
return
win
;
}

Open a popup using the first argument. Wait for it to close.
Returns the window object

@param  {Function}
@param  {String}
@param  {String}
@param  {Object}
@param  {Function}
@return {Object}

Open a popup using the first argument . Wait for it to close . Returns the window object


function popup(url, name, options, callback) {
    return popupExecute(window.open, url, name, options, callback);
}

function popup ( url , name , options , callback ) { return popupExecute ( window . open , url , name , options , callback ) ; }

Open a popup using the first argument.
Wait for it to close and call the callback.
Set the options string using the options object
Returns the window object

@param  {String} url
@param  {String} name
@param  {Object} options
@param  {Function} callback
@return {Object}

Open a popup using the first argument . Wait for it to close and call the callback . Set the options string using the options object Returns the window object


function popupWithPost(url, postData, name, options, callback) {
    function openWithPostData(popupUrl, popupName, optionsString) {
        return openPopupWithPost(popupUrl, postData, popupName, optionsString);
    }

    return popupExecute(openWithPostData, url, name, options, callback);
}

function popupWithPost ( url , postData , name , options , callback ) { function openWithPostData ( popupUrl , popupName , optionsString ) { return openPopupWithPost ( popupUrl , postData , popupName , optionsString ) ; } return popupExecute ( openWithPostData , url , name , options , callback ) ; }

Open a popup using the first argument.
Post the data into the open popup.
Wait for it to close and call the callback.
Set the options string using the options object
Returns the window object

@param  {String} url
@param  {Object} postData
@param  {String} name
@param  {Object} options
@param  {Function} callback
@return {Object}

Open a popup using the first argument . Post the data into the open popup . Wait for it to close and call the callback . Set the options string using the options object Returns the window object


function getWrappingContentRange(editor) {
	if (editor.somethingSelected()) {
		const sel = editor.listSelections().filter(sel => sel.anchor !== sel.head)[0];
		if (sel) {
			return  comparePos(sel.anchor, sel.head) < 0
				? { from: sel.anchor, to: sel.head }
				: { from: sel.head, to: sel.anchor };
		}
	}

	// Nothing selected, find parent HTML node and return range for its content
	return getTagRangeForPos(editor, editor.getCursor());
}

Returns content range that should be wrapped
@param {CodeMirror} editor


function betweenTags(editor, range) {
	if (equalCursorPos(range.anchor, range.head)) {
		const cursor = range.anchor;
		const mode = editor.getModeAt(cursor);

		if (mode.name === 'xml') {
			const left = editor.getTokenAt(cursor);
			const right = editor.getTokenAt(Object.assign({}, cursor, { ch: cursor.ch + 1 }));

			return left.type === 'tag bracket' && left.string === '>'
				&& right.type === 'tag bracket' && right.string === '</';
		}
	}
}

function
betweenTags
(
editor
,
range
)
{
if
(
equalCursorPos
(
range
.
anchor
,
range
.
head
)
)
{
const
cursor
=
range
.
anchor
;
const
mode
=
editor
.
getModeAt
(
cursor
)
;
if
(
mode
.
name
===
'xml'
)
{
const
left
=
editor
.
getTokenAt
(
cursor
)
;
const
right
=
editor
.
getTokenAt
(
Object
.
assign
(
{
}
,
cursor
,
{
ch
:
cursor
.
ch
+
1
}
)
)
;
return
left
.
type
===
'tag bracket'
&&
left
.
string
===
'>'
&&
right
.
type
===
'tag bracket'
&&
right
.
string
===
'</'
;
}
}
}

Check if given range is a single caret between tags
@param {CodeMirror} editor
@param {CodeMirror.range} range


function canExtract(editor, pos, config) {
	const tokenType = editor.getTokenTypeAt(pos);

	if (config.type === 'stylesheet') {
		return tokenType !== 'comment' && tokenType !== 'string';
	}

	if (config.syntax === 'html') {
		return tokenType === null;
	}

	if (config.syntax === 'slim' || config.syntax === 'pug') {
		return tokenType === null || tokenType === 'tag'
			|| (tokenType && /attribute/.test(tokenType));
	}

	if (config.syntax === 'haml') {
		return tokenType === null || tokenType === 'attribute';
	}

	if (config.syntax === 'jsx') {
		// JSX a bit tricky, delegate it to caller
		return true;
	}

	return false;
}

Check if abbreviation can be extracted from given position
@param {CodeMirror.Editor} editor
@param {CodeMirror.Position} pos
@param {Object} config
@return {Boolean}


function getStylesheetCompletions(editor, pos, config) {
	const line = editor.getLine(pos.line).slice(0, pos.ch);
	const prefix = extractPrefix(line, /[\w-@$]/);

	if (prefix) {
		// Make sure that current position precedes element name (e.g. not attribute,
		// class, id etc.)
		const prefixRange = {
			from: { line: pos.line, ch: pos.ch - prefix.length },
			to: pos
		};

		if (config.options && config.options.property) {
			const lowerProp = config.options.property.toLowerCase();
			// Find matching CSS property snippet for keyword completions
			const completion = getSnippetCompletions(editor, pos, config)
				.find(item => item.property && item.property === lowerProp);

			if (completion && completion.keywords.length) {
				return completion.keywords.map(kw => {
					return kw.key.indexOf(prefix) === 0 && new EmmetCompletion('value', editor, prefixRange, kw.key, kw.preview, kw.snippet);
				}).filter(Boolean);
			}
		} else {
			return getSnippetCompletions(editor, pos, config)
				.filter(completion => completion.key !== prefix && completion.key.indexOf(prefix) === 0)
				.map(completion => new EmmetCompletion('snippet', editor, prefixRange, completion.key, completion.preview, completion.snippet));
		}
	}

	return [];
}

Returns completions for stylesheet syntaxes
@param  {CodeMirror} editor
@param  {CodeMirror.Position} pos Cursor position in editor
@param  {Object} config Resolved Emmet config
@return {EmmetCompletion[]}


function getSnippetCompletions(editor, pos, config) {
	const { type, syntax } = config;

	if (!editor.state.emmetCompletions) {
		editor.state.emmetCompletions = {};
	}

	const cache = editor.state.emmetCompletions;

	if (!(syntax in cache)) {
		const registry = createSnippetsRegistry(type, syntax, config.snippets);

		cache[syntax] = type === 'stylesheet'
			? getStylesheetSnippets(registry, config)
			: getMarkupSnippets(registry, config);
	}

	return cache[syntax];
}

function getSnippetCompletions ( editor , pos , config ) { const { type , syntax } = config ; if ( ! editor . state . emmetCompletions ) { editor . state . emmetCompletions = { } ; } const cache = editor . state . emmetCompletions ; if ( ! ( syntax in cache ) ) { const registry = createSnippetsRegistry ( type , syntax , config . snippets ) ; cache [ syntax ] = type === 'stylesheet' ? getStylesheetSnippets ( registry , config ) : getMarkupSnippets ( registry , config ) ; } return cache [ syntax ] ; }

Returns all possible snippets completions for given editor context.
Completions are cached in editor for for re-use
@param  {CodeMirror.Editor} editor
@param  {CodeMirror.Position} pos
@param  {Object} config
@return {Array}

Returns all possible snippets completions for given editor context . Completions are cached in editor for for re - use


function getStylesheetSnippets(registry) {
	return convertToCSSSnippets(registry).map(snippet => {
		let preview = snippet.property;
		const keywords = snippet.keywords();
		if (keywords.length) {
			preview += `: ${removeFields(keywords.join(' | '))}`;
		} else if (snippet.value) {
			preview += `: ${removeFields(snippet.value)}`;
		}

		return {
			key: snippet.key,
			value: snippet.value,
			snippet: snippet.key,
			property: snippet.property,
			keywords: keywords.map(kw => {
				const m = kw.match(/^[\w-]+/);
				return m && {
					key: m[0],
					preview: removeFields(kw),
					snippet: kw
				};
			}).filter(Boolean),
			preview
		};
	});
}

function
getStylesheetSnippets
(
registry
)
{
return
convertToCSSSnippets
(
registry
)
.
map
(
snippet
=>
{
let
preview
=
snippet
.
property
;
const
keywords
=
snippet
.
keywords
(
)
;
if
(
keywords
.
length
)
{
preview
+=
`
${
removeFields
(
keywords
.
join
(
' | '
)
)
}
`
;
}
else
if
(
snippet
.
value
)
{
preview
+=
`
${
removeFields
(
snippet
.
value
)
}
`
;
}
return
{
key
:
snippet
.
key
,
value
:
snippet
.
value
,
snippet
:
snippet
.
key
,
property
:
snippet
.
property
,
keywords
:
keywords
.
map
(
kw
=>
{
const
m
=
kw
.
match
(
/
^[\w-]+
/
)
;
return
m
&&
{
key
:
m
[
0
]
,
preview
:
removeFields
(
kw
)
,
snippet
:
kw
}
;
}
)
.
filter
(
Boolean
)
,
preview
}
;
}
)
;
}

Returns stylesheet snippets list
@param {SnippetsRegistry} registry
@return {Array}


function getMarkupSnippets(registry, config) {
	return registry.all({ type: 'string' }).map(snippet => ({
		key: snippet.key,
		value: snippet.value,
		preview: removeFields(expand(snippet.value, config)),
		snippet: snippet.key
	}));
}

function getMarkupSnippets ( registry , config ) { return registry . all ( { type : 'string' } ) . map ( snippet => ( { key : snippet . key , value : snippet . value , preview : removeFields ( expand ( snippet . value , config ) ) , snippet : snippet . key } ) ) ; }

Returns markup snippets list
@param {SnippetsRegistry} registry
@param {Object} config
@return {Array}


function extractPrefix(str, match) {
	let offset = str.length;

	while (offset > 0) {
		if (!match.test(str[offset - 1])) {
			break;
		}
		offset--;
	}

	return str.slice(offset);
}

function extractPrefix ( str , match ) { let offset = str . length ; while ( offset > 0 ) { if ( ! match . test ( str [ offset - 1 ] ) ) { break ; } offset -- ; } return str . slice ( offset ) ; }

Extracts prefix from the end of given string that matches `match` regexp
@param {String} str
@param {RegExp} match
@return {String} Extracted prefix

Extracts prefix from the end of given string that matches match regexp


function isValidMarker(editor, marker) {
	const range = marker.find();

	// No newlines inside abbreviation
	if (range.from.line !== range.to.line) {
		return false;
	}

	// Make sure marker contains valid abbreviation
	let text = editor.getRange(range.from, range.to);
	if (!text || /^\s|\s$/g.test(text)) {
		return false;
	}

	if (marker.model && marker.model.config.syntax === 'jsx' && text[0] === '<') {
		text = text.slice(1);
	}

	if (!marker.model || marker.model.abbreviation !== text) {
		// marker contents was updated, re-parse abbreviation
		try {
			marker.model = new Abbreviation(text, range, marker.model.config);
			if (!marker.model.valid(editor, true)) {
				marker.model = null;
			}
		} catch (err) {
			console.warn(err);
			marker.model = null;
		}
	}

	return Boolean(marker.model && marker.model.snippet);
}

Ensures that given editor Emmet abbreviation marker contains valid Emmet abbreviation
and updates abbreviation model if required
@param {CodeMirror} editor
@param {CodeMirror.TextMarket} marker
@return {Boolean} `true` if marker contains valid abbreviation


function (property) {
        var def = this._definition[property];
        if (def.type === 'boolean') {
            // if it's a bool, just flip it
            this[property] = !this[property];
        } else if (def && def.values) {
            // If it's a property with an array of values
            // skip to the next one looping back if at end.
            this[property] = arrayNext(def.values, this[property]);
        } else {
            throw new TypeError('Can only toggle properties that are type `boolean` or have `values` array.');
        }
        return this;
    }

Toggle boolean properties or properties that have a `values` array in its definition.

Toggle boolean properties or properties that have a values array in its definition .


function (attr) {
        if (attr == null) return !!Object.keys(this._changed).length;
        if (has(this._derived, attr)) {
            return this._derived[attr].depList.some(function (dep) {
                return this.hasChanged(dep);
            }, this);
        }
        return has(this._changed, attr);
    }

function ( attr ) { if ( attr == null ) return ! ! Object . keys ( this . _changed ) . length ; if ( has ( this . _derived , attr ) ) { return this . _derived [ attr ] . depList . some ( function ( dep ) { return this . hasChanged ( dep ) ; } , this ) ; } return has ( this . _changed , attr ) ; }

Determine if the model has changed since the last `"change"` event. If you specify an attribute name, determine if that attribute has changed.

Determine if the model has changed since the last change event . If you specify an attribute name determine if that attribute has changed .


function (propertyName) {
        if (!this._eventBubblingHandlerCache[propertyName]) {
            this._eventBubblingHandlerCache[propertyName] = function (name, model, newValue) {
                if (changeRE.test(name)) {
                    this.trigger('change:' + propertyName + '.' + name.split(':')[1], model, newValue);
                } else if (name === 'change') {
                    this.trigger('change', this);
                }
            }.bind(this);
        }
        return this._eventBubblingHandlerCache[propertyName];
    }

function ( propertyName ) { if ( ! this . _eventBubblingHandlerCache [ propertyName ] ) { this . _eventBubblingHandlerCache [ propertyName ] = function ( name , model , newValue ) { if ( changeRE . test ( name ) ) { this . trigger ( 'change:' + propertyName + '.' + name . split ( ':' ) [ 1 ] , model , newValue ) ; } else if ( name === 'change' ) { this . trigger ( 'change' , this ) ; } } . bind ( this ) ; } return this . _eventBubblingHandlerCache [ propertyName ] ; }

Returns a bound handler for doing event bubbling while adding a name to the change string.

Returns a bound handler for doing event bubbling while adding a name to the change string .


function createDerivedProperty(modelProto, name, definition) {
    var def = modelProto._derived[name] = {
        fn: isFunction(definition) ? definition : definition.fn,
        cache: (definition.cache !== false),
        depList: definition.deps || []
    };

    // add to our shared dependency list
    def.depList.forEach(function (dep) {
        modelProto._deps[dep] = union(modelProto._deps[dep] || [], [name]);
    });

    // defined a top-level getter for derived names
    Object.defineProperty(modelProto, name, {
        get: function () {
            return this._getDerivedProperty(name);
        },
        set: function () {
            throw new TypeError("`" + name + "` is a derived property, it can't be set directly.");
        }
    });
}

helper for creating derived property definitions


function Image(image, address){

	var at = this.attributes = image.attribs;

	this.name = path.basename(at.src, path.extname(at.src));
	this.saveTo = path.dirname(require.main.filename) + "/";
	this.extension = path.extname(at.src);
	this.address = url.resolve(address, at.src);
	this.fromAddress = address;
}

function Image ( image , address ) { var at = this . attributes = image . attribs ; this . name = path . basename ( at . src , path . extname ( at . src ) ) ; this . saveTo = path . dirname ( require . main . filename ) + "/" ; this . extension = path . extname ( at . src ) ; this . address = url . resolve ( address , at . src ) ; this . fromAddress = address ; }


function shipitTask(grunt) {
  'use strict';

  // Init shipit
  grunt.shipit = new Shipit();

  grunt.registerTask('shipit', 'Shipit Task', function (env) {
    var config = grunt.config.get('shipit');

    grunt.shipit.environment = env;

    // Support legacy options.
    if (!config.default && config.options)
      config.default = config.options;

    grunt.shipit
      .initConfig(config)
      .initialize();
  });
}

function
shipitTask
(
grunt
)
{
'use strict'
;
// Init shipit
grunt
.
shipit
=
new
Shipit
(
)
;
grunt
.
registerTask
(
'shipit'
,
'Shipit Task'
,
function
(
env
)
{
var
config
=
grunt
.
config
.
get
(
'shipit'
)
;
grunt
.
shipit
.
environment
=
env
;
// Support legacy options.
if
(
!
config
.
default
&&
config
.
options
)
config
.
default
=
config
.
options
;
grunt
.
shipit
.
initConfig
(
config
)
.
initialize
(
)
;
}
)
;
}


function injectTemplate (s, node, offset, id) {
  const t = node.src ? readSrc(id, node.src) : node.content

  // Compile template
  const compiled = compiler.compile(t)
  const renderFuncs = '\nrender: ' + toFunction(compiled.render) + ',' +
    '\nstaticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + '],'
  s.appendLeft(offset, renderFuncs)
  return renderFuncs
}

function
injectTemplate
(
s
,
node
,
offset
,
id
)
{
const
t
=
node
.
src
readSrc
(
id
,
node
.
src
)
:
node
.
content
// Compile template
const
compiled
=
compiler
.
compile
(
t
)
const
renderFuncs
=
'\nrender: '
+
toFunction
(
compiled
.
render
)
+
','
+
'\nstaticRenderFns: ['
+
compiled
.
staticRenderFns
.
map
(
toFunction
)
.
join
(
','
)
+
'],'
s
.
appendLeft
(
offset
,
renderFuncs
)
return
renderFuncs
}

Only support for es5 modules

@param script
@param template
@returns {string}


function _defaultCheckSize(size) {
  return function (raw) {
    if (raw.length < size) {
      return false;
    }
    this.buffer = raw.substr(size);
    return raw.substr(0, size);
  };
}

function _defaultCheckSize ( size ) { return function ( raw ) { if ( raw . length < size ) { return false ; } this . buffer = raw . substr ( size ) ; return raw . substr ( 0 , size ) ; } ; }

A closure factory to build the checkSize function for most of our handlers


function (configFile, options) {
    DataStream.call(this);
    this.options = options || {};
    var self = this;

    // apply config
    this.configFile = configFile;

    this.init();

    // Bundles streams
    this.bundles = {};

    // Let return instance before build
    this.buildConfig = this.compileConfig(configFile, self.options);

    this.makeEmptyStreamsUnreadable(this.buildConfig);

    var isFatalErrors = !this.isAllModulesExists(this.buildConfig);
    if (isFatalErrors) {
        this.readable = false;
        this.style.readable = false;
        this.sourceMap.readable = false;
    } else {
        this._initBundlesStreams(this.buildConfig.bundles);
    }
    process.nextTick(function () {
        if (!isFatalErrors) {
            if (configFile) {
                var buildResult = self.build(self.buildConfig);

                self.write(buildResult.source);
                self.style.write(buildResult.style);
                self.sourceMap.write(buildResult.sourceMap.toString());
                self._streamBundles(buildResult.bundles);
            } else {
                self.log.write('lmd usage:\n\t    ' + 'lmd'.blue + ' ' + 'config.lmd.js(on)'.green + ' [output.lmd.js]\n');
            }
        } else {
            self.printFatalErrors(self.buildConfig);
        }
        self.closeStreams();
    });
}

function
(
configFile
,
options
)
{
DataStream
.
call
(
this
)
;
this
.
options
=
options
||
{
}
;
var
self
=
this
;
// apply config
this
.
configFile
=
configFile
;
this
.
init
(
)
;
// Bundles streams
this
.
bundles
=
{
}
;
// Let return instance before build
this
.
buildConfig
=
this
.
compileConfig
(
configFile
,
self
.
options
)
;
this
.
makeEmptyStreamsUnreadable
(
this
.
buildConfig
)
;
var
isFatalErrors
=
!
this
.
isAllModulesExists
(
this
.
buildConfig
)
;
if
(
isFatalErrors
)
{
this
.
readable
=
false
;
this
.
style
.
readable
=
false
;
this
.
sourceMap
.
readable
=
false
;
}
else
{
this
.
_initBundlesStreams
(
this
.
buildConfig
.
bundles
)
;
}
process
.
nextTick
(
function
(
)
{
if
(
!
isFatalErrors
)
{
if
(
configFile
)
{
var
buildResult
=
self
.
build
(
self
.
buildConfig
)
;
self
.
write
(
buildResult
.
source
)
;
self
.
style
.
write
(
buildResult
.
style
)
;
self
.
sourceMap
.
write
(
buildResult
.
sourceMap
.
toString
(
)
)
;
self
.
_streamBundles
(
buildResult
.
bundles
)
;
}
else
{
self
.
log
.
write
(
'lmd usage:\n\t    '
+
'lmd'
.
blue
+
' '
+
'config.lmd.js(on)'
.
green
+
' [output.lmd.js]\n'
)
;
}
}
else
{
self
.
printFatalErrors
(
self
.
buildConfig
)
;
}
self
.
closeStreams
(
)
;
}
)
;
}

LmdBuilder LMD Package Builder

LmdBuilder is readable stream

@constructor

@inherits Stream

@param {String} configFile
@param {Object} [options]

@example

new LmdBuilder("config.json", {
warn: true
})
.pipe(process.stdout);


function getSandboxMap(ast) {
        var map = {};

        walker.with_walkers({
            // looking for first var with sandbox item;
            "var" : function (vars) {
                for (var i = 0, c = vars.length, varItem; i < c; i++) {
                    varItem = vars[i];
                    if (varItem[0] === 'sandbox') {
                        varItem[1][1].forEach(function (objectVar) {
                            map[objectVar[0]] = objectVar[1][1];
                        });
                        throw 0;
                    }
                }
            }
        }, function () {
            try {
                return walker.walk(ast);
            } catch (e) {}
        });

        return map;
    }

Uses variable sandbox for create replacement map

@param {Object} ast toplevel AST

@return {Object} {name: replaceName} map


function breakSandbox(ast, replaceMap) {
        var sandboxName = ast[2][0] || 'sb';

        var newAst = walker.with_walkers({
            // lookup for dot
            // looking for this pattern
            // ["dot", ["name", "sb"], "require"] -> ["name", map["require"]]
            "dot" : function () {
                if (this[1] && this[1][0] === "name" && this[1][1] === sandboxName) {
                    var sourceName = this[2];
                    return ["name", replaceMap[sourceName]];
                }
            }
        }, function () {
            return walker.walk(ast);
        });

        // remove IEFE's `sb` or whatever argument
        newAst[1][2] = [];

        return newAst;
    }

Brakes sendbox in one module

@param {Object} ast
@param {Object} replaceMap

@return {Object} call AST


function () {
                if (isSandboxVariableWiped) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem[0] === 'sandbox') {
                        isSandboxVariableWiped = true;
                        this[1].splice(i, 1);

                        return this;
                    }
                }
            }

function ( ) { if ( isSandboxVariableWiped ) { return ; } for ( var i = 0 , c = this [ 1 ] . length , varItem ; i < c ; i ++ ) { varItem = this [ 1 ] [ i ] ; if ( varItem [ 0 ] === 'sandbox' ) { isSandboxVariableWiped = true ; this [ 1 ] . splice ( i , 1 ) ; return this ; } } }


function getEvents(ast) {
        var usage = {},
            eventIndex = 0;

        walker.with_walkers({
            // looking for first var with sandbox item;
            "call" : function () {
                if (this[1] && this[2][0]) {
                    var functionName = this[1][1];
                    switch (functionName) {
                        case "lmd_on":
                        case "lmd_trigger":
                            var eventName = this[2][0][1];
                            if (!usage[eventName]) {
                                usage[eventName] = {
                                    on: 0,
                                    trigger: 0,
                                    eventIndex: eventIndex
                                };
                                eventIndex++;
                            }
                            if (functionName === "lmd_on") {
                                usage[eventName].on++;
                            } else {
                                usage[eventName].trigger++;
                            }
                            break;
                    }
                }
            }
        }, function () {
            return walker.walk(ast);
        });

        return usage;
    }

Collects all plugins events with usage and event index

{
eventIndex: 3, // relative event index
on: 1,         // number of listeners
trigger: 2     // number of triggers
}

@param {Object} ast toplevel AST

@return {Object} toplevel AST


function wipeLmdEvents(ast) {
        var itemsToWipe = ['lmd_on', 'lmd_trigger', 'lmd_events'];

        return walker.with_walkers({
            // wipe lmdEvents variables
            "var": function () {
                if (!itemsToWipe.length) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem) {
                        var itemIndex = itemsToWipe.indexOf(varItem[0]);
                        if (itemIndex !== -1) {
                            itemsToWipe.splice(itemIndex, 1);
                            this[1].splice(i, 1);
                            i--;
                        }
                    }
                }
            }
        }, function () {
            return walker.walk(ast);
        });
    }

function
wipeLmdEvents
(
ast
)
{
var
itemsToWipe
=
[
'lmd_on'
,
'lmd_trigger'
,
'lmd_events'
]
;
return
walker
.
with_walkers
(
{
// wipe lmdEvents variables
"var"
:
function
(
)
{
if
(
!
itemsToWipe
.
length
)
{
return
;
}
for
(
var
i
=
0
,
c
=
this
[
1
]
.
length
,
varItem
;
i
<
c
;
i
++
)
{
varItem
=
this
[
1
]
[
i
]
;
if
(
varItem
)
{
var
itemIndex
=
itemsToWipe
.
indexOf
(
varItem
[
0
]
)
;
if
(
itemIndex
!==
1
)
{
itemsToWipe
.
splice
(
itemIndex
,
1
)
;
this
[
1
]
.
splice
(
i
,
1
)
;
i
;
}
}
}
}
}
,
function
(
)
{
return
walker
.
walk
(
ast
)
;
}
)
;
}

Wipes lmd_on, lmd_trigger, lmd_events variables from source

@param {Object} ast

@return {Object} modified ast


function () {
                if (!itemsToWipe.length) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem) {
                        var itemIndex = itemsToWipe.indexOf(varItem[0]);
                        if (itemIndex !== -1) {
                            itemsToWipe.splice(itemIndex, 1);
                            this[1].splice(i, 1);
                            i--;
                        }
                    }
                }
            }

function ( ) { if ( ! itemsToWipe . length ) { return ; } for ( var i = 0 , c = this [ 1 ] . length , varItem ; i < c ; i ++ ) { varItem = this [ 1 ] [ i ] ; if ( varItem ) { var itemIndex = itemsToWipe . indexOf ( varItem [ 0 ] ) ; if ( itemIndex !== - 1 ) { itemsToWipe . splice ( itemIndex , 1 ) ; this [ 1 ] . splice ( i , 1 ) ; i -- ; } } } }


function (optionName, isApply, isInline) {
        // /*if ($P.CSS || $P.JS || $P.ASYNC) {*/
        var inlinePreprocessorBlock = isInline ? '/*if (' + optionName + ') {*/' : 'if (' + optionName + ') {',
            bracesCounter = 0,

            startIndex = lmd_js.indexOf(inlinePreprocessorBlock),
            startLength = inlinePreprocessorBlock.length,

            endIndex = startIndex + inlinePreprocessorBlock.length,
            endLength = isInline ? 5 : 1;

        if (startIndex === -1) {
            return false;
        }

        // lookup for own }
        while (lmd_js.length > endIndex) {
            if (lmd_js[endIndex] === '{') {
                bracesCounter++;
            }
            if (lmd_js[endIndex] === '}') {
                bracesCounter--;
            }

            // found!
            if (bracesCounter === -1) {
                if (isInline) {
                    // step back
                    endIndex -= 2;
                } else {
                    // remove leading spaces from open part
                    while (startIndex) {
                        startIndex--;
                        startLength++;
                        if (lmd_js[startIndex] !== '\t' && lmd_js[startIndex] !== ' ') {
                            startIndex++;
                            startLength--;
                            break;
                        }
                    }

                    // remove leading spaces from close part
                    while (endIndex) {
                        endIndex--;
                        endLength++;
                        if (lmd_js[endIndex] !== '\t' && lmd_js[endIndex] !== ' ') {
                            endIndex++;
                            endLength--;
                            break;
                        }
                    }
                    // add front \n
                    endLength++;
                    startLength++;
                }

                if (isApply) {
                    // wipe preprocessor blocks only
                    // open
                    lmd_js = lmd_js.substr(0, startIndex) + lmd_js.substr(startIndex + startLength);

                    // close
                    lmd_js = lmd_js.substr(0, endIndex - startLength) + lmd_js.substr(endIndex + endLength - startLength);

                    if (!isInline) {
                        // indent block back
                        var blockForIndent = lmd_js.substr(startIndex, endIndex - startLength - startIndex);

                        blockForIndent = blockForIndent
                            .split('\n')
                            .map(function (line) {
                                return line.replace(/^\s{4}/, '');
                            })
                            .join('\n');

                        lmd_js = lmd_js.substr(0, startIndex) + blockForIndent + lmd_js.substr(endIndex - startLength);
                    }
                } else {
                    // wipe all
                    lmd_js = lmd_js.substr(0, startIndex) + lmd_js.substr(endIndex + endLength);
                }
                break;
            }
            endIndex++;
        }

        return true;
    }

Applies or removes block from lmd_js

@param {String} optionName block name eg $P.CACHE
@param isApply  apply or remove block
@param isInline block is inline (based on block comment)

@returns {Boolean} true if block was found, false - not found


function (e) {
                if (isNotLoaded) {
                    isNotLoaded = 0;
                    // register or cleanup
                    link.removeAttribute('id');

                    if (!e) {
                        sb.trigger('*:request-error', moduleName, module);
                    }
                    callback(e ? sb.register(moduleName, link) : head.removeChild(link) && sb.undefined); // e === undefined if error
                }
            }

function
(
e
)
{
if
(
isNotLoaded
)
{
isNotLoaded
=
0
;
// register or cleanup
link
.
removeAttribute
(
'id'
)
;
if
(
!
e
)
{
sb
.
trigger
(
'*:request-error'
,
moduleName
,
module
)
;
}
callback
(
e
sb
.
register
(
moduleName
,
link
)
:
head
.
removeChild
(
link
)
&&
sb
.
undefined
)
;
// e === undefined if error
}
}


function d3_layout_hierarchyRebind(object, hierarchy) {
  object.sort = d3.rebind(object, hierarchy.sort);
  object.children = d3.rebind(object, hierarchy.children);
  object.links = d3_layout_hierarchyLinks;
  object.value = d3.rebind(object, hierarchy.value);

  // If the new API is used, enabling inlining.
  object.nodes = function(d) {
    d3_layout_hierarchyInline = true;
    return (object.nodes = object)(d);
  };

  return object;
}

A method assignment helper for hierarchy subclasses.

A method assignment helper for hierarchy subclasses .


function position(row, u, rect, flush) {
    var i = -1,
        n = row.length,
        x = rect.x,
        y = rect.y,
        v = u ? round(row.area / u) : 0,
        o;
    if (u == rect.dx) { // horizontal subdivision
      if (flush || v > rect.dy) v = v ? rect.dy : 0; // over+underflow
      while (++i < n) {
        o = row[i];
        o.x = x;
        o.y = y;
        o.dy = v;
        x += o.dx = v ? round(o.area / v) : 0;
      }
      o.z = true;
      o.dx += rect.x + rect.dx - x; // rounding error
      rect.y += v;
      rect.dy -= v;
    } else { // vertical subdivision
      if (flush || v > rect.dx) v = v ? rect.dx : 0; // over+underflow
      while (++i < n) {
        o = row[i];
        o.x = x;
        o.y = y;
        o.dx = v;
        y += o.dy = v ? round(o.area / v) : 0;
      }
      o.z = false;
      o.dy += rect.y + rect.dy - y; // rounding error
      rect.x += v;
      rect.dx -= v;
    }
  }

function
position
(
row
,
u
,
rect
,
flush
)
{
var
i
=
1
,
n
=
row
.
length
,
x
=
rect
.
x
,
y
=
rect
.
y
,
v
=
u
round
(
row
.
area
/
u
)
:
0
,
o
;
if
(
u
==
rect
.
dx
)
{
// horizontal subdivision
if
(
flush
||
v
>
rect
.
dy
)
v
=
v
rect
.
dy
:
0
;
// over+underflow
while
(
++
i
<
n
)
{
o
=
row
[
i
]
;
o
.
x
=
x
;
o
.
y
=
y
;
o
.
dy
=
v
;
x
+=
o
.
dx
=
v
round
(
o
.
area
/
v
)
:
0
;
}
o
.
z
=
true
;
o
.
dx
+=
rect
.
x
+
rect
.
dx
x
;
// rounding error
rect
.
y
+=
v
;
rect
.
dy
-=
v
;
}
else
{
// vertical subdivision
if
(
flush
||
v
>
rect
.
dx
)
v
=
v
rect
.
dx
:
0
;
// over+underflow
while
(
++
i
<
n
)
{
o
=
row
[
i
]
;
o
.
x
=
x
;
o
.
y
=
y
;
o
.
dx
=
v
;
y
+=
o
.
dy
=
v
round
(
o
.
area
/
v
)
:
0
;
}
o
.
z
=
false
;
o
.
dy
+=
rect
.
y
+
rect
.
dy
y
;
// rounding error
rect
.
x
+=
v
;
rect
.
dx
-=
v
;
}
}

Positions the specified row of nodes. Modifies `rect`.

Positions the specified row of nodes . Modifies rect .


function(classes) {
            var map = {};

            function find(name, data) {
                var node = map[name], i;
                if (!node) {
                    node = map[name] = data || {name: name, children: []};
                    if (name.length) {
                        node.parent = find("");
                        node.parent.children.push(node);
                        node.name = name;
                        node.key = escapeId(name);
                    }
                }
                return node;
            }

            classes.forEach(function(d) {
                find(d.name, d);
            });

            return map[""];
        }

function ( classes ) { var map = { } ; function find ( name , data ) { var node = map [ name ] , i ; if ( ! node ) { node = map [ name ] = data || { name : name , children : [ ] } ; if ( name . length ) { node . parent = find ( "" ) ; node . parent . children . push ( node ) ; node . name = name ; node . key = escapeId ( name ) ; } } return node ; } classes . forEach ( function ( d ) { find ( d . name , d ) ; } ) ; return map [ "" ] ; }

Lazily construct the package hierarchy from class names.

Lazily construct the package hierarchy from class names .


function stringify(object) {
    var properties = [];
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            properties.push(quote(key) + ':' + getValue(object[key]));
        }
    }
    return "{" + properties.join(",") + "}";
}

function stringify ( object ) { var properties = [ ] ; for ( var key in object ) { if ( object . hasOwnProperty ( key ) ) { properties . push ( quote ( key ) + ':' + getValue ( object [ key ] ) ) ; } } return "{" + properties . join ( "," ) + "}" ; }


function countIf() {
		var self = this, ret;
		if (self[0].start && analyzing.indexOf(self) < 0) {
			var decision = self[1];
			var lineId = self[0].name + ':' + (self[0].start.line + lineOffset);

			self[1] = wrapCondition(decision, lineId);

			// We are adding new lines, make sure code blocks are actual blocks
			if (self[2] && self[2][0].start && self[2][0].start.value != "{") {
				self[2] = [ "block", [self[2]]];
			}

			if (self[3] && self[3][0].start && self[3][0].start.value != "{") {
				self[3] = [ "block", [self[3]]];
			}
		}

		ret = countLine.call(self);

		if (decision) {
			analyzing.pop(decision);
		}

		return ret;
	}

Walker for 'if' nodes. It overrides countLine because we want to instrument conditions.

'this' is an if node, so
'this[0]' is the node descriptor
'this[1]' is the decision block
'this[2]' is the 'then' code block
'this[3]' is the 'else' code block

Note that if/else if/else in AST are represented as nested if/else

Walker for if nodes . It overrides countLine because we want to instrument conditions .


function wrapCondition(decision, lineId, parentPos) {
		if (options.condition === false) {
			// condition coverage is disabled
			return decision;
		}

		if (isSingleCondition(decision)) {
			var pos = getPositionStart(decision, parentPos);
			var condId = lineId + ":" + pos;

			analyzing.push(decision);
			allConditions.push(condId);
			return ["call",
                ["dot", ["name", "require"], "coverage_condition"],
				[
					[ "string", moduleName ],
					[ "string", condId],
					decision
				]
			];
		} else {
			decision[2] = wrapCondition(decision[2], lineId, getPositionStart(decision, parentPos));
			decision[3] = wrapCondition(decision[3], lineId, getPositionEnd(decision, parentPos));

			return decision;
		}
	}

function
wrapCondition
(
decision
,
lineId
,
parentPos
)
{
if
(
options
.
condition
===
false
)
{
// condition coverage is disabled
return
decision
;
}
if
(
isSingleCondition
(
decision
)
)
{
var
pos
=
getPositionStart
(
decision
,
parentPos
)
;
var
condId
=
lineId
+
":"
+
pos
;
analyzing
.
push
(
decision
)
;
allConditions
.
push
(
condId
)
;
return
[
"call"
,
[
"dot"
,
[
"name"
,
"require"
]
,
"coverage_condition"
]
,
[
[
"string"
,
moduleName
]
,
[
"string"
,
condId
]
,
decision
]
]
;
}
else
{
decision
[
2
]
=
wrapCondition
(
decision
[
2
]
,
lineId
,
getPositionStart
(
decision
,
parentPos
)
)
;
decision
[
3
]
=
wrapCondition
(
decision
[
3
]
,
lineId
,
getPositionEnd
(
decision
,
parentPos
)
)
;
return
decision
;
}
}

This is the key function for condition coverage as it wraps every condition in
a function call.
The condition id is generated fron the lineId (@see countLine) plus the character
position of the condition.

This is the key function for condition coverage as it wraps every condition in a function call . The condition id is generated fron the lineId (


function isSingleCondition(decision) {
		if (decision[0].start && decision[0].name != "binary") {
			return true;
		} else if (decision[1] == "&&" || decision[1] == "||") {
			return false;
		} else {
			return true;
		}
	}

function isSingleCondition ( decision ) { if ( decision [ 0 ] . start && decision [ 0 ] . name != "binary" ) { return true ; } else if ( decision [ 1 ] == "&&" || decision [ 1 ] == "||" ) { return false ; } else { return true ; } }

Wheter or not the if decision has only one boolean condition


function countLabel() {
		var ret;
		if (this[0].start && analyzing.indexOf(this) < 0) {
			var content = this[2];

			if (content[0].name == "for" && content[4] && content[4].name != "block") {
				content[4] = [ "block", [content[4]]];
			}
			analyzing.push(content);

			var ret = countLine.call(this);

			analyzing.pop(content);
		}
		return ret;
	}

function countLabel ( ) { var ret ; if ( this [ 0 ] . start && analyzing . indexOf ( this ) < 0 ) { var content = this [ 2 ] ; if ( content [ 0 ] . name == "for" && content [ 4 ] && content [ 4 ] . name != "block" ) { content [ 4 ] = [ "block" , [ content [ 4 ] ] ] ; } analyzing . push ( content ) ; var ret = countLine . call ( this ) ; analyzing . pop ( content ) ; } return ret ; }

Label nodes need special treatment as well.

myLabel : for (;;) {
//whateveer code here
continue myLabel
}

Label can be wrapped by countLine, hovewer the subsequent for shouldn't be wrapped.

instrumentation("label");
mylabel : instrumentation("for")
for (;;) {}

The above code would be wrong.

This function makes sure that the 'for' after a label is not instrumented and that
the 'for' content is wrapped in a block.

I'm don't think it's reasonable to use labels with something that is not a 'for' block.
In that case the instrumented code might easily break.

Label nodes need special treatment as well .


function giveNameToAnonymousFunction () {
		var node = this;

		if (node[0].name == "var" || node[0].name == "object") {
			node[1].forEach(function (assignemt) {
				if (assignemt[1]) {
					if (assignemt[1][0].name === "function") {
						assignemt[1][0].anonymousName = assignemt[0];
					} else if (assignemt[1][0].name === "conditional") {
						if (assignemt[1][2][0] && assignemt[1][2][0].name === "function") {
							assignemt[1][2][0].anonymousName = assignemt[0];
						}
						if (assignemt[1][3][0] && assignemt[1][3][0].name === "function") {
							assignemt[1][3][0].anonymousName = assignemt[0];
						}
					}
				}
			});
		} else if (node[0].name == "assign" && node[1] === true) {
			if (node[3][0].name === "function") {
				node[3][0].anonymousName = getNameFromAssign(node);
			} else if (node[3][0] === "conditional") {
				if (node[3][2][0] && node[3][2][0].name === "function") {
					node[3][2][0].anonymousName = getNameFromAssign(node);
				}
				if (node[3][3][0] && node[3][3][0].name === "function") {
					node[3][3][0].anonymousName = getNameFromAssign(node);
				}
			}
		}
	}

function giveNameToAnonymousFunction ( ) { var node = this ; if ( node [ 0 ] . name == "var" || node [ 0 ] . name == "object" ) { node [ 1 ] . forEach ( function ( assignemt ) { if ( assignemt [ 1 ] ) { if ( assignemt [ 1 ] [ 0 ] . name === "function" ) { assignemt [ 1 ] [ 0 ] . anonymousName = assignemt [ 0 ] ; } else if ( assignemt [ 1 ] [ 0 ] . name === "conditional" ) { if ( assignemt [ 1 ] [ 2 ] [ 0 ] && assignemt [ 1 ] [ 2 ] [ 0 ] . name === "function" ) { assignemt [ 1 ] [ 2 ] [ 0 ] . anonymousName = assignemt [ 0 ] ; } if ( assignemt [ 1 ] [ 3 ] [ 0 ] && assignemt [ 1 ] [ 3 ] [ 0 ] . name === "function" ) { assignemt [ 1 ] [ 3 ] [ 0 ] . anonymousName = assignemt [ 0 ] ; } } } } ) ; } else if ( node [ 0 ] . name == "assign" && node [ 1 ] === true ) { if ( node [ 3 ] [ 0 ] . name === "function" ) { node [ 3 ] [ 0 ] . anonymousName = getNameFromAssign ( node ) ; } else if ( node [ 3 ] [ 0 ] === "conditional" ) { if ( node [ 3 ] [ 2 ] [ 0 ] && node [ 3 ] [ 2 ] [ 0 ] . name === "function" ) { node [ 3 ] [ 2 ] [ 0 ] . anonymousName = getNameFromAssign ( node ) ; } if ( node [ 3 ] [ 3 ] [ 0 ] && node [ 3 ] [ 3 ] [ 0 ] . name === "function" ) { node [ 3 ] [ 3 ] [ 0 ] . anonymousName = getNameFromAssign ( node ) ; } } } }

This function tries to extract the name of anonymous functions depending on where they are
defined.

For instance
var something = function () {}
the function itself is anonymous but we can use 'something' as its name

'node' is anything that gets counted, function are extracted from

var
node[0] : node description
node[1] : array of assignments
node[x][0] : variable name
node[x][1] : value, node

object  (when functions are properties of an object)
node[0] : node description
node[1] : array of attributes
node[x][0] : attribute name
node[x][1] : value, node

assign  (things like object.name = function () {})
node[0] : node description
node[1] : type of assignment, 'true' if '=' or operand (like += |= and others)
node[2] : left value, object property or variable
node[3] : right value, node

in case of assign, node[2] can be
'name' if we assign to a variable
name[0] : node description
name[1] : variable's name
'dot' when we assign to an object's property
dot[0] : node description
dot[1] : container object
dot[2] : property

This function tries to extract the name of anonymous functions depending on where they are defined .


function wrapConditionals () {
		if (options.condition === false) {
			// condition coverage is disabled
			return;
		}

		var self = this, ret;
		if (self[0].start && analyzing.indexOf(self) < 0) {
			analyzing.push(self);
			var lineId = self[0].name + ':' + (self[0].start.line + lineOffset);

			self[1] = wrapCondition(self[1], lineId);

			self[2] = walker.walk(self[2]);
			self[3] = walker.walk(self[3]);

			analyzing.pop(self);

			return self;
		} else if (self[1]) {
			self[1] = wrapCondition(self[1], lineId);
		}
	}

function
wrapConditionals
(
)
{
if
(
options
.
condition
===
false
)
{
// condition coverage is disabled
return
;
}
var
self
=
this
,
ret
;
if
(
self
[
0
]
.
start
&&
analyzing
.
indexOf
(
self
)
<
0
)
{
analyzing
.
push
(
self
)
;
var
lineId
=
self
[
0
]
.
name
+
':'
+
(
self
[
0
]
.
start
.
line
+
lineOffset
)
;
self
[
1
]
=
wrapCondition
(
self
[
1
]
,
lineId
)
;
self
[
2
]
=
walker
.
walk
(
self
[
2
]
)
;
self
[
3
]
=
walker
.
walk
(
self
[
3
]
)
;
analyzing
.
pop
(
self
)
;
return
self
;
}
else
if
(
self
[
1
]
)
{
self
[
1
]
=
wrapCondition
(
self
[
1
]
,
lineId
)
;
}
}

This function wraps ternary conditionals in order to have condition coverage

'this' is a node containing
'this[0]' node descriptor
'this[1]' decision block
'this[2]' first statement
'this[3]' second statement


function (name, deps, module) {
    switch (arguments.length) {
        case 1: // define(function () {})
            module = name;
            deps = name = sb.undefined;
            break;

        case 2: // define(['a', 'b'], function () {})
            module = deps;
            deps = name;
            name = sb.undefined;
            break;

        case 3: // define('name', ['a', 'b'], function () {})
    }

    if (typeof module !== "function") {
        amdModules[currentModule] = module;
        return;
    }

    var output = {'exports': {}};
    if (!deps) {
        deps = ["require", "exports", "module"];
    }
    for (var i = 0, c = deps.length; i < c; i++) {
        switch (deps[i]) {
            case "require":
                deps[i] = currentRequire;
                break;
            case "module":
                deps[i] = output;
                break;
            case "exports":
                deps[i] = output.exports;
                break;
            default:
                deps[i] = currentRequire && currentRequire(deps[i]);
        }
    }
    module = module.apply(this, deps) || output.exports;
    amdModules[currentModule] = module;
}

RequireJS & AMD-style define

(function (require) {
var define = require.define;

define(["a"], function (a) {
return a + 2;
});
})

@param name
@param deps
@param module


function stats_calculate_coverage(moduleName) {
    var stats = sb.trigger('*:stats-get', moduleName, null)[1],
        total,
        covered,
        lineId,
        lineNum,
        parts;

    var lineReport = {};

    if (!stats.lines) {
        return;
    }
    stats.coverage = {};

    covered = 0;
    total = stats.lines.length;
    for (lineId in stats.runLines) {
        if (stats.runLines[lineId] > 0) {
            covered++;
        } else {
            lineNum = lineId;
            if (!lineReport[lineNum]) {
                lineReport[lineNum] = {};
            }
            lineReport[lineNum].lines = false;
        }
    }
    stats.coverage.lines = {
        total: total,
        covered: covered,
        percentage: 100.0 * (total ? covered / total : 1)
    };

    covered = 0;
    total = stats.functions.length;
    for (lineId in stats.runFunctions) {
        if (stats.runFunctions[lineId] > 0) {
            covered++;
        } else {
            parts = lineId.split(':');
            lineNum = parts[1];
            if (!lineReport[lineNum]) {
                lineReport[lineNum] = {};
            }
            if (!lineReport[lineNum].functions) {
                lineReport[lineNum].functions = [];
            }
            lineReport[lineNum].functions.push(parts[0]);
        }
    }
    stats.coverage.functions = {
        total:total,
        covered:covered,
        percentage:100.0 * (total ? covered / total : 1)
    };

    covered = 0;
    total = stats.conditions.length;
    for (lineId in stats.runConditions) {
        if (stats.runConditions[lineId][1] > 0) {
            covered += 1;
        }

        if (stats.runConditions[lineId][1] === 0) {

            parts = lineId.split(':');
            lineNum = parts[1];
            if (!lineReport[lineNum]) {
                lineReport[lineNum] = {};
            }
            if (!lineReport[lineNum].conditions) {
                lineReport[lineNum].conditions = [];
            }
            lineReport[lineNum].conditions.push(stats.runConditions[lineId]);
        }
    }
    stats.coverage.conditions = {
        total:total,
        covered:covered,
        percentage:100.0 * (total ? covered / total : 1)
    };
    stats.coverage.report = lineReport;
}

function stats_calculate_coverage ( moduleName ) { var stats = sb . trigger ( '*:stats-get' , moduleName , null ) [ 1 ] , total , covered , lineId , lineNum , parts ; var lineReport = { } ; if ( ! stats . lines ) { return ; } stats . coverage = { } ; covered = 0 ; total = stats . lines . length ; for ( lineId in stats . runLines ) { if ( stats . runLines [ lineId ] > 0 ) { covered ++ ; } else { lineNum = lineId ; if ( ! lineReport [ lineNum ] ) { lineReport [ lineNum ] = { } ; } lineReport [ lineNum ] . lines = false ; } } stats . coverage . lines = { total : total , covered : covered , percentage : 100.0 * ( total ? covered / total : 1 ) } ; covered = 0 ; total = stats . functions . length ; for ( lineId in stats . runFunctions ) { if ( stats . runFunctions [ lineId ] > 0 ) { covered ++ ; } else { parts = lineId . split ( ':' ) ; lineNum = parts [ 1 ] ; if ( ! lineReport [ lineNum ] ) { lineReport [ lineNum ] = { } ; } if ( ! lineReport [ lineNum ] . functions ) { lineReport [ lineNum ] . functions = [ ] ; } lineReport [ lineNum ] . functions . push ( parts [ 0 ] ) ; } } stats . coverage . functions = { total : total , covered : covered , percentage : 100.0 * ( total ? covered / total : 1 ) } ; covered = 0 ; total = stats . conditions . length ; for ( lineId in stats . runConditions ) { if ( stats . runConditions [ lineId ] [ 1 ] > 0 ) { covered += 1 ; } if ( stats . runConditions [ lineId ] [ 1 ] === 0 ) { parts = lineId . split ( ':' ) ; lineNum = parts [ 1 ] ; if ( ! lineReport [ lineNum ] ) { lineReport [ lineNum ] = { } ; } if ( ! lineReport [ lineNum ] . conditions ) { lineReport [ lineNum ] . conditions = [ ] ; } lineReport [ lineNum ] . conditions . push ( stats . runConditions [ lineId ] ) ; } } stats . coverage . conditions = { total : total , covered : covered , percentage : 100.0 * ( total ? covered / total : 1 ) } ; stats . coverage . report = lineReport ; }

Calculate coverage total

@param moduleName


function (config, mixins) {
    if (Array.isArray(config.mixins) && Array.isArray(mixins)) {
        config.mixins.push.apply(config.mixins, mixins);
        return config;
    }

    return deepDestructableMerge(config, {
        mixins: mixins
    });
}

function ( config , mixins ) { if ( Array . isArray ( config . mixins ) && Array . isArray ( mixins ) ) { config . mixins . push . apply ( config . mixins , mixins ) ; return config ; } return deepDestructableMerge ( config , { mixins : mixins } ) ; }

Merges mixins with config

@param {Object} config
@param {String[]} mixins


function (left, right) {
    for (var prop in right) {
        if (right.hasOwnProperty(prop))  {
            if (typeof left[prop] === "object") {
                deepDestructableMerge(left[prop], right[prop]);
            } else {
                left[prop] = right[prop];
            }
        }
    }
    return left;
}

function ( left , right ) { for ( var prop in right ) { if ( right . hasOwnProperty ( prop ) ) { if ( typeof left [ prop ] === "object" ) { deepDestructableMerge ( left [ prop ] , right [ prop ] ) ; } else { left [ prop ] = right [ prop ] ; } } } return left ; }

Config files deep merge

@param {Object} left
@param {Object} right


function (config, configDir) {
    config = config || {};
    if (typeof config.extends !== "string") {
        return config;
    }

    var parentConfig = tryExtend(readConfig(configDir, config.extends), configDir);

    return deepDestructableMerge(parentConfig, config);
}

function ( config , configDir ) { config = config || { } ; if ( typeof config . extends !== "string" ) { return config ; } var parentConfig = tryExtend ( readConfig ( configDir , config . extends ) , configDir ) ; return deepDestructableMerge ( parentConfig , config ) ; }

Merges all config files in module's lineage

@param {Object} config
@param {String} configDir

Merges all config files in module s lineage


function (modulePath, dependsFileMask) {
    modulePath = [].concat(modulePath);

    return modulePath.map(function (modulePath) {
        var fileName = modulePath.replace(/^.*\/|\.[a-z0-9]+$/g, '');

        return path.join(path.dirname(modulePath), dependsFileMask.replace('*', fileName));
    });
}

function ( modulePath , dependsFileMask ) { modulePath = [ ] . concat ( modulePath ) ; return modulePath . map ( function ( modulePath ) { var fileName = modulePath . replace ( / ^.*\/|\.[a-z0-9]+$ / g , '' ) ; return path . join ( path . dirname ( modulePath ) , dependsFileMask . replace ( '*' , fileName ) ) ; } ) ; }

Returns depends config file of this module

@param {String|Array} modulePath
@param {String}       dependsFileMask

@return {Array}


function (configA, configB, flagsNames, isMasterConfig) {
    // Apply Flags
    flagsNames.forEach(function (optionsName) {
        // if master -> B
        if (typeof configB[optionsName] === "undefined") {
            return;
        }

        if (isMasterConfig) {
            configA[optionsName] = configB[optionsName];
        } else {
            // if A literal B array -> B
            if (configB[optionsName] instanceof Array && !(configA[optionsName] instanceof Array) ) {
                configA[optionsName] = configB[optionsName];
            } else if (configB[optionsName] instanceof Array && configA[optionsName] instanceof Array) {
                // if A array B array -> A concat B
                configA[optionsName] = configA[optionsName].concat(configB[optionsName]);
            } else {
                // if A literal B literal -> union
                // if A array B literal -> A
                configA[optionsName] = configA[optionsName] || configB[optionsName];
            }
            // else {}
        }
    });
}

function
(
configA
,
configB
,
flagsNames
,
isMasterConfig
)
{
// Apply Flags
flagsNames
.
forEach
(
function
(
optionsName
)
{
// if master -> B
if
(
typeof
configB
[
optionsName
]
===
"undefined"
)
{
return
;
}
if
(
isMasterConfig
)
{
configA
[
optionsName
]
=
configB
[
optionsName
]
;
}
else
{
// if A literal B array -> B
if
(
configB
[
optionsName
]
instanceof
Array
&&
!
(
configA
[
optionsName
]
instanceof
Array
)
)
{
configA
[
optionsName
]
=
configB
[
optionsName
]
;
}
else
if
(
configB
[
optionsName
]
instanceof
Array
&&
configA
[
optionsName
]
instanceof
Array
)
{
// if A array B array -> A concat B
configA
[
optionsName
]
=
configA
[
optionsName
]
.
concat
(
configB
[
optionsName
]
)
;
}
else
{
// if A literal B literal -> union
// if A array B literal -> A
configA
[
optionsName
]
=
configA
[
optionsName
]
||
configB
[
optionsName
]
;
}
// else {}
}
}
)
;
}

Merges configs flags

@param {Object}   configA
@param {Object}   configB
@param {String[]} flagsNames
@param {Boolean}  isMasterConfig


function addPluginsFromBundles(resultConfig) {
    if (resultConfig.bundles) {
        var bundles = Object.keys(resultConfig.bundles),
            lmdPlugins = Object.keys(LMD_PLUGINS);

        // Apply flags from bundles
        bundles.forEach(function (bundleName) {
            mergeFlags(resultConfig, resultConfig.bundles[bundleName], lmdPlugins, false);
        });

        // Set bundle plugin
        if (bundles.length) {
            resultConfig.bundle = true;
        }
    }
}

function
addPluginsFromBundles
(
resultConfig
)
{
if
(
resultConfig
.
bundles
)
{
var
bundles
=
Object
.
keys
(
resultConfig
.
bundles
)
,
lmdPlugins
=
Object
.
keys
(
LMD_PLUGINS
)
;
// Apply flags from bundles
bundles
.
forEach
(
function
(
bundleName
)
{
mergeFlags
(
resultConfig
,
resultConfig
.
bundles
[
bundleName
]
,
lmdPlugins
,
false
)
;
}
)
;
// Set bundle plugin
if
(
bundles
.
length
)
{
resultConfig
.
bundle
=
true
;
}
}
}

For now add plugins from build to bundle

@param resultConfig


function (code, options) {
    var exports = [],
        requires = [],
        bind = [],
        extra_exports = options.extra_exports,
        extra_require = options.extra_require,
        extra_bind = options.extra_bind,
        exportCode,
        bindModuleName;

    // add exports to the module end
    // extra_exports = {name: code, name: code}
    if (typeof extra_exports === "object") {
        for (var exportName in extra_exports) {
            exportCode = extra_exports[exportName];
            exports.push('    ' + JSON.stringify(exportName) + ': ' + exportCode);
        }
        code += '\n\n/* added by builder */\nreturn {\n' + exports.join(',\n') + '\n};';
    } else if (extra_exports) {
        // extra_exports = string
        code += '\n\n/* added by builder */\nreturn ' + extra_exports + ';';
    }

    // change context of module (this)
    // and proxy return value
    // return function(){}.call({name: require('name')});
    if (typeof extra_bind === "object") {
        for (var bindName in extra_bind) {
            bindModuleName = extra_bind[bindName];
            bind.push('    ' + JSON.stringify(bindName) + ': require(' + JSON.stringify(bindModuleName) + ')');
        }
        code = '\nreturn function(){\n\n' + code + '\n}.call({\n' + bind.join(',\n') + '\n});';
    } else if (extra_bind) {
        // return function(){}.call(require('name'));
        code = '\nreturn function(){\n\n' + code + '\n}.call(require(' + JSON.stringify(extra_bind) + '));';
    }

    // add require to the module start
    if (typeof extra_require === "object") {
        // extra_require = [name, name, name]
        if (extra_require instanceof Array) {
            for (var i = 0, c = extra_require.length, moduleName; i < c; i++) {
                moduleName = extra_require[i];
                requires.push('require(' + JSON.stringify(moduleName) + ');');
            }
            code = '/* added by builder */\n' + requires.join('\n') + '\n\n' + code;
        } else {
            // extra_require = {name: name, name: name}
            for (var localName in extra_require) {
                moduleName = extra_require[localName];
                requires.push(localName + ' = require(' + JSON.stringify(moduleName) + ')');
            }
            code = '/* added by builder */\nvar ' + requires.join(',\n    ') + ';\n\n' + code;
        }
    } else if (extra_require) {
        // extra_require = string
        code = '/* added by builder */\nrequire(' + JSON.stringify(extra_require) + ');\n\n' + code;
    }

    return '(function (require) { /* wrapped by builder */\n' + code + '\n})';
}

Wrapper for non-lmd modules files

@param {String}               code
@param {Object}               options
@param {Object|String}        options.extra_exports
@param {Object|String|String} options.extra_require
@param {Object|String|String} options.extra_bind

@returns {String} wrapped code


function (code, moduleOptions, moduleType) {
    switch (moduleType) {
        case "3-party":
            // create lmd module from non-lmd module
            code = wrap3partyModule(code, moduleOptions);
            break;

        case "plain":
            // wrap plain module
            code = wrapPlainModule(code);
            break;

        case "amd":
            // AMD RequireJS
            code = wrapAmdModule(code);
            break;

        case "fd":
        case "fe":
            // wipe tail ;
            code = removeTailSemicolons(code);
    }

    return code;
}

Aggregates all module wrappers

@param code
@param moduleOptions
@param moduleType

@return {String}


function getModuleType (code) {
    var ast;

    if (typeof code === "object") {
        ast = code;
    } else {
        try {
            JSON.parse(code);
            return "json";
        } catch (e) {}

        try {
            ast = parser.parse(code);
        } catch (e) {
            return "string";
        }
    }

    // Empty module
    if (ast.length === 2 && !ast[1].length && ast[0] === 'toplevel') return "plain";

    // ["toplevel",[["defun","depA",["require"],[]]]]
    if (ast && ast.length === 2 &&
        ast[1] && ast[1].length === 1 &&
        ast[1][0][0] === "defun"
        ) {
        return "fd";
    }

    // ["toplevel",[["stat",["function",null,["require"],[]]]]]
    if (ast && ast.length === 2 &&
        ast[1] && ast[1].length === 1 &&
        ast[1][0][0] === "stat" &&
        ast[1][0][1] &&
        ast[1][0][1][0] === "function"
        ) {
        return "fe";
    }

    if (ast) {
        var isAmd = ast[1].every(function (ast) {
            return ast[0] === "stat" &&
                ast[1][0] === "call" &&
                ast[1][1][0] === "name" &&
                ast[1][1][1] === "define";
        });

        if (isAmd) {
            return "amd";
        }
    }

    return "plain";
}

Checks module type

@param {Object|String} code module AST or module Content

@return {String} df|fe|plain|amd


function d3_transform(m) {
  var r0 = [m.a, m.b],
      r1 = [m.c, m.d],
      kx = d3_transformNormalize(r0),
      kz = d3_transformDot(r0, r1),
      ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz));
  this.translate = [m.e, m.f];
  this.rotate = Math.atan2(m.b, m.a) * d3_transformDegrees;
  this.scale = [kx, ky || 0];
  this.skew = ky ? kz / ky * d3_transformDegrees : 0;
}

function d3_transform ( m ) { var r0 = [ m . a , m . b ] , r1 = [ m . c , m . d ] , kx = d3_transformNormalize ( r0 ) , kz = d3_transformDot ( r0 , r1 ) , ky = d3_transformNormalize ( d3_transformCombine ( r1 , r0 , - kz ) ) ; this . translate = [ m . e , m . f ] ; this . rotate = Math . atan2 ( m . b , m . a ) * d3_transformDegrees ; this . scale = [ kx , ky || 0 ] ; this . skew = ky ? kz / ky * d3_transformDegrees : 0 ; }

Compute x-scale and normalize the first row. Compute shear and make second row orthogonal to first. Compute y-scale and normalize the second row. Finally, compute the rotation.

Compute x - scale and normalize the first row . Compute shear and make second row orthogonal to first . Compute y - scale and normalize the second row . Finally compute the rotation .


function mousewheel() {
    start.apply(this, arguments);
    if (!d3_behavior_zoomZooming) d3_behavior_zoomZooming = d3_behavior_zoomLocation(d3.svg.mouse(d3_behavior_zoomTarget));
    d3_behavior_zoomTo(d3_behavior_zoomDelta() + xyz[2], d3.svg.mouse(d3_behavior_zoomTarget), d3_behavior_zoomZooming);
  }

function mousewheel ( ) { start . apply ( this , arguments ) ; if ( ! d3_behavior_zoomZooming ) d3_behavior_zoomZooming = d3_behavior_zoomLocation ( d3 . svg . mouse ( d3_behavior_zoomTarget ) ) ; d3_behavior_zoomTo ( d3_behavior_zoomDelta ( ) + xyz [ 2 ] , d3 . svg . mouse ( d3_behavior_zoomTarget ) , d3_behavior_zoomZooming ) ; }


function d3_behavior_zoomDelta() {

  // mousewheel events are totally broken!
  // https://bugs.webkit.org/show_bug.cgi?id=40441
  // not only that, but Chrome and Safari differ in re. to acceleration!
  if (!d3_behavior_zoomDiv) {
    d3_behavior_zoomDiv = d3.select("body").append("div")
        .style("visibility", "hidden")
        .style("top", 0)
        .style("height", 0)
        .style("width", 0)
        .style("overflow-y", "scroll")
      .append("div")
        .style("height", "2000px")
      .node().parentNode;
  }

  var e = d3.event, delta;
  try {
    d3_behavior_zoomDiv.scrollTop = 1000;
    d3_behavior_zoomDiv.dispatchEvent(e);
    delta = 1000 - d3_behavior_zoomDiv.scrollTop;
  } catch (error) {
    delta = e.wheelDelta || (-e.detail * 5);
  }

  return delta * .005;
}

detect the pixels that would be scrolled by this wheel event


function (data) {
    var config;

    // case data is argv string
    if (typeof data === "string") {
        // try to parse new version
        config = parseArgv(data);

        // its new config argv string
        if (Object.keys(config).length) {
            // translate short params to long one
            config.mode = config.mode || config.m;
            config.output = config.output || config.o;
            config.log = config.log || config.l;
            config.config = config.config || config.c;
            config['no-warn'] = config['no-warn'] || config['no-w'];
            config['source-map'] = config['source-map'] || config['sm'];
            config['source-map-root'] = config['source-map-root'] || config['sm-root'];
            config['source-map-www'] = config['source-map-www'] || config['sm-www'];
            config['source-map-inline'] = config['source-map-inline'] || config['sm-inline'];
        } else {
            // an old argv format, split argv and parse manually
            data = data.split(' ');

            // without mode
            if (availableModes.indexOf(data[2]) === -1) {
                config = {
                    mode: 'main',
                    config: data[2],
                    output: data[3]
                };
            } else { // with mode
                config = {
                    mode: data[2],
                    config: data[3],
                    output: data[4]
                };
            }
        }

    // case data is config object
    } else if (typeof config === "object") {
        // use as is
        config = data;

    // case else
    } else {
        // wut?
        throw new Error('Bad config data');
    }

    config.mode = config.mode || 'main';
    config.warn = !config['no-warn'];
    config.sourcemap = config['source-map'] || false;
    config.www_root = config['source-map-root'] || "";
    config.sourcemap_www = config['source-map-www'] || "";
    config.sourcemap_inline = config['source-map-inline'] || false;
    config.log = config.log || false;

    return config;
}

Formats lmd config

@param  {String|Object} data

@return {Object}


function parse (options, document, callback) {
  xml2js.parseString(document, {
    trim: true,
    normalizeTags: true,
    normalize: true
  }, function (err, result) {
    var source = options.source;

    if (!err) {

      // Process the url input, but break if base.input returns false.
      //   In other words, _.find is looking for a non-falsy err.
      // For now, this can only happen if no outputDir is defined,
      //   which is a fatal bad option problem and will happen immediately.
      _.find(
        // if the sitemap is malformed, just blow up
        result.urlset.url,
        function (urlNode) {
          // optionally ignore current urls by sitemap policy
          var url,
              process = !options.sitemapPolicy ||
                !stillCurrent(urlNode, options);

          if (process) {
            // if sitemap is malformed, just blow up
            url = urlm.parse(urlNode.loc[0]);
            if (!base.input(_.extend({}, options, {
                protocol: url.protocol,
                auth: url.auth,
                hostname: url.hostname,
                port: url.port
              }),
              urlNode.loc[0])
            ) {
              source = urlNode.loc[0];
              err = base.generatorError();
            }
          }

          return err;
        }
      );
    }

    callback(common.prependMsgToErr(err, source, true));
  });
}

Parse a sitemap document
For each qualifying url element in urlset, call base.input
Stops processing if an error occurs.

@param {Object} options - Sitemap options.
@param {String} options.source - The sitemap url or file.
@param {Boolean} options.sitemapPolicy - True if sitemapPolicy should be enforced.
@param {String} document - An xml document string.
@param {Function} callback - The completion callback.

Parse a sitemap document For each qualifying url element in urlset call base . input Stops processing if an error occurs .


function convert(options, buffer, next, callback) {
  var gunzip = path.extname(options.source) === ".gz";

  if (gunzip) {
    zlib.gunzip(buffer, function (err, result) {
      if (err) {
        callback(common.prependMsgToErr(err, options.source, true));
      } else {
        next(options, result && result.toString(), callback);
      }
    });
  }
  else {
    next(options, buffer.toString(), callback);
  }
}

function convert ( options , buffer , next , callback ) { var gunzip = path . extname ( options . source ) === ".gz" ; if ( gunzip ) { zlib . gunzip ( buffer , function ( err , result ) { if ( err ) { callback ( common . prependMsgToErr ( err , options . source , true ) ) ; } else { next ( options , result && result . toString ( ) , callback ) ; } } ) ; } else { next ( options , buffer . toString ( ) , callback ) ; } }

Convert Buffer input, call next or callback with error

@param {Object} options - Sitemap options.
@param {String} options.source - Sitemap URL.
@param {Buffer} buffer - A node buffer.
@param {Function} next - A function to run after optional conversion applied.
@param {Function} callback - A completion callback.

Convert Buffer input call next or callback with error


function getUrl (options, parseFn, callback) {
  request({
    url: options.source,
    encoding: null,
    timeout: options.timeout() // get the default timeout
  }, function (err, res, body) {
    var error = err || common.checkResponse(res, ["text/xml", "application/xml"]);

    if (error) {
      callback(common.prependMsgToErr(error, options.source, true));
    } else {
      convert(options, body, parseFn, callback);
    }
  });
}

function
getUrl
(
options
,
parseFn
,
callback
)
{
request
(
{
url
:
options
.
source
,
encoding
:
,
timeout
:
options
.
timeout
(
)
// get the default timeout
}
,
function
(
err
,
res
,
body
)
{
var
error
=
err
||
common
.
checkResponse
(
res
,
[
"text/xml"
,
"application/xml"
]
)
;
if
(
error
)
{
callback
(
common
.
prependMsgToErr
(
error
,
options
.
source
,
true
)
)
;
}
else
{
convert
(
options
,
body
,
parseFn
,
callback
)
;
}
}
)
;
}

Retrieve the sitemap from a url and call to parse it.

@param {Object} options - Sitemap options.
@param {String} options.source - Sitemap URL.
@param {Function} options.timeout - User supplied run timeout.
@param {Function} parseFn - A data parser function.
@param {Function} callback - A completion callback function.

Retrieve the sitemap from a url and call to parse it .


function getFile (options, parseFn, callback) {
  fs.readFile(options.source, function (err, data) {
    if (err) {
      callback(common.prependMsgToErr(err, options.source, true));
    } else {
      convert(options, data, parseFn, callback);
    }
  });
}

function getFile ( options , parseFn , callback ) { fs . readFile ( options . source , function ( err , data ) { if ( err ) { callback ( common . prependMsgToErr ( err , options . source , true ) ) ; } else { convert ( options , data , parseFn , callback ) ; } } ) ; }

Retrieve the sitemap from a file and call to parse it.

@param {Object} options - Sitemap options.
@param {String} options.source - Sitemap file path.
@param {Function} parseFn - A data parser function.
@param {Function} callback - A completion callback.

Retrieve the sitemap from a file and call to parse it .


function (error, message, quoteInput) {
    var result, prepend, empty = "", quote = "'";

    if (error) {
      if (message) {
        prepend = quoteInput ? empty.concat(quote, message, quote) : message;
      }

      // Force Error instance, coerce given error to a string
      error = error instanceof Error ? error : new Error(empty + error);

      // If message supplied, prepend it
      error.message =
        prepend ? empty.concat(prepend, ": ", error.message) : error.message;

      result = error;
    }

    return result;
  }

Prepend a message to an Error message.

@param {Object} [error] - An instance of Error. If not, converted to Error.
If undefined, then pass through undefined.
@param {String} [message] - The message to prepend.
@param {Boolean} [quoteInput] - True if the message should be quoted.
@returns {Error} The updated Error instance, undefined if no error.


function (res, mediaTypes) {
    var contentTypeOk,
        result = "status: '" + res.statusCode + "', GET failed.";

    mediaTypes = !Array.isArray(mediaTypes) ? [mediaTypes] : mediaTypes;

    if (res.statusCode === 200) {
      // if content-type exists, and media type found then contentTypeOk
      contentTypeOk =
        res.headers["content-type"] &&
        // empty array and none found return true
        !mediaTypes.every(function(mediaType) {
          // flip -1 to 0 and NOT, so that true == NOT found, found stops loop w/false
          return !~res.headers["content-type"].indexOf(mediaType);
        });

      result = contentTypeOk ? "" : "content-type not one of '"+mediaTypes.join(",")+"'";
    }

    return result;
  }

Simple response checker for remote files.
Expected use in robots.txt or sitemap.xml only.

@param {IncomingMessage} res - The IncomingMessage response to check.
@param {Array} mediaTypes - array of acceptable content-type media type strings.
@returns {String} Error message, empty string (falsy) if OK.

Simple response checker for remote files . Expected use in robots . txt or sitemap . xml only .


function nodeCall (nodeFunc /* args... */) {
  var nodeArgs = Array.prototype.slice.call(arguments, 1);

  return new Promise(function (resolve, reject) {
    /**
     * Resolve a node callback
     */
    function nodeResolver (err, value) {
      if (err) {
        reject(err);
      } else {
        resolve(value);
      }
    }

    nodeArgs.push(nodeResolver);
    nodeFunc.apply(nodeFunc, nodeArgs);
  });
}

/**
     * Resolve a node callback
     */

Utility to promisify a Node function

@param {Function} nodeFunc - The node-style function to Promisify.


function prepareWrite (outputPath, callback) {
  var path = pathLib.parse(outputPath);
  var dir = pathLib.join(path.root, path.dir);
  mkdirp(dir, callback);
}

function prepareWrite ( outputPath , callback ) { var path = pathLib . parse ( outputPath ) ; var dir = pathLib . join ( path . root , path . dir ) ; mkdirp ( dir , callback ) ; }

Make sure path exists so a sitemap write can succeed.

@param {String} outputPath - File path and name.
@param {Funcion} callback - Completion callback.

Make sure path exists so a sitemap write can succeed .


function parse (options, document, callback) {
  xml2js.parseString(document, {
    trim: true,
    normalizeTags: true,
    normalize: true
  }, function (err, result) {
    var sitemapUrls = [];
    var sitemapIndexOptions = Object.assign({}, options, {
      outputPath: undefined
    });

    if (!err) {
      // Check if we should process each sitemap in the index.
      _.forEach(
        // if the sitemap index is malformed, just blow up
        result.sitemapindex.sitemap,
        function (sitemapNode) {
          // optionally ignore current sitemaps by sitemap policy
          var shouldProcess = !options.sitemapPolicy ||
            !smLib.stillCurrent(sitemapNode, sitemapIndexOptions);

          if (shouldProcess) {
            // if sitemap index is malformed, just blow up
            sitemapUrls.push(sitemapNode.loc[0]);
          }
        }
      );

      // Edge case message for clarity
      if (sitemapUrls.length === 0) {
        console.log("[*] No sitemaps qualified for processing");
      }

      // Get all the sitemaps, parse them, and generate input for each
      Promise.all(sitemapUrls.map(function (sitemapUrl) {
        var sitemapOptions = Object.assign({}, options, {
          source: sitemapUrl,
          input: "sitemap",
          sitemapOutputDir: false,
          __sitemapIndex: sitemapIndexOptions
        });

        console.log("[+] Loading the sitemap: '"+sitemapUrl+"'");

        return nodeCall(smLib.getUrl, sitemapOptions, processSitemap);
      }))
        .then(function () {
          // Ignore the array of results to this function
          callback();
        })
        .catch(callback);
    } else {
      callback(err);
    }
  });
}

Parse a sitemap index document
For each qualifying sitemap element, download, parse the sitemap.
Stops processing if an error occurs.

@param {Object} options - Sitemap options.
@param {Boolean} options.sitemapPolicy - True if sitemap policy should be used.
@param {String} document - xml document string.
@param {Function} callback - A completion callback.

Parse a sitemap index document For each qualifying sitemap element download parse the sitemap . Stops processing if an error occurs .


function (options, listener) {
    var opts = Object.assign({}, base.defaults(defaults), options);

    return base.run(opts, generateInput, listener);
  }

function ( options , listener ) { var opts = Object . assign ( { } , base . defaults ( defaults ) , options ) ; return base . run ( opts , generateInput , listener ) ; }

Generate the input arguments for snapshots from a robots.txt file.
Each input argument generated calls the listener passing the input object.

@param {Object} options - Sitemap index options.
@param {Function} listener - Callback to receive each input.
@returns {Promise} Resolves to undefined on completion.

Generate the input arguments for snapshots from a robots . txt file . Each input argument generated calls the listener passing the input object .


function generateInput (options) {
  return nodeCall(
    fs.readFile,
    options.source
  )
    .catch(function (err) {
      options._abort(err);
    })
    .then(function (data) {
      var error;

      if (data) {
        data.toString().split('\n').every(function (line) {
          var page = line.replace(/^\s+|\s+$/g, "");

          if (!base.input(options, page)) {
            error = common.prependMsgToErr(base.generatorError(), page, true);
            return false;
          }
          return true;
        });

        if (error) {
          console.error(error);
          options._abort(error);
        }
      }

      base.EOI(textfile);
    });
}

function generateInput ( options ) { return nodeCall ( fs . readFile , options . source ) . catch ( function ( err ) { options . _abort ( err ) ; } ) . then ( function ( data ) { var error ; if ( data ) { data . toString ( ) . split ( '\n' ) . every ( function ( line ) { var page = line . replace ( / ^\s+|\s+$ / g , "" ) ; if ( ! base . input ( options , page ) ) { error = common . prependMsgToErr ( base . generatorError ( ) , page , true ) ; return false ; } return true ; } ) ; if ( error ) { console . error ( error ) ; options . _abort ( error ) ; } } base . EOI ( textfile ) ; } ) ; }

Generate the snapshot arguments from a line oriented text file.
Each line contains a single url we need a snapshot for.

@param {Object} options - input generator options object.
@param {String} options.source - path to the local input file.
@returns {Promise} resolves when complete.

Generate the snapshot arguments from a line oriented text file . Each line contains a single url we need a snapshot for .


function generateInput (options) {
  var result = new Promise(function (resolve, reject) {
    var all;

    if (Array.isArray(options.source)) {
      all = options.source.every(function (sourceUrl) {
        var url = urlm.parse(sourceUrl);
        var opts = Object.assign({}, options, {
          protocol: url.protocol,
          auth: url.auth,
          hostname: url.hostname,
          port: url.port
        });

        if (!base.input(opts, sourceUrl)) {
          reject(
            common.prependMsgToErr(base.generatorError(), sourceUrl, true)
          );
          return false;
        }

        return true;
      });

      if (all) {
        resolve();
      }
    } else {
      reject(new Error("options.source must be an array"));
    }
  });

  return result
    .catch(function (error) {
      options._abort(error);
    })
    .then(function () {
      base.EOI(array);
    });
}

function
generateInput
(
options
)
{
var
result
=
new
Promise
(
function
(
resolve
,
reject
)
{
var
all
;
if
(
Array
.
isArray
(
options
.
source
)
)
{
all
=
options
.
source
.
every
(
function
(
sourceUrl
)
{
var
url
=
urlm
.
parse
(
sourceUrl
)
;
var
opts
=
Object
.
assign
(
{
}
,
options
,
{
protocol
:
url
.
protocol
,
auth
:
url
.
auth
,
hostname
:
url
.
hostname
,
port
:
url
.
port
}
)
;
if
(
!
base
.
input
(
opts
,
sourceUrl
)
)
{
reject
(
common
.
prependMsgToErr
(
base
.
generatorError
(
)
,
sourceUrl
,
true
)
)
;
return
false
;
}
return
true
;
}
)
;
if
(
all
)
{
resolve
(
)
;
}
}
else
{
reject
(
new
Error
(
"options.source must be an array"
)
)
;
}
}
)
;
return
result
.
catch
(
function
(
error
)
{
options
.
_abort
(
error
)
;
}
)
.
then
(
function
(
)
{
base
.
EOI
(
array
)
;
}
)
;
}

Generate the snapshot arguments from an array of pages.
Stops processing if one fails.

@param {Object} options - input generator options object.
@param {String} options.source - Array of urls.
@param {Function} options._abort - Called to abort the output watcher.
@returns {Promise} Resolves to undefined on success.

Generate the snapshot arguments from an array of pages . Stops processing if one fails .


function normalize (obj) {
  var result = obj;
  if (typeof obj !== "function") {
    if (typeof obj !== "undefined") {
      if (Object.prototype.toString.call(obj) !== "[object Object]") {
        result = (function (value) { return function () { return value; }; }(obj));
      } else {
        result = (function (o) { return function (key, passthru) {
          if (o[key] === void 0) {
            return o.__default || (passthru ? key : undefined);
          } else {
            return o[key];
          }
        }; }(obj));
      }
    } else {
      result = function (passthru) { return passthru; };
    }
  }
  return result;
}

function
normalize
(
obj
)
{
var
result
=
obj
;
if
(
typeof
obj
!==
"function"
)
{
if
(
typeof
obj
!==
"undefined"
)
{
if
(
Object
.
prototype
.
toString
.
call
(
obj
)
!==
"[object Object]"
)
{
result
=
(
function
(
value
)
{
return
function
(
)
{
return
value
;
}
;
}
(
obj
)
)
;
}
else
{
result
=
(
function
(
o
)
{
return
function
(
key
,
passthru
)
{
if
(
o
[
key
]
===
void
0
)
{
return
o
.
__default
||
(
passthru
key
:
undefined
)
;
}
else
{
return
o
[
key
]
;
}
}
;
}
(
obj
)
)
;
}
}
else
{
result
=
function
(
passthru
)
{
return
passthru
;
}
;
}
}
return
result
;
}

Normalize the given object to a function.

If the input is a function, return it as is.
If the input is undefined, then a passthru function is generated.
If the input is NOT an Object, then a function returns that value.
If the input is an Object, then a function receives a key and
returns the property value if it exists, otherwise return the __default value.
If a passthru is requested, the key is returned when no __default is found.

@param {Any} obj - Some input to be represented by a function.
@returns {Function} A function to represent the given input.

Normalize the given object to a function .


function supplyMissingDefault (options, name) {
  if (options[name]() === void 0) {
    options[name] = _.wrap(options[name], function(func, key) {
      var res = func(key);
      return res === void 0 ? defaults[name] : res;
    });
  }
}

function supplyMissingDefault ( options , name ) { if ( options [ name ] ( ) === void 0 ) { options [ name ] = _ . wrap ( options [ name ] , function ( func , key ) { var res = func ( key ) ; return res === void 0 ? defaults [ name ] : res ; } ) ; } }

If a normalized option was overriden, but a default still undefined, supply one.
The result could still be undefined, but only if the default is undefined.

If calling the normalized option with no args is undefined, supply missing default.

@param {Object} options - Input generator options.
@param {String} name - The name of the property to supply missing default for.

If a normalized option was overriden but a default still undefined supply one . The result could still be undefined but only if the default is undefined .


function prepOptions (options, listener) {
  // Ensure defaults are represented
  common.ensure(options, defaults);

  // Normalize certain arguments if they are not functions.
  // The certain arguments are per-page options.
  // However, outputPath is a special case
  [
    "selector", "timeout", "useJQuery", "verbose", "phantomjsOptions"
  ]
  .forEach(function (perPageOption) {
    options[perPageOption] = normalize(options[perPageOption]);
    supplyMissingDefault(options, perPageOption);
  });

  options._inputEmitter = new EventEmitter();
  options._inputEmitter.on("input", listener);
}

Prepare options for use by an input generator.

@param {Object} options - Input generator options with or without defaults.
@param {Function} listener - The input generator listener.

Prepare options for use by an input generator .