<commit_before>// required modules
const url               = require('url');
const S                 = require('string');
const cheerio           = require('cheerio');

module.exports = exports = function(payload, fn) {

  // get the data
  var data = payload.getData();

  // parse our payload url
  var uri = url.parse(data.url);

  // get the page content
  payload.getPageContent(function(err, content) {

    // did we get a error ?
    if(err) {

      // debug
      payload.error('Got a error trying to get the Page Content', err);

      // done
      return fn(null);

    }

    // did we find content ?
    if(S(content || '').isEmpty() === true) return cb(null);

    // load up cheerio
    var $ = cheerio.load(content || '');

    // parse the lines
    var lines = content.split('\n')

    // local line count
    var last_current_line = -1;

    // check for title tags
    $('img').each(function(i, elem) {

      // get the url
      var url_str = $(elem).attr('src') || $(elem).attr('href') || '';

      // check the url
      if(S(url_str).isEmpty() === false) return;

      // get the element html
      var elementHTML = $.html(elem);

      // build out the occurrence we will be adding
      var occurrence = {

        url: url_str,
        display: 'url',
        message: S( elementHTML ).truncate(100, ' ...').s

      }

      // build up code block
      var build = payload.getSnippetManager().build( lines, last_current_line, elementHTML )

      // check if we found a build
      if(build) {

        // add to list
        occurrence.display      = 'code';
        occurrence.code         = build;

        // set last line
        last_current_line       = build.subject;

      }

      // add the rule
      payload.addRule({

          type:     'error',
          message:  'Avoid empty src on image tags',
          key:      'emptysrc'

        }, occurrence)

    });

    // output
    fn(null);

  });

};
<commit_msg>Fix for the freeze on the live testing environment<commit_after>// required modules
const url               = require('url');
const S                 = require('string');
const cheerio           = require('cheerio');

module.exports = exports = function(payload, fn) {

  // get the data
  var data = payload.getData();

  // parse our payload url
  var uri = url.parse(data.url);

  // get the page content
  payload.getPageContent(function(err, content) {

    // did we get a error ?
    if(err) {

      // debug
      payload.error('Got a error trying to get the Page Content', err);

      // done
      return fn(null);

    }

    // did we find content ?
    if(S(content || '').isEmpty() === true) return fn(null);

    // load up cheerio
    var $ = cheerio.load(content || '');

    // parse the lines
    var lines = content.split('\n')

    // local line count
    var last_current_line = -1;

    // check for title tags
    $('img').each(function(i, elem) {

      // get the url
      var url_str = $(elem).attr('src') || $(elem).attr('href') || '';

      // check the url
      if(S(url_str).isEmpty() === false) return;

      // get the element html
      var elementHTML = $.html(elem);

      // build out the occurrence we will be adding
      var occurrence = {

        url: url_str,
        display: 'url',
        message: S( elementHTML ).truncate(100, ' ...').s

      }

      // build up code block
      var build = payload.getSnippetManager().build( lines, last_current_line, elementHTML )

      // check if we found a build
      if(build) {

        // add to list
        occurrence.display      = 'code';
        occurrence.code         = build;

        // set last line
        last_current_line       = build.subject;

      }

      // add the rule
      payload.addRule({

          type:     'error',
          message:  'Avoid empty src on image tags',
          key:      'emptysrc'

        }, occurrence)

    });

    // output
    fn(null);

  });

};
<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Utility functions for handling variables.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

/**
 * @name Blockly.Variables
 * @namespace
 **/
goog.provide('Blockly.Variables');

goog.require('Blockly.Blocks');
goog.require('Blockly.constants');
goog.require('Blockly.VariableModel');
goog.require('Blockly.Workspace');
goog.require('goog.string');

/**
 * Constant to separate variable names from procedures and generated functions
 * when running generators.
 * @deprecated Use Blockly.VARIABLE_CATEGORY_NAME
 */
Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME;

/**
 * Find all user-created variables that are in use in the workspace.
 * For use by generators.
 * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
 * @return {!Array.<string>} Array of variable names.
 */
Blockly.Variables.allUsedVariables = function(root) {
  var blocks;
  if (root instanceof Blockly.Block) {
    // Root is Block.
    blocks = root.getDescendants();
  } else if (root instanceof Blockly.Workspace ||
      root instanceof Blockly.WorkspaceSvg) {
    // Root is Workspace.
    blocks = root.getAllBlocks();
  } else {
    throw 'Not Block or Workspace: ' + root;
  }

  var ignorableName = Blockly.Variables.noVariableText();

  var variableHash = Object.create(null);
  // Iterate through every block and add each variable to the hash.
  for (var x = 0; x < blocks.length; x++) {
    var blockVariables = blocks[x].getVars();
    if (blockVariables) {
      for (var y = 0; y < blockVariables.length; y++) {
        var varName = blockVariables[y];
        // Variable name may be null if the block is only half-built.
        if (varName && varName.toLowerCase() != ignorableName) {
          variableHash[varName.toLowerCase()] = varName;
        }
      }
    }
  }
  // Flatten the hash into a list.
  var variableList = [];
  for (var name in variableHash) {
    variableList.push(variableHash[name]);
  }
  return variableList;
};

/**
 * Find all variables that the user has created through the workspace or
 * toolbox.  For use by generators.
 * @param {!Blockly.Workspace} root The workspace to inspect.
 * @return {!Array.<Blockly.VariableModel>} Array of variable models.
 */
Blockly.Variables.allVariables = function(root) {
  if (root instanceof Blockly.Block) {
    // Root is Block.
    console.warn('Deprecated call to Blockly.Variables.allVariables ' +
                 'with a block instead of a workspace.  You may want ' +
                 'Blockly.Variables.allUsedVariables');
    return {};
  }
  return root.getAllVariables();
};

/**
 * Create a dom element for a value tag with the given name attribute.
 * @param {string} name The value to use for the name attribute.
 * @return {!Element} An XML element: <value name="name"></value>
 */
Blockly.Variables.createValueDom_ = function(name) {
  var value = goog.dom.createDom('value');
  value.setAttribute('name', name);
  return value;
};

/**
 * Create a dom element for a shadow tag with the given tupe attribute.
 * @param {string} type The value to use for the type attribute.
 * @param {string} value The value to have inside the tag.
 * @return {!Element} An XML element: <shadow type="type">value</shadow>
 */
Blockly.Variables.createShadowDom_ = function(type) {
  var shadow = goog.dom.createDom('shadow');
  shadow.setAttribute('type', type);
  return shadow;
};

/**
 * Create a dom element for variable.
 * @param {Blockly.VariableModel} variableModel The variable to use.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createVariableDom_ = function(variableModel) {
  // <field name="VARIABLE">
  //   variablename
  // </field>
  var field = goog.dom.createDom('field', null, variableModel.name);
  field.setAttribute('name', 'VARIABLE');
  field.setAttribute('variableType', variableModel.type);
  field.setAttribute('id', variableModel.getId());
  return field;
};

/**
 * Create a dom element for value tag with a shadow text inside.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createTextDom_ = function() {
  //   <value name="VALUE">
  //     <shadow type="text">
  //       <field name="TEXT">0</field>
  //     </shadow>
  //   </value>
  var value = Blockly.Variables.createValueDom_('VALUE');
  var shadow = Blockly.Variables.createShadowDom_('text');
  var field = goog.dom.createDom('field', null, '0');
  field.setAttribute('name', 'TEXT');
  shadow.appendChild(field);
  value.appendChild(shadow);
  return value;
};

/**
 * Create a dom element for value tag with a shadow number inside.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createMathNumberDom_ = function() {
  //   <value name="VALUE">
  //     <shadow type="math_number">
  //       <field name="NUM">0</field>
  //     </shadow>
  //   </value>
  var value = Blockly.Variables.createValueDom_('VALUE');
  var shadow = Blockly.Variables.createShadowDom_('math_number');
  var field = goog.dom.createDom('field', null, '1');
  field.setAttribute('name', 'NUM');
  shadow.appendChild(field);
  value.appendChild(shadow);
  return value;
};

/**
 * Return the text that should be used in a field_variable or
 * field_variable_getter when no variable exists.
 * TODO: #572
 * @return {string} The text to display.
 */
Blockly.Variables.noVariableText = function() {
  return "No variable selected";
};

/**
* Return a new variable name that is not yet being used. This will try to
* generate single letter variable names in the range 'i' to 'z' to start with.
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
* then 'i2' to 'z2' etc.  Skip 'l'.
 * @param {!Blockly.Workspace} workspace The workspace to be unique in.
* @return {string} New variable name.
*/
Blockly.Variables.generateUniqueName = function(workspace) {
  var variableList = workspace.getAllVariables();
  var newName = '';
  if (variableList.length) {
    var nameSuffix = 1;
    var letters = 'ijkmnopqrstuvwxyzabcdefgh';  // No 'l'.
    var letterIndex = 0;
    var potName = letters.charAt(letterIndex);
    while (!newName) {
      var inUse = false;
      for (var i = 0; i < variableList.length; i++) {
        if (variableList[i].name.toLowerCase() == potName) {
          // This potential name is already used.
          inUse = true;
          break;
        }
      }
      if (inUse) {
        // Try the next potential name.
        letterIndex++;
        if (letterIndex == letters.length) {
          // Reached the end of the character sequence so back to 'i'.
          // a new suffix.
          letterIndex = 0;
          nameSuffix++;
        }
        potName = letters.charAt(letterIndex);
        if (nameSuffix > 1) {
          potName += nameSuffix;
        }
      } else {
        // We can use the current potential name.
        newName = potName;
      }
    }
  } else {
    newName = 'i';
  }
  return newName;
};

/**
 * Create a new variable on the given workspace.
 * @param {!Blockly.Workspace} workspace The workspace on which to create the
 *     variable.
 * @param {function(?string=)=} opt_callback A callback. It will
 *     be passed an acceptable new variable name, or null if change is to be
 *     aborted (cancel button), or undefined if an existing variable was chosen.
 * @param {string} opt_type Optional type of variable, like 'string' or 'list'.
 */
Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
  // This function needs to be named so it can be called recursively.
  var promptAndCheckWithAlert = function(defaultName) {
    Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE, defaultName,
      function(text) {
        if (text) {
          if (workspace.getVariable(text)) {
            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS.replace('%1',
                text.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(text);  // Recurse
                });
          }
          else if (!Blockly.Procedures.isNameUsed(text, workspace)) {
            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                text.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(text);  // Recurse
                });
          }
          else {
            var variable = workspace.createVariable(text, opt_type);

            var flyout = workspace.getFlyout();
            var variableBlockId = variable.getId();
            if (flyout.setCheckboxState) {
              flyout.setCheckboxState(variableBlockId, true);
            }

            if (opt_callback) {
              opt_callback(text);
            }
          }
        } else {
          // User canceled prompt without a value.
          if (opt_callback) {
            opt_callback(null);
          }
        }
      });
  };
  promptAndCheckWithAlert('');
};

/**
 * Rename a variable with the given workspace, variableType, and oldName.
 * @param {!Blockly.Workspace} workspace The workspace on which to rename the
 *     variable.
 * @param {?Blockly.VariableModel} variable Variable to rename.
 * @param {function(?string=)=} opt_callback A callback. It will
 *     be passed an acceptable new variable name, or null if change is to be
 *     aborted (cancel button), or undefined if an existing variable was chosen.
 */
Blockly.Variables.renameVariable = function(workspace, variable,
  opt_callback) {
  // This function needs to be named so it can be called recursively.
  var promptAndCheckWithAlert = function(defaultName) {
    Blockly.Variables.promptName(
      Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', variable.name), defaultName,
      function(newName) {
        if (newName) {
          var newVariable = workspace.getVariable(newName);
          if (newVariable && newVariable.type != variable.type) {
            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE.replace('%1',
                newName.toLowerCase()).replace('%2', newVariable.type),
                function() {
                  promptAndCheckWithAlert(newName);  // Recurse
                });
          }
          else if (!Blockly.Procedures.isNameUsed(newName, workspace)) {
            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                newName.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(newName);  // Recurse
                });
          }
          else {
            workspace.renameVariable(variable.name, newName);
            if (opt_callback) {
              opt_callback(newName);
            }
          }
        } else {
          // User canceled prompt without a value.
          if (opt_callback) {
            opt_callback(null);
          }
        }
      });
  };
  promptAndCheckWithAlert('');
};

/**
 * Prompt the user for a new variable name.
 * @param {string} promptText The string of the prompt.
 * @param {string} defaultText The default value to show in the prompt's field.
 * @param {function(?string)} callback A callback. It will be passed the new
 *     variable name, or null if the user picked something illegal.
 */
Blockly.Variables.promptName = function(promptText, defaultText, callback) {
  Blockly.prompt(promptText, defaultText, function(newVar) {
    // Merge runs of whitespace.  Strip leading and trailing whitespace.
    // Beyond this, all names are legal.
    if (newVar) {
      newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
      if (newVar == Blockly.Msg.RENAME_VARIABLE ||
          newVar == Blockly.Msg.NEW_VARIABLE) {
        // Ok, not ALL names are legal...
        newVar = null;
      }
    }
    callback(newVar);
  });
};

/**
 * Generate XML string for variable field.
 * @param {!Blockly.VariableModel} variableModel The variable model to generate
 *     an XML string from.
 * @param {?string} opt_name The optional name of the field, such as "VARIABLE"
 *     or "LIST". Defaults to "VARIABLE".
 * @return {string} The generated XML.
 * @private
 */
Blockly.Variables.generateVariableFieldXml_ = function(variableModel, opt_name) {
  var name = opt_name || "VARIABLE";
  var xmlString = '<field name="' + name + '" ' + 'variableType="' +
      variableModel.type + '" id="' + variableModel.getId() + '">'+
      variableModel.name +
      '</field>';
  return xmlString;
};
<commit_msg>Escape variable names correctly when serializing to XML (#1279)<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Utility functions for handling variables.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

/**
 * @name Blockly.Variables
 * @namespace
 **/
goog.provide('Blockly.Variables');

goog.require('Blockly.Blocks');
goog.require('Blockly.constants');
goog.require('Blockly.VariableModel');
goog.require('Blockly.Workspace');
goog.require('goog.string');

/**
 * Constant to separate variable names from procedures and generated functions
 * when running generators.
 * @deprecated Use Blockly.VARIABLE_CATEGORY_NAME
 */
Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME;

/**
 * Find all user-created variables that are in use in the workspace.
 * For use by generators.
 * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
 * @return {!Array.<string>} Array of variable names.
 */
Blockly.Variables.allUsedVariables = function(root) {
  var blocks;
  if (root instanceof Blockly.Block) {
    // Root is Block.
    blocks = root.getDescendants();
  } else if (root instanceof Blockly.Workspace ||
      root instanceof Blockly.WorkspaceSvg) {
    // Root is Workspace.
    blocks = root.getAllBlocks();
  } else {
    throw 'Not Block or Workspace: ' + root;
  }

  var ignorableName = Blockly.Variables.noVariableText();

  var variableHash = Object.create(null);
  // Iterate through every block and add each variable to the hash.
  for (var x = 0; x < blocks.length; x++) {
    var blockVariables = blocks[x].getVars();
    if (blockVariables) {
      for (var y = 0; y < blockVariables.length; y++) {
        var varName = blockVariables[y];
        // Variable name may be null if the block is only half-built.
        if (varName && varName.toLowerCase() != ignorableName) {
          variableHash[varName.toLowerCase()] = varName;
        }
      }
    }
  }
  // Flatten the hash into a list.
  var variableList = [];
  for (var name in variableHash) {
    variableList.push(variableHash[name]);
  }
  return variableList;
};

/**
 * Find all variables that the user has created through the workspace or
 * toolbox.  For use by generators.
 * @param {!Blockly.Workspace} root The workspace to inspect.
 * @return {!Array.<Blockly.VariableModel>} Array of variable models.
 */
Blockly.Variables.allVariables = function(root) {
  if (root instanceof Blockly.Block) {
    // Root is Block.
    console.warn('Deprecated call to Blockly.Variables.allVariables ' +
                 'with a block instead of a workspace.  You may want ' +
                 'Blockly.Variables.allUsedVariables');
    return {};
  }
  return root.getAllVariables();
};

/**
 * Create a dom element for a value tag with the given name attribute.
 * @param {string} name The value to use for the name attribute.
 * @return {!Element} An XML element: <value name="name"></value>
 */
Blockly.Variables.createValueDom_ = function(name) {
  var value = goog.dom.createDom('value');
  value.setAttribute('name', name);
  return value;
};

/**
 * Create a dom element for a shadow tag with the given tupe attribute.
 * @param {string} type The value to use for the type attribute.
 * @param {string} value The value to have inside the tag.
 * @return {!Element} An XML element: <shadow type="type">value</shadow>
 */
Blockly.Variables.createShadowDom_ = function(type) {
  var shadow = goog.dom.createDom('shadow');
  shadow.setAttribute('type', type);
  return shadow;
};

/**
 * Create a dom element for variable.
 * @param {Blockly.VariableModel} variableModel The variable to use.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createVariableDom_ = function(variableModel) {
  // <field name="VARIABLE">
  //   variablename
  // </field>
  var field = goog.dom.createDom('field', null, variableModel.name);
  field.setAttribute('name', 'VARIABLE');
  field.setAttribute('variableType', variableModel.type);
  field.setAttribute('id', variableModel.getId());
  return field;
};

/**
 * Create a dom element for value tag with a shadow text inside.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createTextDom_ = function() {
  //   <value name="VALUE">
  //     <shadow type="text">
  //       <field name="TEXT">0</field>
  //     </shadow>
  //   </value>
  var value = Blockly.Variables.createValueDom_('VALUE');
  var shadow = Blockly.Variables.createShadowDom_('text');
  var field = goog.dom.createDom('field', null, '0');
  field.setAttribute('name', 'TEXT');
  shadow.appendChild(field);
  value.appendChild(shadow);
  return value;
};

/**
 * Create a dom element for value tag with a shadow number inside.
 * @return {!Element} An XML element.
 */
Blockly.Variables.createMathNumberDom_ = function() {
  //   <value name="VALUE">
  //     <shadow type="math_number">
  //       <field name="NUM">0</field>
  //     </shadow>
  //   </value>
  var value = Blockly.Variables.createValueDom_('VALUE');
  var shadow = Blockly.Variables.createShadowDom_('math_number');
  var field = goog.dom.createDom('field', null, '1');
  field.setAttribute('name', 'NUM');
  shadow.appendChild(field);
  value.appendChild(shadow);
  return value;
};

/**
 * Return the text that should be used in a field_variable or
 * field_variable_getter when no variable exists.
 * TODO: #572
 * @return {string} The text to display.
 */
Blockly.Variables.noVariableText = function() {
  return "No variable selected";
};

/**
* Return a new variable name that is not yet being used. This will try to
* generate single letter variable names in the range 'i' to 'z' to start with.
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
* then 'i2' to 'z2' etc.  Skip 'l'.
 * @param {!Blockly.Workspace} workspace The workspace to be unique in.
* @return {string} New variable name.
*/
Blockly.Variables.generateUniqueName = function(workspace) {
  var variableList = workspace.getAllVariables();
  var newName = '';
  if (variableList.length) {
    var nameSuffix = 1;
    var letters = 'ijkmnopqrstuvwxyzabcdefgh';  // No 'l'.
    var letterIndex = 0;
    var potName = letters.charAt(letterIndex);
    while (!newName) {
      var inUse = false;
      for (var i = 0; i < variableList.length; i++) {
        if (variableList[i].name.toLowerCase() == potName) {
          // This potential name is already used.
          inUse = true;
          break;
        }
      }
      if (inUse) {
        // Try the next potential name.
        letterIndex++;
        if (letterIndex == letters.length) {
          // Reached the end of the character sequence so back to 'i'.
          // a new suffix.
          letterIndex = 0;
          nameSuffix++;
        }
        potName = letters.charAt(letterIndex);
        if (nameSuffix > 1) {
          potName += nameSuffix;
        }
      } else {
        // We can use the current potential name.
        newName = potName;
      }
    }
  } else {
    newName = 'i';
  }
  return newName;
};

/**
 * Create a new variable on the given workspace.
 * @param {!Blockly.Workspace} workspace The workspace on which to create the
 *     variable.
 * @param {function(?string=)=} opt_callback A callback. It will
 *     be passed an acceptable new variable name, or null if change is to be
 *     aborted (cancel button), or undefined if an existing variable was chosen.
 * @param {string} opt_type Optional type of variable, like 'string' or 'list'.
 */
Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
  // This function needs to be named so it can be called recursively.
  var promptAndCheckWithAlert = function(defaultName) {
    Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE, defaultName,
      function(text) {
        if (text) {
          if (workspace.getVariable(text)) {
            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS.replace('%1',
                text.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(text);  // Recurse
                });
          }
          else if (!Blockly.Procedures.isNameUsed(text, workspace)) {
            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                text.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(text);  // Recurse
                });
          }
          else {
            var variable = workspace.createVariable(text, opt_type);

            var flyout = workspace.getFlyout();
            var variableBlockId = variable.getId();
            if (flyout.setCheckboxState) {
              flyout.setCheckboxState(variableBlockId, true);
            }

            if (opt_callback) {
              opt_callback(text);
            }
          }
        } else {
          // User canceled prompt without a value.
          if (opt_callback) {
            opt_callback(null);
          }
        }
      });
  };
  promptAndCheckWithAlert('');
};

/**
 * Rename a variable with the given workspace, variableType, and oldName.
 * @param {!Blockly.Workspace} workspace The workspace on which to rename the
 *     variable.
 * @param {?Blockly.VariableModel} variable Variable to rename.
 * @param {function(?string=)=} opt_callback A callback. It will
 *     be passed an acceptable new variable name, or null if change is to be
 *     aborted (cancel button), or undefined if an existing variable was chosen.
 */
Blockly.Variables.renameVariable = function(workspace, variable,
  opt_callback) {
  // This function needs to be named so it can be called recursively.
  var promptAndCheckWithAlert = function(defaultName) {
    Blockly.Variables.promptName(
      Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', variable.name), defaultName,
      function(newName) {
        if (newName) {
          var newVariable = workspace.getVariable(newName);
          if (newVariable && newVariable.type != variable.type) {
            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE.replace('%1',
                newName.toLowerCase()).replace('%2', newVariable.type),
                function() {
                  promptAndCheckWithAlert(newName);  // Recurse
                });
          }
          else if (!Blockly.Procedures.isNameUsed(newName, workspace)) {
            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                newName.toLowerCase()),
                function() {
                  promptAndCheckWithAlert(newName);  // Recurse
                });
          }
          else {
            workspace.renameVariable(variable.name, newName);
            if (opt_callback) {
              opt_callback(newName);
            }
          }
        } else {
          // User canceled prompt without a value.
          if (opt_callback) {
            opt_callback(null);
          }
        }
      });
  };
  promptAndCheckWithAlert('');
};

/**
 * Prompt the user for a new variable name.
 * @param {string} promptText The string of the prompt.
 * @param {string} defaultText The default value to show in the prompt's field.
 * @param {function(?string)} callback A callback. It will be passed the new
 *     variable name, or null if the user picked something illegal.
 */
Blockly.Variables.promptName = function(promptText, defaultText, callback) {
  Blockly.prompt(promptText, defaultText, function(newVar) {
    // Merge runs of whitespace.  Strip leading and trailing whitespace.
    // Beyond this, all names are legal.
    if (newVar) {
      newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
      if (newVar == Blockly.Msg.RENAME_VARIABLE ||
          newVar == Blockly.Msg.NEW_VARIABLE) {
        // Ok, not ALL names are legal...
        newVar = null;
      }
    }
    callback(newVar);
  });
};

/**
 * Generate XML string for variable field.
 * @param {!Blockly.VariableModel} variableModel The variable model to generate
 *     an XML string from.
 * @param {?string} opt_name The optional name of the field, such as "VARIABLE"
 *     or "LIST". Defaults to "VARIABLE".
 * @return {string} The generated XML.
 * @private
 */
Blockly.Variables.generateVariableFieldXml_ = function(variableModel, opt_name) {
  // The variable name may be user input, so it may contain characters that need
  // to be escaped to create valid XML.
  var element = goog.dom.createDom('field');
  element.setAttribute('name', opt_name || 'VARIABLE');
  element.setAttribute('variableType', variableModel.type);
  element.setAttribute('id', variableModel.getId());
  element.textContent = variableModel.name;

  var xmlString = Blockly.Xml.domToText(element);
  return xmlString;
};
<|endoftext|>


<commit_before>(function () {

	// get uri
	var nick = URI(window.location).query(true).nick;
	var opponent = URI(window.location).query(true).opponent;

	var address = DOMAIN + ":" + PORT.toString();

	var isAttacker = undefined;

	// disable 'My Ships'
	for (var i = 0; i < 100; i++) {
		$($("#nick table button")[i]).addClass("disabled");
	}

	// disable 'Enemy Ships'
	for (var i = 0; i < 100; i++) {
		$($("#opponent table button")[i]).addClass("disabled");
	}

	// local battle
	var battle = {};

	// DOM
	var nick_map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
	opponent_map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];

	// download battle on the beginning of game
	$.ajax({
		type: "GET",
		url: address + "/getBattle",
		dataType: "jsonp",
		data: {
			nick: nick,
			opponent: opponent
		},
		success: function (res) {
			// add data to local objects
			var att = new Player(res.attacker.nick, res.attacker.status, res.attacker.set),
				def = new Player(res.defender.nick, res.defender.status, res.defender.set);

			battle = new Battle(res.attacker.nick, res.defender.nick, [att, def]);

			// bring back ints
			for (var i = 0; i < 10; i++)
				for (var j = 0; j < 10; j++){
					battle.attacker.set.map[i][j] = parseInt(battle.attacker.set.map[i][j]);
					battle.defender.set.map[i][j] = parseInt(battle.defender.set.map[i][j]);
				}

			// update isAttacker
			(battle.attacker.nick == nick) ? isAttacker = true : isAttacker = false;

			// get DOM
			for (var i = 0, x = 0; i < 10; i++)
				for (var j = 0; j < 10; j++, x++)
					nick_map[i][j] = ($($("#nick button")[x]));

			for (var i = 0, x = 0; i < 10; i++)
				for (var j = 0; j < 10; j++, x++)
					opponent_map[i][j] = ($($("#opponent button")[x]));

			// map ships on map
			if(isAttacker){
				// map nick ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.attacker.set.map[i][j] == 1)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-stop");
						else if(battle.attacker.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.attacker.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");

				// map opponent ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.defender.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.defender.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");

			}
			else{
				// map nick ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.defender.set.map[i][j] == 1)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-stop");
						else if(battle.defender.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.defender.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");

				// map opponent ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.attacker.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.attacker.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");
			}

			// check if my turn
			if(isAttacker && battle.turn%2 == 0)
				for (var i = 0; i < 100; i++)
					$($("#opponent table button")[i]).removeClass("disabled");

			else if(!isAttacker && battle.turn%2 == 1)
				for (var i = 0; i < 100; i++)
					$($("#opponent table button")[i]).removeClass("disabled");

		},
		error: function (error) {
			alert("An error occured while connecting to server. See log for details.");
			console.log(error);
		}
	});

	// attack listener
	$("#opponent button").on("click", function () {

		var x = $(this).data().x,
			y = $(this).data().y;

		// attack locally
		//0 empty space
		//1 ship
		//2 killed ship
		//3 missed shot
		switch( isAttacker ? battle.defender.attackedBy(battle.attacker, x, y) : battle.attacker.attackedBy(battle.defender, x, y)){
			case 0:	// miss
				$($(this).context.firstChild).addClass("glyphicon-certificate");

				// disable 'Enemy Ships'
				for (var i = 0; i < 100; i++) {
					$($("#opponent table button")[i]).addClass("disabled");
				}
				break;
			case 1:	// ship hit
				$($(this).context.firstChild).addClass("glyphicon-remove");

				// disable 'Enemy Ships'
				for (var i = 0; i < 100; i++) {
					$($("#opponent table button")[i]).addClass("disabled");
				}
				break;
			case 2:	// already hit
				alert("You can't shoot in the same place again!");
				break;
			case 3:	// already missed
				alert("You can't miss in the same place again!");
				break;
		}

		// increse turn
		battle.turn = parseInt(battle.turn)+1;

		// send updated battle object to server
		$.ajax({
			type: "POST",
			url: address + "/attack",
			dataType: "jsonp",
			data: battle,
			success: function (res) {
				if(!res)
					alert("No such battle is currently existing in database");
			},
			error: function (error) {
				alert("An error occured while connecting to server. See log for details.");
				console.log(error);
			}
		});

	});

	// refresh button
	// ...

})();<commit_msg>Few bugs fixed<commit_after>(function () {

	// get uri
	var nick = URI(window.location).query(true).nick;
	var opponent = URI(window.location).query(true).opponent;

	var address = DOMAIN + ":" + PORT.toString();

	var isAttacker = undefined;

	// disable 'My Ships'
	for (var i = 0; i < 100; i++) {
		$($("#nick table button")[i]).addClass("disabled");
	}

	// disable 'Enemy Ships'
	for (var i = 0; i < 100; i++) {
		$($("#opponent table button")[i]).addClass("disabled");
	}

	// local battle
	var battle = {};

	// DOM
	var nick_map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
	opponent_map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
					[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];

	// download battle on the beginning of game
	$.ajax({
		type: "GET",
		url: address + "/getBattle",
		dataType: "jsonp",
		data: {
			nick: nick,
			opponent: opponent
		},
		success: function (res) {
			// add data to local objects
			var att = new Player(res.attacker.nick, res.attacker.status, res.attacker.set),
				def = new Player(res.defender.nick, res.defender.status, res.defender.set);

			battle = new Battle(res.attacker.nick, res.defender.nick, [att, def]);

			battle.turn = parseInt(res.turn);

			// bring back ints
			for (var i = 0; i < 10; i++)
				for (var j = 0; j < 10; j++){
					battle.attacker.set.map[i][j] = parseInt(battle.attacker.set.map[i][j]);
					battle.defender.set.map[i][j] = parseInt(battle.defender.set.map[i][j]);
				}

			// update isAttacker
			(battle.attacker.nick == nick) ? isAttacker = true : isAttacker = false;

			// get DOM
			for (var i = 0, x = 0; i < 10; i++)
				for (var j = 0; j < 10; j++, x++)
					nick_map[i][j] = ($($("#nick button")[x]));

			for (var i = 0, x = 0; i < 10; i++)
				for (var j = 0; j < 10; j++, x++)
					opponent_map[i][j] = ($($("#opponent button")[x]));

			// map ships on map
			if(isAttacker){
				// map nick ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.attacker.set.map[i][j] == 1)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-stop");
						else if(battle.attacker.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.attacker.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");

				// map opponent ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.defender.set.map[i][j] == 2)
							$(opponent_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.defender.set.map[i][j] == 3)
							$(opponent_map[i][j].context.firstChild).addClass("glyphicon-certificate");

			}
			else{
				// map nick ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.defender.set.map[i][j] == 1)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-stop");
						else if(battle.defender.set.map[i][j] == 2)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.defender.set.map[i][j] == 3)
							$(nick_map[i][j].context.firstChild).addClass("glyphicon-certificate");

				// map opponent ships
				for (var i = 0; i < 10; i++)
					for (var j = 0; j < 10; j++)
						if(battle.attacker.set.map[i][j] == 2)
							$(opponent_map[i][j].context.firstChild).addClass("glyphicon-remove");
						else if(battle.attacker.set.map[i][j] == 3)
							$(opponent_map[i][j].context.firstChild).addClass("glyphicon-certificate");
			}

			// check if my turn
			if(isAttacker && battle.turn%2 == 0)
				for (var i = 0; i < 100; i++)
					$($("#opponent table button")[i]).removeClass("disabled");

			else if(!isAttacker && battle.turn%2 == 1)
				for (var i = 0; i < 100; i++)
					$($("#opponent table button")[i]).removeClass("disabled");

		},
		error: function (error) {
			alert("An error occured while connecting to server. See log for details.");
			console.log(error);
		}
	});

	// attack listener
	$("#opponent button").on("click", function () {

		var x = $(this).data().x,
			y = $(this).data().y;

		// attack locally
		//0 empty space
		//1 ship
		//2 killed ship
		//3 missed shot

		var didCorrectShot = false, canHitAgain = false;

		while(!didCorrectShot){
			switch( isAttacker ? battle.defender.attackedBy(battle.attacker, x, y) : battle.attacker.attackedBy(battle.defender, x, y)){
				case 0:	// miss
					$($(this).context.firstChild).addClass("glyphicon-certificate");

					// disable 'Enemy Ships'
					for (var i = 0; i < 100; i++) {
						$($("#opponent table button")[i]).addClass("disabled");
					}
					didCorrectShot = true;
					break;
				case 1:	// ship hit
					$($(this).context.firstChild).addClass("glyphicon-remove");

					// disable 'Enemy Ships'
					for (var i = 0; i < 100; i++) {
						$($("#opponent table button")[i]).addClass("disabled");
					}
					didCorrectShot = true;
					canHitAgain = true;
					break;
				case 2:	// already hit
					alert("You can't shoot in the same place again!");
					break;
				case 3:	// already missed
					alert("You can't miss in the same place again!");
					break;
			}
		}

		// increse turn
		if(!canHitAgain)
			battle.turn = parseInt(battle.turn)+1;

		// send updated battle object to server
		$.ajax({
			type: "POST",
			url: address + "/attack",
			dataType: "jsonp",
			data: battle,
			success: function (res) {
				if(!res)
					alert("No such battle is currently existing in database");
			},
			error: function (error) {
				alert("An error occured while connecting to server. See log for details.");
				console.log(error);
			}
		});

	});

	// refresh button
	// ...

})();<|endoftext|>


<commit_before>var util = require('util'),
    SearchBuilder = require('./searchBuilder'),
    ConditionBuilder = require('./conditionBuilder'),
    Field = require('./field');

// Query fields
var QUERY_PAGE_START = 'iDisplayStart';
var QUERY_PAGE_SIZE = 'iDisplayLength';
var QUERY_NB_COLUMNS = 'iColumns';
var QUERY_FIELD_PREFIX = 'mDataProp_';
var QUERY_SEARCHABLE_PREFIX = 'bSearchable_';
var QUERY_SORTING_COLUMNS = 'iSortingCols';
var QUERY_SORTABLE_PREFIX = 'bSortable_';
var QUERY_SORT_COLUMN_PREFIX = 'iSortCol_';
var QUERY_SORT_DIRECTION_PREFIX = 'sSortDir_';
var QUERY_SORTING_COLUMNS = 'iSortingCols';
var QUERY_SORT_COLUMN_PREFIX = 'iSortCol_';
var QUERY_SORT_DIRECTION_PREFIX = 'sSortDir_';

module.exports = function SearchCriteria(model, query, options) {
  var options = options;
  var pageStart = getPageStart(query);
  var pageSize = getPageSize(query);
  var nbColumns = getNbColumns(query);
  SearchBuilder.initialize(query);
  var search = SearchBuilder.getOverallSearch();
  var sorts = getSorts(query);
  var fields = [];
  loadFields(model, query, nbColumns, sorts, fields);
  var select = {};
  var sort = {};
  var conditions;
  var populate = [];
  var aggregates = [];

  Object.defineProperty(this, "options", {
    writable: false, enumerable: true, value: options });

  Object.defineProperty(this, "pageStart", {
    writable: false, enumerable: true, value: pageStart });

  Object.defineProperty(this, "pageSize", {
    writable: false, enumerable: true, value: pageSize });

  Object.defineProperty(this, "nbColumns", {
    writable: false, enumerable: true, value: nbColumns });

  Object.defineProperty(this, "search", {
    writable: false, enumerable: true, value: search });

  Object.defineProperty(this, "fields", {
    writable: false, enumerable: true, value: fields });

  Object.defineProperty(this, "select", {
    enumerable: true,
    get: function() { return select; },
    set: function(value) { select = value; }
  });

  Object.defineProperty(this, "isSelectEmpty", {
    enumerable: true,
    value: function() { return !select || Object.keys(select).length == 0; }
  });

  Object.defineProperty(this, "sort", {
    enumerable: true,
    get: function() { return sort; },
    set: function(value) { sort = value; }
  });

  Object.defineProperty(this, "conditions", {
    enumerable: true,
    get: function() { return conditions; },
    set: function(value) { conditions = value; }
  });

  Object.defineProperty(this, "populate", {
    enumerable: true,
    get: function() { return populate; },
    set: function(value) { populate = value; }
  });

  Object.defineProperty(this, "aggregates", {
    enumerable: true,
    get: function() { return aggregates; },
    set: function(value) { aggregates = value; }
  });

  Object.defineProperty(this, "data", {
    enumerable: true,
    get: function() {
      var data = { options: options, pageStart: pageStart, pageSize: pageSize,
        nbColumns: nbColumns, search: search, fields: [], select: select,
        sort: sort, conditions: conditions, populate: populate };
      for (var index = 0; index < fields.length; ++index) {
        data.fields.push(fields[index]);
      }
      return data;
    }
  });

  Object.defineProperty(this, "toString", {
    enumerable: false,
    value: function() {
      return util.inspect(this.data, false, null, true);
    }
  });

  load(this);
}

function getPageStart(query) {
  return parseInt(query[QUERY_PAGE_START] || 0);
}

function getPageSize(query) {
  return parseInt(query[QUERY_PAGE_SIZE] || 0);
}

function getNbColumns(query) {
  return parseInt(query[QUERY_NB_COLUMNS] || 0);
}

function getSorts(query) {
  var sortables = [];
  var nbSortingCols = parseInt(query[QUERY_SORTING_COLUMNS]);
  while (--nbSortingCols >= 0) {
    var index = parseInt(query[
        util.format("%s%s", QUERY_SORT_COLUMN_PREFIX, nbSortingCols)]);
    var dir = query[util.format("%s%s", QUERY_SORT_DIRECTION_PREFIX,
        nbSortingCols)];
    sortables[index] = { dir: dir, precedence: nbSortingCols };
  }
  return sortables;
}

function loadFields(model, query, nbColumns, sorts, fields) {
  for (var index = 0; index < nbColumns; ++index) {
    try {
      fields.push(new Field(model, query, sorts, index));
    } catch(err) { Tools.verbose('Field %s error', err); }
  }
}

function load(searchCriteria) {
  var conjunctions = [];
  var disjunctions = [];
  if (searchCriteria.options.conditions) {
    conjunctions.push(searchCriteria.options.conditions);
  }
  searchCriteria.fields.forEach(function(field) {
    if (field.sortable && field.sort) addSort(searchCriteria, field);
    if (field.selectable) addSelect(searchCriteria, field);
    if (field.ref || field.base) addPopulate(searchCriteria, field);
    if (field.searchable && field.base == undefined) {
      addConditions(searchCriteria, field, conjunctions, disjunctions);
    }
  });
  if (disjunctions.length > 0) {
    conjunctions.push(ConditionBuilder.buildDisjunction(disjunctions));
  }
  if (conjunctions.length > 0) {
    searchCriteria.conditions = ConditionBuilder.buildConjunction(conjunctions);
  }
}

function addSort(searchCriteria, field) {
  searchCriteria.sort[field.path] = field.sort.dir;
}

function addSelect(searchCriteria, field) {
  var path = field.base ? field.base[0] : field.path;
  if (searchCriteria.select[path] == undefined) {
    searchCriteria.select[path] = 1;
  }
}

function addPopulate(searchCriteria, field) {
  var path, populate;
  if (field.base && field.base.length > 0) {
    path = "";
    field.base.forEach(function(base) {
      if (path.length > 0) path += PATH_SEPARATOR;
      path += base;
    });
  } else path = field.path;
  var select = field.path.substring(path.length + 1);
  for (var index = 0; index < searchCriteria.populate.length; ++index) {
    populate = searchCriteria.populate[index];
    if (populate && populate.path == path) {
      break;
    }
  }
  if (index >= searchCriteria.populate.length) {
    populate = { path: path, sort: {} };
    if (field.base) {
      populate.select = select;
    }
    searchCriteria.populate.push(populate);
  } else if (populate.select) {
    if (populate.select.indexOf(field.path) == -1) {
      populate.select += select + " ";
    }
  }
  if (field.sort) populate.sort[select] = field.sort.dir;
}

function addConditions(searchCriteria, field, conjunctions, disjunctions) {
  var condition = ConditionBuilder.getGeneralSearch(field,
      searchCriteria.search, searchCriteria.options);
  if (condition) {
    var element = {};
    element[field.path] = condition;
    disjunctions.push(element);
  }
  condition = ConditionBuilder.getFieldSearch(field, searchCriteria.options);
  if (condition) {
    var element = {};
    element[field.path] = condition;
    conjunctions.push(element);
    if (field.arrayPath) addAggregate(searchCriteria, field, condition);
  }
}

function addAggregate(searchCriteria, field, condition) {
  var group = { _id: { _id: '$_id' } };
  group[field.arrayPath] = { $push: '$'+field.arrayPath };
  var project = { _id: '$_id._id' };
  project[field.arrayPath] = 1;
  searchCriteria.fields.forEach(function(f) {
    if (f == field) return;
    if (f.path.indexOf(field.arrayPath+'.') == 0) return;
    group._id[f.base || f.arrayPath || f.path] = '$'+(f.base || f.path);
    project[f.base || f.path] = '$_id.'+(f.base || f.path);
  });
  var aggregate = {};
  aggregate.unwind = field.arrayPath;
  aggregate.match = {};
  aggregate.match[field.path] = condition;
  aggregate.group = group;
  aggregate.project = project;
  searchCriteria.aggregates.push(aggregate);
}

<commit_msg>fix missing module<commit_after>var util = require('util'),
    Tools = require('./tools'),
    SearchBuilder = require('./searchBuilder'),
    ConditionBuilder = require('./conditionBuilder'),
    Field = require('./field');

// Query fields
var QUERY_PAGE_START = 'iDisplayStart';
var QUERY_PAGE_SIZE = 'iDisplayLength';
var QUERY_NB_COLUMNS = 'iColumns';
var QUERY_FIELD_PREFIX = 'mDataProp_';
var QUERY_SEARCHABLE_PREFIX = 'bSearchable_';
var QUERY_SORTING_COLUMNS = 'iSortingCols';
var QUERY_SORTABLE_PREFIX = 'bSortable_';
var QUERY_SORT_COLUMN_PREFIX = 'iSortCol_';
var QUERY_SORT_DIRECTION_PREFIX = 'sSortDir_';
var QUERY_SORTING_COLUMNS = 'iSortingCols';
var QUERY_SORT_COLUMN_PREFIX = 'iSortCol_';
var QUERY_SORT_DIRECTION_PREFIX = 'sSortDir_';

module.exports = function SearchCriteria(model, query, options) {
  var options = options;
  var pageStart = getPageStart(query);
  var pageSize = getPageSize(query);
  var nbColumns = getNbColumns(query);
  SearchBuilder.initialize(query);
  var search = SearchBuilder.getOverallSearch();
  var sorts = getSorts(query);
  var fields = [];
  loadFields(model, query, nbColumns, sorts, fields);
  var select = {};
  var sort = {};
  var conditions;
  var populate = [];
  var aggregates = [];

  Object.defineProperty(this, "options", {
    writable: false, enumerable: true, value: options });

  Object.defineProperty(this, "pageStart", {
    writable: false, enumerable: true, value: pageStart });

  Object.defineProperty(this, "pageSize", {
    writable: false, enumerable: true, value: pageSize });

  Object.defineProperty(this, "nbColumns", {
    writable: false, enumerable: true, value: nbColumns });

  Object.defineProperty(this, "search", {
    writable: false, enumerable: true, value: search });

  Object.defineProperty(this, "fields", {
    writable: false, enumerable: true, value: fields });

  Object.defineProperty(this, "select", {
    enumerable: true,
    get: function() { return select; },
    set: function(value) { select = value; }
  });

  Object.defineProperty(this, "isSelectEmpty", {
    enumerable: true,
    value: function() { return !select || Object.keys(select).length == 0; }
  });

  Object.defineProperty(this, "sort", {
    enumerable: true,
    get: function() { return sort; },
    set: function(value) { sort = value; }
  });

  Object.defineProperty(this, "conditions", {
    enumerable: true,
    get: function() { return conditions; },
    set: function(value) { conditions = value; }
  });

  Object.defineProperty(this, "populate", {
    enumerable: true,
    get: function() { return populate; },
    set: function(value) { populate = value; }
  });

  Object.defineProperty(this, "aggregates", {
    enumerable: true,
    get: function() { return aggregates; },
    set: function(value) { aggregates = value; }
  });

  Object.defineProperty(this, "data", {
    enumerable: true,
    get: function() {
      var data = { options: options, pageStart: pageStart, pageSize: pageSize,
        nbColumns: nbColumns, search: search, fields: [], select: select,
        sort: sort, conditions: conditions, populate: populate };
      for (var index = 0; index < fields.length; ++index) {
        data.fields.push(fields[index]);
      }
      return data;
    }
  });

  Object.defineProperty(this, "toString", {
    enumerable: false,
    value: function() {
      return util.inspect(this.data, false, null, true);
    }
  });

  load(this);
}

function getPageStart(query) {
  return parseInt(query[QUERY_PAGE_START] || 0);
}

function getPageSize(query) {
  return parseInt(query[QUERY_PAGE_SIZE] || 0);
}

function getNbColumns(query) {
  return parseInt(query[QUERY_NB_COLUMNS] || 0);
}

function getSorts(query) {
  var sortables = [];
  var nbSortingCols = parseInt(query[QUERY_SORTING_COLUMNS]);
  while (--nbSortingCols >= 0) {
    var index = parseInt(query[
        util.format("%s%s", QUERY_SORT_COLUMN_PREFIX, nbSortingCols)]);
    var dir = query[util.format("%s%s", QUERY_SORT_DIRECTION_PREFIX,
        nbSortingCols)];
    sortables[index] = { dir: dir, precedence: nbSortingCols };
  }
  return sortables;
}

function loadFields(model, query, nbColumns, sorts, fields) {
  for (var index = 0; index < nbColumns; ++index) {
    try {
      fields.push(new Field(model, query, sorts, index));
    } catch(err) { Tools.verbose('Field %s error', err); }
  }
}

function load(searchCriteria) {
  var conjunctions = [];
  var disjunctions = [];
  if (searchCriteria.options.conditions) {
    conjunctions.push(searchCriteria.options.conditions);
  }
  searchCriteria.fields.forEach(function(field) {
    if (field.sortable && field.sort) addSort(searchCriteria, field);
    if (field.selectable) addSelect(searchCriteria, field);
    if (field.ref || field.base) addPopulate(searchCriteria, field);
    if (field.searchable && field.base == undefined) {
      addConditions(searchCriteria, field, conjunctions, disjunctions);
    }
  });
  if (disjunctions.length > 0) {
    conjunctions.push(ConditionBuilder.buildDisjunction(disjunctions));
  }
  if (conjunctions.length > 0) {
    searchCriteria.conditions = ConditionBuilder.buildConjunction(conjunctions);
  }
}

function addSort(searchCriteria, field) {
  searchCriteria.sort[field.path] = field.sort.dir;
}

function addSelect(searchCriteria, field) {
  var path = field.base ? field.base[0] : field.path;
  if (searchCriteria.select[path] == undefined) {
    searchCriteria.select[path] = 1;
  }
}

function addPopulate(searchCriteria, field) {
  var path, populate;
  if (field.base && field.base.length > 0) {
    path = "";
    field.base.forEach(function(base) {
      if (path.length > 0) path += PATH_SEPARATOR;
      path += base;
    });
  } else path = field.path;
  var select = field.path.substring(path.length + 1);
  for (var index = 0; index < searchCriteria.populate.length; ++index) {
    populate = searchCriteria.populate[index];
    if (populate && populate.path == path) {
      break;
    }
  }
  if (index >= searchCriteria.populate.length) {
    populate = { path: path, sort: {} };
    if (field.base) {
      populate.select = select;
    }
    searchCriteria.populate.push(populate);
  } else if (populate.select) {
    if (populate.select.indexOf(field.path) == -1) {
      populate.select += select + " ";
    }
  }
  if (field.sort) populate.sort[select] = field.sort.dir;
}

function addConditions(searchCriteria, field, conjunctions, disjunctions) {
  var condition = ConditionBuilder.getGeneralSearch(field,
      searchCriteria.search, searchCriteria.options);
  if (condition) {
    var element = {};
    element[field.path] = condition;
    disjunctions.push(element);
  }
  condition = ConditionBuilder.getFieldSearch(field, searchCriteria.options);
  if (condition) {
    var element = {};
    element[field.path] = condition;
    conjunctions.push(element);
    if (field.arrayPath) addAggregate(searchCriteria, field, condition);
  }
}

function addAggregate(searchCriteria, field, condition) {
  var group = { _id: { _id: '$_id' } };
  group[field.arrayPath] = { $push: '$'+field.arrayPath };
  var project = { _id: '$_id._id' };
  project[field.arrayPath] = 1;
  searchCriteria.fields.forEach(function(f) {
    if (f == field) return;
    if (f.path.indexOf(field.arrayPath+'.') == 0) return;
    group._id[f.base || f.arrayPath || f.path] = '$'+(f.base || f.path);
    project[f.base || f.path] = '$_id.'+(f.base || f.path);
  });
  var aggregate = {};
  aggregate.unwind = field.arrayPath;
  aggregate.match = {};
  aggregate.match[field.path] = condition;
  aggregate.group = group;
  aggregate.project = project;
  searchCriteria.aggregates.push(aggregate);
}

<|endoftext|>


<commit_before><commit_msg>Updated Icons<commit_after><|endoftext|>


<commit_before>import MJMLElement from './decorators/MJMLElement'
import React, { Component } from 'react'
import _ from 'lodash'
import  { widthParser } from '../helpers/mjAttribute'

/**
 * Columns are the basic containers for your content. They must be located under mj-section tags in order to be considered by the engine
 */
@MJMLElement({
  tagName: 'mj-column'
})
class Column extends Component {

  static baseStyles = {
    td: {
      border: 'none',
      borderSpacing: '0'
    },
    div: {
      verticalAlign: "top"
    }
  };

  getStyles() {
    const { mjAttribute } = this.props

    return _.merge({}, this.constructor.baseStyles, {
      div: {
        display: "inline-block",
        verticalAlign: mjAttribute('vertical-align'),
        fontSize: "13",
        textAlign: "left",
        minWidth: mjAttribute('width')
      }
    })
  }

  getColumnClass() {
    const { mjAttribute, sibling } = this.props
    const width = mjAttribute('width')

    if (width == undefined) {
      return `mj-column-per-${100/sibling}`
    }

    const { width: parsedWidth, unit } = widthParser(width)

    switch(unit) {
      case '%':
        return `mj-column-per-${parsedWidth}`

      case 'px':
      default:
        return `mj-column-px-${parsedWidth}`
    }
  }

  render() {
    const { mjAttribute, renderChildren, sibling } = this.props
    const width = mjAttribute('width') || (100 / sibling)
    const mjColumnClass = this.getColumnClass()

    this.styles = this.getStyles()

    return (

            {renderChildren()}

    )
  }

}

export default Column
<commit_msg>Avoid column-per-33.3333333333333<commit_after>import MJMLElement from './decorators/MJMLElement'
import React, { Component } from 'react'
import _ from 'lodash'
import  { widthParser } from '../helpers/mjAttribute'

/**
 * Columns are the basic containers for your content. They must be located under mj-section tags in order to be considered by the engine
 */
@MJMLElement({
  tagName: 'mj-column'
})
class Column extends Component {

  static baseStyles = {
    td: {
      border: 'none',
      borderSpacing: '0'
    },
    div: {
      verticalAlign: "top"
    }
  };

  getStyles() {
    const { mjAttribute } = this.props

    return _.merge({}, this.constructor.baseStyles, {
      div: {
        display: "inline-block",
        verticalAlign: mjAttribute('vertical-align'),
        fontSize: "13",
        textAlign: "left",
        minWidth: mjAttribute('width')
      }
    })
  }

  getColumnClass() {
    const { mjAttribute, sibling } = this.props
    const width = mjAttribute('width')

    if (width == undefined) {
      return `mj-column-per-${parseInt(100/sibling)}`
    }

    const { width: parsedWidth, unit } = widthParser(width)

    switch(unit) {
      case '%':
        return `mj-column-per-${parsedWidth}`

      case 'px':
      default:
        return `mj-column-px-${parsedWidth}`
    }
  }

  render() {
    const { mjAttribute, renderChildren, sibling } = this.props
    const width = mjAttribute('width') || (100 / sibling)
    const mjColumnClass = this.getColumnClass()

    this.styles = this.getStyles()

    return (

            {renderChildren()}

    )
  }

}

export default Column
<|endoftext|>


<commit_before><commit_msg>switch back to ruby for `heroku apps`<commit_after><|endoftext|>


<commit_before>const _isNumber = require('lodash/isNumber');
const { StyleRoot } = require('radium');
const React = require('react');
const Velocity = require('velocity-animate');
const _throttle = require('lodash/throttle');
const _merge = require('lodash/merge');

const Button = require('../components/Button');

const StyleConstants = require('../constants/Style');

const Drawer = React.createClass({
  propTypes: {
    animateLeftDistance: React.PropTypes.number,
    breakPoints: React.PropTypes.shape({
      large: React.PropTypes.number,
      medium: React.PropTypes.number
    }),
    buttonPrimaryColor: React.PropTypes.string,
    closeOnScrimClick: React.PropTypes.bool,
    contentStyle: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.object
    ]),
    duration: React.PropTypes.number,
    easing: React.PropTypes.array,
    headerMenu: React.PropTypes.element,
    headerStyle: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.object
    ]),
    maxWidth: React.PropTypes.number,
    navConfig: React.PropTypes.shape({
      label: React.PropTypes.string.isRequired,
      onNextClick: React.PropTypes.func.isRequired,
      onPreviousClick: React.PropTypes.func.isRequired
    }),
    onClose: React.PropTypes.func.isRequired,
    showCloseButton: React.PropTypes.bool,
    showScrim: React.PropTypes.bool,
    styles: React.PropTypes.object,
    title: React.PropTypes.string
  },

  getDefaultProps () {
    return {
      buttonPrimaryColor: StyleConstants.Colors.PRIMARY,
      breakPoints: StyleConstants.BreakPoints,
      closeOnScrimClick: true,
      duration: 500,
      easing: [0.28, 0.14, 0.34, 1.04],
      maxWidth: 960,
      showCloseButton: true,
      showScrim: true,
      title: ''
    };
  },

  componentWillMount () {
    this._resizeThrottled = _throttle(this._resize, 100);
  },

  componentDidMount () {
    this._animateComponent({ left: this._getAnimationDistance() });
    window.addEventListener('resize', this._resizeThrottled);
  },

  componentWillUnmount () {
    window.removeEventListener('resize', this._resizeThrottled);
  },

  _getAnimationDistance () {
    if (_isNumber(this.props.animateLeftDistance)) {
      return this.props.animateLeftDistance + '%';
    }

    const windowWidth = window.innerWidth;

    if (windowWidth >= this.props.breakPoints.large) {
      //Resolution - maxWidth
      return windowWidth - this.props.maxWidth;
    } else if (windowWidth <= this.props.breakPoints.medium) {
      //All the way over to the left
      return 0;
    } else {
      //20% from the left
      const newLeft = windowWidth * 0.2;

      return Math.max(newLeft, windowWidth - this.props.maxWidth);
    }
  },

  /**
   * Animate the Drawer closed and then call the onClose callback.
   *
   * @returns {Promise} that is resolved when the animation finishes
   */
  close () {
    return this._animateComponent({ left: '100%' })
      .then(() => {
        this.props.onClose();
      });
  },

  _animateComponent (transition, extraOptions) {
    const el = this._component;
    const options = Object.assign({
      duration: this.props.duration,
      easing: this.props.easing
    }, extraOptions);

    return Velocity(el, transition, options);
  },

  _resize () {
    this._animateComponent({ left: this._getAnimationDistance() }, { duration: 0 });
  },

  _renderNav () {
    const styles = this.styles();

    return (

        <Button
          icon='caret-left'
          onClick={this.props.navConfig.onPreviousClick}
          primaryColor={this.props.buttonPrimaryColor}
          type='base'
        />

          {this.props.navConfig.label}

        <Button
          icon='caret-right'
          onClick={this.props.navConfig.onNextClick}
          primaryColor={this.props.buttonPrimaryColor}
          type='base'
        />

    );
  },

  render () {
    const styles = this.styles();

    return (


<commit_before>import React, { Component, PropTypes } from 'react'
if (process.env.BROWSER) {
      require("./Footer.css");
}

export default class Footer extends Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (

                                關於我們

                                聯絡我們

                                隱私政策

                                贊助我們

                                 除另有註明，網站內容皆採用創用CC姓名標示-非商業性-禁止改作授權條款

                                 github.com/twreporter

        )
    }
}

<commit_msg>add the links in Footer<commit_after>import React, { Component, PropTypes } from 'react'
if (process.env.BROWSER) {
      require("./Footer.css");
}

export default class Footer extends Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (

                                關於我們

                                聯絡我們

                                隱私政策

                                贊助我們

                                 除另有註明，網站內容皆採用創用CC姓名標示-非商業性-禁止改作授權條款

                                 github.com/twreporter

        )
    }
}

<|endoftext|>


<commit_before>import React from 'react';
import { Link } from 'react-router-dom';

import './Footer.css';

export default () => (

Get Involved!

					If you are a parent, educator, school student, university student or industry professional of any age and gender, you can get involved with us. Find out more <Link to="/get-involved">here</Link>!

Follow us!

          Facebook

          Email

Code by Roy Portas

);
<commit_msg>Fixed link to volunteer page<commit_after>import React from 'react';
import { Link } from 'react-router-dom';

import './Footer.css';

export default () => (

Get Involved!

					If you are a parent, educator, school student, university student
          or industry professional of any age and gender,
          you can get involved with us. Find out more <Link to="/volunteer-with-us">here</Link>!

Follow us!

          Facebook

          Email

Code by Roy Portas

);
<|endoftext|>


<commit_before>import  React from 'react';
import { Link } from 'react-router';

const Layout = () => {
    return (

Buen Provecho

Recipes and Chef's on Demand

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

                    <Link className="btn btn-default btn-lg" to="/signup">Sign Up Today!</Link>

Contact Us

                <address>
                    Buen Provecho

123, Main St.

New York, NY 10001

                </address>
                <address>
                    P:(123) 456-7890

                    E: Food@buenprovecho.com
                </address>

Food Photo #1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Cooking Photo #2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Food Photo #3

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

    );
};

 export default Layout;<commit_msg>Modification<commit_after>import  React from 'react';
import { Link } from 'react-router';

const Layout = () => {
    return (

Buen Provecho

Recipes and Chef's on Demand

Heloo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

                    <Link className="btn btn-default btn-lg" to="/signup">Sign Up Today!</Link>

Contact Us

                <address>
                    Buen Provecho

123, Main St.

New York, NY 10001

                </address>
                <address>
                    P:(123) 456-7890

                    E: Food@buenprovecho.com
                </address>

Food Photo #1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Cooking Photo #2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

Food Photo #3

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et molestiae similique eligendi reiciendis sunt distinctio odit? Quia, neque, ipsa, adipisci quisquam ullam deserunt accusantium illo iste exercitationem nemo voluptates asperiores.

    );
};

 export default Layout;<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import TransitionGroup from 'react-addons-css-transition-group';

// These can be overridden by changing the componentClassName prop
import '../../css/styles.css';

const getter = (obj, propName) => (obj.get ? obj.get(propName) : obj[propName]);

import Notif from './Notif';

function Notifs(props) {
  const { notifs, className, componentClassName, CustomComponent, transitionEnterTimeout, transitionLeaveTimeout, onActionClick, actionLabel } = props;

  const items = notifs.map((notif) => (
    <Notif
      key={getter(notif, 'id')}
      id={getter(notif, 'id')}
      message={getter(notif, 'message')}
      kind={getter(notif, 'kind')}
      componentClassName={componentClassName}
      CustomComponent={CustomComponent}
      onActionClick={onActionClick}
      actionLabel={actionLabel}
    />
  ));

  return (
    <div className={`${componentClassName}__container ${className}`} >
      <TransitionGroup
        transitionName={`${componentClassName}-transition`}
        transitionEnterTimeout={transitionEnterTimeout}
        transitionLeaveTimeout={transitionLeaveTimeout}
      >
        {items}
      </TransitionGroup>

  );
}

Notifs.defaultProps = {
  componentClassName: 'notif',
  transitionEnterTimeout: 600,
  transitionLeaveTimeout: 600,
  onActionClick: null,
  action: null,
};

Notifs.propTypes = {
  notifs: React.PropTypes.array,
  className: React.PropTypes.string,
  CustomComponent: React.PropTypes.func,
  componentClassName: React.PropTypes.string,
  transitionEnterTimeout: React.PropTypes.number,
  transitionLeaveTimeout: React.PropTypes.number,
  onActionClick: React.PropTypes.func,
  actionLabel: React.PropTypes.string,
};

export default connect((state) => ({ notifs: state.get ? state.get('notifs') : state.notifs }), {})(Notifs);
<commit_msg>only write className to DOM if it exists<commit_after>import React from 'react';
import { connect } from 'react-redux';
import TransitionGroup from 'react-addons-css-transition-group';

// These can be overridden by changing the componentClassName prop
import '../../css/styles.css';

const getter = (obj, propName) => (obj.get ? obj.get(propName) : obj[propName]);

import Notif from './Notif';

function Notifs(props) {
  const { notifs, className, componentClassName, CustomComponent, transitionEnterTimeout, transitionLeaveTimeout, onActionClick, actionLabel } = props;

  const items = notifs.map((notif) => (
    <Notif
      key={getter(notif, 'id')}
      id={getter(notif, 'id')}
      message={getter(notif, 'message')}
      kind={getter(notif, 'kind')}
      componentClassName={componentClassName}
      CustomComponent={CustomComponent}
      onActionClick={onActionClick}
      actionLabel={actionLabel}
    />
  ));
  const classes = [
    `${componentClassName}__container`,
    className || null
  ].join(' ').split();

  return (

      <TransitionGroup
        transitionName={`${componentClassName}-transition`}
        transitionEnterTimeout={transitionEnterTimeout}
        transitionLeaveTimeout={transitionLeaveTimeout}
      >
        {items}
      </TransitionGroup>

  );
}

Notifs.defaultProps = {
  className: null,
  componentClassName: 'notif',
  transitionEnterTimeout: 600,
  transitionLeaveTimeout: 600,
  onActionClick: null,
  action: null
};

Notifs.propTypes = {
  notifs: React.PropTypes.array,
  className: React.PropTypes.string,
  CustomComponent: React.PropTypes.func,
  componentClassName: React.PropTypes.string,
  transitionEnterTimeout: React.PropTypes.number,
  transitionLeaveTimeout: React.PropTypes.number,
  onActionClick: React.PropTypes.func,
  actionLabel: React.PropTypes.string
};

export default connect((state) => ({ notifs: state.get ? state.get('notifs') : state.notifs }), {})(Notifs);
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import map from 'lodash/map'

import Contact from './Contact'

function Result({ contact, lead, header, points, score, resultBox }) {
  const { scoreTxt, submit } = resultBox
  return (

{scoreTxt}

{score}

{lead[0]} {lead[1]}

{resultBox.lead[0]} {resultBox.lead[1]}

{header}

            {
              map(points, (point, index) =>
{point}
)
            }

              {submit.label}
              <button>{submit.button}</button>

            <Contact {...contact} />

  )
}

Result.propTypes = {
  contact: PropTypes.object.isRequired,
  lead: PropTypes.array.isRequired,
  header: PropTypes.string.isRequired,
  points: PropTypes.array.isRequired,
  score: PropTypes.string.isRequired,
  resultBox: PropTypes.object.isRequired,
}
Result.defaultProps = {}
export default Result
<commit_msg>forgot to include it in PropTypes<commit_after>import React, { PropTypes } from 'react'
import map from 'lodash/map'

import Contact from './Contact'

function Result({ contact, lead, header, points, score, resultBox }) {
  const { scoreTxt, submit } = resultBox
  return (

{scoreTxt}

{score}

{lead[0]} {lead[1]}

{resultBox.lead[0]} {resultBox.lead[1]}

{header}

            {
              map(points, (point, index) =>
{point}
)
            }

              {submit.label}
              <button>{submit.button}</button>

            <Contact {...contact} />

  )
}

Result.propTypes = {
  closeBox: PropTypes.func.isRequired,
  contact: PropTypes.object.isRequired,
  lead: PropTypes.array.isRequired,
  header: PropTypes.string.isRequired,
  points: PropTypes.array.isRequired,
  score: PropTypes.string.isRequired,
  resultBox: PropTypes.object.isRequired,
}
Result.defaultProps = {}
export default Result
<|endoftext|>


<commit_before>import React from 'react';

const Footer = ({appUrl}) => {
  return (

          {[
            {url: appUrl.eventsSite(), name: 'Chronik'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.peopleSite(), name: 'Personen'},
            {url: appUrl.scientistsSite(), name: 'Wissenschaftler'},
            {url: appUrl.astronautsSite(), name: 'Raumfahrer'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: '', name: 'Orte'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.objectsSite(), name: 'Objekte'},
            {url: appUrl.peopleSite(), name: 'Sonnensystem'},
            {url: appUrl.constellationsSite(), name: 'Sternbilder'},
            {url: appUrl.starsSite(), name: 'Sterne'},
            {url: appUrl.spaceStationsSite(), name: 'Raumstationen'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.astronomySite(), name: 'Astronomie'},
            {url: appUrl.scientistsSite(), name: 'Wissenschaftler'},
            {url: appUrl.solarSystemSite(), name: 'Sonnensystem'},
            {url: appUrl.constellationsSite(), name: 'Sternbilder'},
            {url: appUrl.starsSite(), name: 'Sterne'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.spaceflightSite(), name: 'Raumfahrt'},
            {url: appUrl.astronautsSite(), name: 'Raumfahrer'},
            {url: appUrl.missionsSite(), name: 'Missionen'},
            {url: appUrl.spacewalksSite(), name: 'Weltraumausstiege'},
            {url: appUrl.spaceStationsSite(), name: 'Raumstationen'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.aboutSite() + '#whatis', name: 'Über uns'},
            {url: appUrl.aboutSite() + '#license', name: 'Lizenz'},
            {url: appUrl.aboutSite() + '#contribute', name: 'Beitragen'},
            {url: appUrl.aboutSite() + '#thanks', name: 'Danke'},
            {url: appUrl.aboutSite() + '#contact', name: 'Kontakt'},
            {url: appUrl.aboutSite() + '#imprint', name: 'Impressum'},
          ].map(link =>
            { link.name }
          )}

          {[
            {url: 'https://twitter.com/cosmowiki', name: 'Twitter'},
            {url: 'https://www.facebook.com/CosmoWiki.org/', name: 'Facebook'},
            {url: '', name: 'Google+'},
            {url: 'https://github.com/cosmowiki/cosmowiki', name: 'Github'},
          ].map(link =>

          ]}

v. 1.0.0

  )
};

export default Footer;

//
<commit_msg>added google+ url<commit_after>import React from 'react';

const Footer = ({appUrl}) => {
  return (

          {[
            {url: appUrl.eventsSite(), name: 'Chronik'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.peopleSite(), name: 'Personen'},
            {url: appUrl.scientistsSite(), name: 'Wissenschaftler'},
            {url: appUrl.astronautsSite(), name: 'Raumfahrer'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: '', name: 'Orte'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.objectsSite(), name: 'Objekte'},
            {url: appUrl.peopleSite(), name: 'Sonnensystem'},
            {url: appUrl.constellationsSite(), name: 'Sternbilder'},
            {url: appUrl.starsSite(), name: 'Sterne'},
            {url: appUrl.spaceStationsSite(), name: 'Raumstationen'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.astronomySite(), name: 'Astronomie'},
            {url: appUrl.scientistsSite(), name: 'Wissenschaftler'},
            {url: appUrl.solarSystemSite(), name: 'Sonnensystem'},
            {url: appUrl.constellationsSite(), name: 'Sternbilder'},
            {url: appUrl.starsSite(), name: 'Sterne'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.spaceflightSite(), name: 'Raumfahrt'},
            {url: appUrl.astronautsSite(), name: 'Raumfahrer'},
            {url: appUrl.missionsSite(), name: 'Missionen'},
            {url: appUrl.spacewalksSite(), name: 'Weltraumausstiege'},
            {url: appUrl.spaceStationsSite(), name: 'Raumstationen'},
            {url: appUrl.spaceTelescopesSite(), name: 'Weltraumteleskope'},
          ].map(link =>

              { link.name }

          )}

          {[
            {url: appUrl.aboutSite() + '#whatis', name: 'Über uns'},
            {url: appUrl.aboutSite() + '#license', name: 'Lizenz'},
            {url: appUrl.aboutSite() + '#contribute', name: 'Beitragen'},
            {url: appUrl.aboutSite() + '#thanks', name: 'Danke'},
            {url: appUrl.aboutSite() + '#contact', name: 'Kontakt'},
            {url: appUrl.aboutSite() + '#imprint', name: 'Impressum'},
          ].map(link =>
            { link.name }
          )}

          {[
            {url: 'https://twitter.com/cosmowiki', name: 'Twitter'},
            {url: 'https://www.facebook.com/CosmoWiki.org/', name: 'Facebook'},
            {url: 'https://plus.google.com/u/0/+CosmoWikide', name: 'Google+'},
            {url: 'https://github.com/cosmowiki/cosmowiki', name: 'Github'},
          ].map(link =>

          ]}

v. 1.0.0

  )
};

export default Footer;

//
<|endoftext|>


<commit_before>module.exports = function(app) {
  app.config([
    'formioComponentsProvider',
    function(formioComponentsProvider) {
      formioComponentsProvider.register('number', {
        icon: 'fa fa-hashtag',
        views: [
          {
            name: 'Display',
            template: 'formio/components/number/display.html'
          },
          {
            name: 'Validation',
            template: 'formio/components/number/validate.html'
          },
          {
            name: 'API',
            template: 'formio/components/common/api.html'
          },
          {
            name: 'Layout',
            template: 'formio/components/common/layout.html'
          },
          {
            name: 'Conditional',
            template: 'formio/components/common/conditional.html'
          }
        ],
        documentation: 'http://help.form.io/userguide/#number'
      });
    }
  ]);
  app.run([
    '$templateCache',
    function($templateCache) {
      // Create the settings markup.
      $templateCache.put('formio/components/number/display.html',
        '<ng-form>' +
          '<form-builder-option property="label"></form-builder-option>' +
          '<form-builder-option property="placeholder"></form-builder-option>' +
          '<form-builder-option property="validate.step" label="Increment (Step)" placeholder="Enter how much to increment per step (or precision)." title="The amount to increment/decrement for each step."></form-builder-option>' +
          '<form-builder-option property="prefix"></form-builder-option>' +
          '<form-builder-option property="suffix"></form-builder-option>' +
          '<form-builder-option property="customClass"></form-builder-option>' +
          '<form-builder-option property="tabindex"></form-builder-option>' +
          '<form-builder-option property="multiple"></form-builder-option>' +
          '<form-builder-option property="tableView"></form-builder-option>' +
        '</ng-form>'
      );

      // Create the API markup.
      $templateCache.put('formio/components/number/validate.html',
        '<ng-form>' +
          '<form-builder-option property="validate.required"></form-builder-option>' +
          '<form-builder-option property="validate.min" type="number" label="Minimum Value" placeholder="Minimum Value" title="The minimum value this field must have before the form can be submitted."></form-builder-option>' +
          '<form-builder-option property="validate.max" type="number" label="Maximum Value" placeholder="Maximum Value" title="The maximum value this field must have before the form can be submitted."></form-builder-option>' +
          '<form-builder-option-custom-validation></form-builder-option-custom-validation>' +
        '</ng-form>'
      );
    }
  ]);
};
<commit_msg>FOR-193 - adding default value field to number component.<commit_after>module.exports = function(app) {
  app.config([
    'formioComponentsProvider',
    function(formioComponentsProvider) {
      formioComponentsProvider.register('number', {
        icon: 'fa fa-hashtag',
        views: [
          {
            name: 'Display',
            template: 'formio/components/number/display.html'
          },
          {
            name: 'Validation',
            template: 'formio/components/number/validate.html'
          },
          {
            name: 'API',
            template: 'formio/components/common/api.html'
          },
          {
            name: 'Layout',
            template: 'formio/components/common/layout.html'
          },
          {
            name: 'Conditional',
            template: 'formio/components/common/conditional.html'
          }
        ],
        documentation: 'http://help.form.io/userguide/#number'
      });
    }
  ]);
  app.run([
    '$templateCache',
    function($templateCache) {
      // Create the settings markup.
      $templateCache.put('formio/components/number/display.html',
        '<ng-form>' +
          '<form-builder-option property="label"></form-builder-option>' +
          '<form-builder-option property="defaultValue"></form-builder-option>' +
          '<form-builder-option property="placeholder"></form-builder-option>' +
          '<form-builder-option property="validate.step" label="Increment (Step)" placeholder="Enter how much to increment per step (or precision)." title="The amount to increment/decrement for each step."></form-builder-option>' +
          '<form-builder-option property="prefix"></form-builder-option>' +
          '<form-builder-option property="suffix"></form-builder-option>' +
          '<form-builder-option property="customClass"></form-builder-option>' +
          '<form-builder-option property="tabindex"></form-builder-option>' +
          '<form-builder-option property="multiple"></form-builder-option>' +
          '<form-builder-option property="tableView"></form-builder-option>' +
        '</ng-form>'
      );

      // Create the API markup.
      $templateCache.put('formio/components/number/validate.html',
        '<ng-form>' +
          '<form-builder-option property="validate.required"></form-builder-option>' +
          '<form-builder-option property="validate.min" type="number" label="Minimum Value" placeholder="Minimum Value" title="The minimum value this field must have before the form can be submitted."></form-builder-option>' +
          '<form-builder-option property="validate.max" type="number" label="Maximum Value" placeholder="Maximum Value" title="The maximum value this field must have before the form can be submitted."></form-builder-option>' +
          '<form-builder-option-custom-validation></form-builder-option-custom-validation>' +
        '</ng-form>'
      );
    }
  ]);
};
<|endoftext|>


<commit_before>import assign from './assign';
/**
 * Property Descriptor that computes its value once and then permanently caches
 * the result.
 *
 * In order to make the computation of microstate properties easy to
 * reason about, we want them to be as lazy as possible. However, in
 * order to make sure that we don't do any extra computation than
 * necessary.
 */
export default class ComputedProperty {
  get writeable() { return false; }

  get enumerable() { return false; }

  constructor(compute, attributes = {}) {
    let property = this;
    this.get = function() {
      let value = compute.call(this);
      property.get = ()=> value;
      return value;
    };
    assign(this, attributes);
  }
}
<commit_msg>add documentation for computed property<commit_after>import assign from './assign';
/**
 * Property Descriptor that computes its value once and then permanently caches
 * the result.
 *
 * In order to make the computation of microstate properties easy to
 * reason about, we want them to be as lazy as possible. However, in
 * order to make sure that we don't do any extra computation than
 * necessary we want to permanently cache the result of those lazy
 * computations. That's where `ComputedProperty` comes in.
 *
 * Every instance of `ComputedProperty` is a valid instance of a
 * JavaScript property descriptor, which, by default,  is
 * is _not_ enumerable. It can be used in any API that expects a property
 * descriptor. For example:
 *
 *   let object = {};
 *   Object.defineProperty('constant', new ComputedProperty(function() {
 *     return {};
 *   }))
 *
 *   object.constant === object.constant //=> true
 *
 * In order to change the configuration of the property descriptor,
 * you can pass a set of overrides to the constructor to do things
 * like make it an enumerable property.
 *
 *   let object = {}
 *   Object.defineProperty('constant', new ComputedProperty(function() {
 *     return {}
 *   }, { enumerable: true }));
 *
 *   Object.keys(object) //=> ['constant']
 *
 * The value of `this` inside the computed property evaluation function will be
 * the object on which this property resides.
 *
 *   let object = {one: 1, two: 2};
 *   Object.defineProperty('info', new ComputedProperty(function() {
 *     return { type: typeof this, keys: Object.keys(this) };
 *   }));
 *
 *   object.info //=> { type: 'object', keys: ['one', 'two'] }
 *
 * Note that it's totally ok to permanently cache the results of computations
 * since the objects to which these properties will be attached are
 * immutable.
 *
 * @constructor ComputedProperty
 * @param {function} compute - evaluates the property value
 * @param {Object} [attributes] - extra attributes for the descriptor.
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description
 */
export default class ComputedProperty {
  get writeable() { return false; }

  get enumerable() { return false; }

  constructor(compute, attributes = {}) {
    let property = this;
    this.get = function() {
      let value = compute.call(this);
      property.get = ()=> value;
      return value;
    };
    assign(this, attributes);
  }
}
<|endoftext|>


<commit_before>import * as Modules from '../modules';
import SoundSource from './SoundSource';
import { TYPES } from './Constants';

class Voice {

    constructor (note, audioContext, modulesConfig, analyser) {
        this.note = note;
        this.modulesConfig = modulesConfig;
        this.modules = {};
        this.soundSources = [];
        this.master = null;
        this.analyser = analyser || null;

        this.setupModules(audioContext);
        this.linkModules();
    }

    setupModules (audioContext) {
        let modConf,
            m;

        Object.keys(this.modulesConfig).forEach((mod) => {
            modConf = this.modulesConfig[mod];
            if (modConf.type && modConf.props) {
                m = new Modules[modConf.type](audioContext, modConf.props, modConf.type);
                this.modules[mod] = {
                    type: modConf.type,
                    instance: m
                };

                if (m.instance instanceof SoundSource) {
                    this.soundSources.push(m);
                } else if (modConf.type === TYPES.MASTER) {
                    this.master = m;
                }
            }
        });
    }

    updateModule (moduleId, props) {
        if (this.modules[moduleId] && this.modules[moduleId].instance) {
            this.modules[moduleId].instance.updateProperties(props);
        }
    }

    linkModules () {
        Object.keys(this.modules).forEach((mod) => {
            let currentModule = this.modules[mod].instance,
                currentModuleType = this.modules[mod].type,
                destinationModule,
                source,
                dest;

            if (currentModule.link) {
                destinationModule = this.modules[currentModule.link];
                if (destinationModule && destinationModule.instance) {
                    source = currentModule.getLineOut();
                    dest = destinationModule.instance.getLineIn(currentModuleType, currentModule);
                    //console.log(mod, source, currentModule.link, dest);
                    if (source && dest) {
                        source.connect(dest);
                    }
                }
            }
        });

        this.master.lineOut(this.analyser);
    }

    noteOn () {
        let m,
            dest;

        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;

            if (typeof m.setEnvelope === 'function') {
                dest = (this.modules[m.link]) ? this.modules[m.link].instance : null;
                m.setEnvelope(dest);
            }
            if (typeof m.setNote === 'function') {
                m.setNote(+this.note);
            }
        });
        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.noteOn === 'function') {
                m.noteOn();
            }
        });
    }

    noteOff () {
        let release = 0,
            adsr = this.modules.adsr.instance,
            m,
            dest;

        release = adsr.getReleaseTime();

        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.resetEnvelope === 'function') {
                dest = (this.modules[m.link]) ? this.modules[m.link].instance : null;
                m.resetEnvelope(dest);
            }
        });
        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.noteOff === 'function') {
                m.noteOff(release);
            }
        });
    }

}

export default Voice;
<commit_msg>docs. close #2<commit_after>import * as Modules from '../modules';
import SoundSource from './SoundSource';
import { TYPES } from './Constants';

/**
 * Voice Class
 * @example
 * const v = new Voice(440, AudioContext, { master: { ... }, adsr: { ... } }, null);
 */
class Voice {

    constructor (note, audioContext, modulesConfig, analyser) {
        this.note = note;
        this.modulesConfig = modulesConfig;
        this.modules = {};
        this.soundSources = [];
        this.master = null;
        this.analyser = analyser || null;

        this.setupModules(audioContext);
        this.linkModules();
    }

    setupModules (audioContext) {
        let modConf,
            m;

        Object.keys(this.modulesConfig).forEach((mod) => {
            modConf = this.modulesConfig[mod];
            if (modConf.type && modConf.props) {
                m = new Modules[modConf.type](audioContext, modConf.props, modConf.type);
                this.modules[mod] = {
                    type: modConf.type,
                    instance: m
                };

                if (m.instance instanceof SoundSource) {
                    this.soundSources.push(m);
                } else if (modConf.type === TYPES.MASTER) {
                    this.master = m;
                }
            }
        });
    }

    updateModule (moduleId, props) {
        if (this.modules[moduleId] && this.modules[moduleId].instance) {
            this.modules[moduleId].instance.updateProperties(props);
        }
    }

    linkModules () {
        Object.keys(this.modules).forEach((mod) => {
            let currentModule = this.modules[mod].instance,
                currentModuleType = this.modules[mod].type,
                destinationModule,
                source,
                dest;

            if (currentModule.link) {
                destinationModule = this.modules[currentModule.link];
                if (destinationModule && destinationModule.instance) {
                    source = currentModule.getLineOut();
                    dest = destinationModule.instance.getLineIn(currentModuleType, currentModule);
                    //console.log(mod, source, currentModule.link, dest);
                    if (source && dest) {
                        source.connect(dest);
                    }
                }
            }
        });

        this.master.lineOut(this.analyser);
    }

    noteOn () {
        let m,
            dest;

        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;

            if (typeof m.setEnvelope === 'function') {
                dest = (this.modules[m.link]) ? this.modules[m.link].instance : null;
                m.setEnvelope(dest);
            }
            if (typeof m.setNote === 'function') {
                m.setNote(+this.note);
            }
        });
        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.noteOn === 'function') {
                m.noteOn();
            }
        });
    }

    noteOff () {
        let release = 0,
            adsr = this.modules.adsr.instance,
            m,
            dest;

        release = adsr.getReleaseTime();

        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.resetEnvelope === 'function') {
                dest = (this.modules[m.link]) ? this.modules[m.link].instance : null;
                m.resetEnvelope(dest);
            }
        });
        Object.keys(this.modules).forEach((e) => {
            m = this.modules[e].instance;
            if (typeof m.noteOff === 'function') {
                m.noteOff(release);
            }
        });
    }

}

export default Voice;
<|endoftext|>


<commit_before>var isObject = require("./is-object");
var hasOwn = Object.prototype.hasOwnProperty;

module.exports = function(obj, prop) {
  return isObject(obj) && hasOwn.call(obj, prop);
};<commit_msg>Fix eslint error in hasOwn.js<commit_after>var isObject = require("./is-object");
var hasOwn = Object.prototype.hasOwnProperty;

module.exports = function(obj, prop) {
  return isObject(obj) && hasOwn.call(obj, prop);
};
<|endoftext|>