<commit_before>/**
 * Module dependencies
 */

var util = require('util');
var assert = require('assert');
var _ = require('@sailshq/lodash');
var flaverr = require('flaverr');
var rttc = require('rttc');
var getModel = require('./get-model');
var getAttribute = require('./get-attribute');
var isValidAttributeName = require('./is-valid-attribute-name');
var normalizePkValue = require('./normalize-pk-value');
var normalizePkValues = require('./normalize-pk-values');

/**
 * normalizeValueToSet()
 *
 * Validate and normalize the provided `value`, hammering it destructively into a format
 * that is compatible with the specified attribute.
 *
 * This function has a return value.   But realize that this is only because the provided value
 * _might_ be a string, number, or some other primitive that is NOT passed by reference, and thus
 * must be replaced, rather than modified.
 *
 * --
 *
 * THIS UTILITY IS NOT CURRENTLY RESPONSIBLE FOR APPLYING HIGH-LEVEL ("anchor") VALIDATION RULES!
 * (but note that this could change at some point in the future)
 *
 * > BUT FOR NOW:
 * > High-level (anchor) validations are completely separate from the
 * > type safety checks here.  (The high-level validations are implemented
 * > elsewhere in Waterline.)
 *
 * --
 *
 * @param  {Ref} value
 *         The value to set (i.e. from the `valuesToSet` or `newRecord` query keys of a "stage 1 query").
 *         (If provided as `undefined`, it will be ignored)
 *         > WARNING:
 *         > IN SOME CASES (BUT NOT ALL!), THE PROVIDED VALUE WILL
 *         > UNDERGO DESTRUCTIVE, IN-PLACE CHANGES JUST BY PASSING IT
 *         > IN TO THIS UTILITY.
 *
 * @param {String} supposedAttrName
 *        The "supposed attribute name"; i.e. the LHS the provided value came from (e.g. "id" or "favoriteBrands")
 *        > Useful for looking up the appropriate attribute definition.
 *
 * @param {String} modelIdentity
 *        The identity of the model this value is for (e.g. "pet" or "user")
 *        > Useful for looking up the Waterline model and accessing its attribute definitions.
 *
 * @param {Ref} orm
 *        The Waterline ORM instance.
 *        > Useful for accessing the model definitions.
 *
 * @param {Boolean?} ensureTypeSafety
 *        Optional.  If provided and set to `true`, then `value` will be validated
 *        (and/or lightly coerced) vs. the logical type schema derived from the attribute
 *        definition.  If it fails, we throw instead of returning.
 *        > • Keep in mind this is separate from high-level validations (e.g. anchor)!!
 *        > • Also note that if this value is for an association, it is _always_
 *        >   checked, regardless of whether this flag is set to `true`.
 *
 * --
 *
 * @returns {Dictionary}
 *          The successfully-normalized value, ready for use in the `valuesToSet` or `newRecord`
 *          query keys in a stage 2 query.
 *
 * --
 *
 * @throws {Error} If the value should be ignored/stripped (e.g. because it is `undefined`, or because it
 *                 does not correspond with a recognized attribute, and the model def has `schema: true`)
 *         @property {String} code
 *                   - E_SHOULD_BE_IGNORED
 *
 *
 * @throws {Error} If it encounters incompatible usage in the provided `value`,
 *                 including e.g. the case where an invalid value is specified for
 *                 an association.
 *         @property {String} code
 *                   - E_HIGHLY_IRREGULAR
 *
 *
 * @throws {Error} If the provided `value` has an incompatible data type.
 *   |     @property {String} code
 *   |               - E_INVALID
 *   |
 *   | This is only versus the attribute's declared "type" --
 *   | failed validation versus associations results in a different error code
 *   | (see above).  Also note that this error is only possible when `ensureTypeSafety`
 *   | is enabled.
 *   |
 *   | Remember: This is NOT a high-level "anchor" validation failure!
 *   | This is the case where a _completely incorrect type of data_ was passed in.
 *   | > Unlike anchor validation errors, this error should never be negotiated/parsed/used
 *   | > for delivering error messages to end users of an application-- it is carved out
 *   | > separately purely to make things easier to follow for the developer.
 *
 *
 * @throws {Error} If anything else unexpected occurs.
 */
module.exports = function normalizeValueToSet(value, supposedAttrName, modelIdentity, orm, ensureTypeSafety) {

  // ================================================================================================
  assert(_.isString(supposedAttrName) && supposedAttrName !== '', new Error('Consistency violation: `supposedAttrName` must be a non-empty string.'));
  // (`modelIdentity` and `orm` will be automatically checked by calling `getModel()` below)
  // ================================================================================================

  // Look up the Waterline model.
  // > This is so that we can reference the original model definition.
  var WLModel;
  try {
    WLModel = getModel(modelIdentity, orm);
  } catch (e) {
    switch (e.code) {
      case 'E_MODEL_NOT_REGISTERED': throw new Error('Consistency violation: '+e.message);
      default: throw e;
    }
  }//</catch>

  // If this value is `undefined`, then bail early, indicating that it should be ignored.
  if (_.isUndefined(value)) {
    throw flaverr('E_SHOULD_BE_IGNORED', new Error(
      'This value is `undefined`.  Remember: in Sails/Waterline, we always treat keys with '+
      '`undefined` values as if they were never there in the first place.'
    ));
  }//-•

  // This local variable will be used to hold a reference to the attribute def
  // that corresponds with this value (if there is one).
  var correspondingAttrDef;

  //  ┌─┐┬ ┬┌─┐┌─┐┬┌─  ┌─┐┌┬┐┌┬┐┬─┐┬┌┐ ┬ ┬┌┬┐┌─┐  ┌┐┌┌─┐┌┬┐┌─┐
  //  │  ├─┤├┤ │  ├┴┐  ├─┤ │  │ ├┬┘│├┴┐│ │ │ ├┤   │││├─┤│││├┤
  //  └─┘┴ ┴└─┘└─┘┴ ┴  ┴ ┴ ┴  ┴ ┴└─┴└─┘└─┘ ┴ └─┘  ┘└┘┴ ┴┴ ┴└─┘

  // If this model declares `schema: true`...
  if (WLModel.hasSchema === true) {

    // Check that this key corresponds with a recognized attribute definition.
    try {
      correspondingAttrDef = getAttribute(supposedAttrName, modelIdentity, orm);
    } catch (e) {
      switch (e.code) {

        // If no such attribute exists, then fail gracefully by bailing early, indicating
        // that this value should be ignored (For example, this might cause this value to
        // be stripped out of the `newRecord` or `valuesToSet` query keys.)
        case 'E_ATTR_NOT_REGISTERED':
          throw flaverr('E_SHOULD_BE_IGNORED', new Error(
            'This model declares itself `schema: true`, but this value does not match '+
            'any recognized attribute (thus it will be ignored).'
          ));

        default:
          throw e;

      }
    }//</catch>

  }//</else if `hasSchema === true` >
  // ‡
  // Else if this model declares `schema: false`...
  else if (WLModel.hasSchema === false) {

    // Check that this key is a valid Waterline attribute name, at least.
    if (!isValidAttributeName(supposedAttrName)) {
      throw flaverr('E_HIGHLY_IRREGULAR', new Error('This is not a valid name for an attribute.'));
    }//-•

  }
  // ‡
  else {
    throw new Error(
      'Consistency violation: Every instantiated Waterline model should always have the `hasSchema` flag '+
      'as either `true` or `false` (should have been automatically derived from the `schema` model setting '+
      'shortly after construction.  And `schema` should have been verified as existing by waterline-schema).  '+
      'But somehow, this model\'s (`'+modelIdentity+'`) `hasSchema` property is as follows: '+
      util.inspect(WLModel.hasSchema, {depth:null})+''
    );
  }//</ else >

  //  ┌─┐┬ ┬┌─┐┌─┐┬┌─   ┬   ┌┬┐┌─┐┬ ┬┌┐ ┌─┐  ┌┐┌┌─┐┬─┐┌┬┐┌─┐┬  ┬┌─┐┌─┐  ┬  ┬┌─┐┬  ┬ ┬┌─┐
  //  │  ├─┤├┤ │  ├┴┐  ┌┼─  │││├─┤└┬┘├┴┐├┤   ││││ │├┬┘│││├─┤│  │┌─┘├┤   └┐┌┘├─┤│  │ │├┤
  //  └─┘┴ ┴└─┘└─┘┴ ┴  └┘   ┴ ┴┴ ┴ ┴ └─┘└─┘  ┘└┘└─┘┴└─┴ ┴┴ ┴┴─┘┴└─┘└─┘   └┘ ┴ ┴┴─┘└─┘└─┘
  // Validate+lightly coerce this value vs. the corresponding attribute definition's
  // declared `type`, `model`, or `collection`.
  //
  // > Only relevant if this value actually matches an attribute definition.
  if (!correspondingAttrDef) {

    // If this value doesn't match a recognized attribute def, then don't validate it
    // (it means this model must have `schema: false`)

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // FUTURE: In this case, validate/coerce this as `type: 'json'`.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  }//‡
  else {

    // First: Do some preprocessing for the special case where `value` is `null`
    if (_.isNull(value)) {

      // If the corresponding attribute is required, then throw an error.
      // (`null` is not allowed as the value for a required attribute)
      //
      // > This is a bit different than `required` elsewhere in the world of Node/RTTC/machines,
      // > because the world of data (i.e. JSON, databases, APIs, etc.) equates `undefined`
      // > and `null`.  But in Waterline, if the RHS of a key is `undefined`, it means the same
      // > thing as if the key wasn't provided at all.  So because of that, when we use `null`
      // > to indicate that we want to clear out an attribute value, it also means that, after
      // > doing so, `null` will ALSO represent the state that attribute value is in (where it
      // > "has no value").
      if (correspondingAttrDef.required) {
        throw flaverr('E_HIGHLY_IRREGULAR', new Error('Cannot use `null` as the value for required attribute (`'+supposedAttrName+'`).'));
      }
      // Otherwise, the corresponding attribute is NOT required, so since our value happens to be `null`,
      // then check for a `defaultsTo`, and if there is one, replace the `null` with the default value.
      else if (!_.isUndefined(correspondingAttrDef.defaultsTo)) {
        value = correspondingAttrDef.defaultsTo;
        // Remember: we're not cloning the `defaultsTo`, so we need to watch out in WL core!
      }

    }//>-•

    // Next:  Move on to a few more nuanced checks for the general case
    if (correspondingAttrDef.model) {

      // Ensure that this is either `null`, or that it matches the expected
      // data type for a pk value of the associated model (normalizing it,
      // if appropriate/possible.)
      if (_.isNull(value)) { /* `null` is ok (unless it's required, but we deal w/ that later) */ }
      else {
        try {
          value = normalizePkValue(value, getAttribute(getModel(correspondingAttrDef.model, orm).primaryKey, correspondingAttrDef.model, orm).type);
        } catch (e) {
          switch (e.code) {
            case 'E_INVALID_PK_VALUE':
              throw flaverr('E_HIGHLY_IRREGULAR', new Error('If specifying the value for a singular (`model`) association, you must do so by providing an appropriate id representing the associated record, or `null` to indicate there will be no associated "'+supposedAttrName+'".  But instead, for `'+supposedAttrName+'`, got: '+util.inspect(value, {depth:null})+''));
            default: throw e;
          }
        }
      }// >-•   </ else (i.e. anything other than `null`)>

    }//‡
    else if (correspondingAttrDef.collection) {

      // Ensure that this is an array, and that each item in the array matches
      // the expected data type for a pk value of the associated model.
      try {
        value = normalizePkValues(value, getAttribute(getModel(correspondingAttrDef.collection, orm).primaryKey, correspondingAttrDef.collection, orm).type);
      } catch (e) {
        switch (e.code) {
          case 'E_INVALID_PK_VALUE':
            throw flaverr('E_HIGHLY_IRREGULAR', new Error('If specifying the value for a plural (`collection`) association, you must do so by providing an array of associated ids representing the associated records.  But instead, for `'+supposedAttrName+'`, got: '+util.inspect(value, {depth:null})+''));
          default: throw e;
        }
      }

    }//‡
    else {
      assert(_.isString(correspondingAttrDef.type) && correspondingAttrDef.type !== '', new Error('Consistency violation: There is no way this attribute (`'+supposedAttrName+'`) should have been allowed to be registered with neither a `type`, `model`, nor `collection`!  Here is the attr def: '+util.inspect(correspondingAttrDef, {depth:null})+''));

      // Only bother doing the type safety check if `ensureTypeSafety` was enabled.
      //
      // > Note: This is just like normal RTTC validation ("loose" mode), with one major exception:
      // > • We tolerate `null` regardless of the type being validated against
      // >  (whereas in RTTC, it'd only be valid vs. `json` and `ref`.)
      // >
      // > This is because, in most databases, `null` is allowed as an implicit base value
      // > for any type of data.  This sorta serves the same purpose as `undefined` in
      // > JavaScript.  (Review the "required"-ness checks above for more on that.)
      if (ensureTypeSafety) {

        if (_.isNull(value)) { /* `null` is always (unless it's required, but we already dealt w/ that above) */ }
        else {

          // Verify that this matches the expected type, and potentially coerce the value
          // at the same time.  This throws an E_INVALID error if validation fails.
          value = rttc.validate(correspondingAttrDef.type, value);

        }//>-•

      }//>-•

    }//</else (i.e. corresponding attr def is just a normal attr--not an association)>

  }//</else (i.e. there is a corresponding attr of some kind>

  // Return the normalized value.
  return value;

};
<commit_msg>Correct outdated comment.<commit_after>/**
 * Module dependencies
 */

var util = require('util');
var assert = require('assert');
var _ = require('@sailshq/lodash');
var flaverr = require('flaverr');
var rttc = require('rttc');
var getModel = require('./get-model');
var getAttribute = require('./get-attribute');
var isValidAttributeName = require('./is-valid-attribute-name');
var normalizePkValue = require('./normalize-pk-value');
var normalizePkValues = require('./normalize-pk-values');

/**
 * normalizeValueToSet()
 *
 * Validate and normalize the provided `value`, hammering it destructively into a format
 * that is compatible with the specified attribute.
 *
 * This function has a return value.   But realize that this is only because the provided value
 * _might_ be a string, number, or some other primitive that is NOT passed by reference, and thus
 * must be replaced, rather than modified.
 *
 * --
 *
 * THIS UTILITY IS NOT CURRENTLY RESPONSIBLE FOR APPLYING HIGH-LEVEL ("anchor") VALIDATION RULES!
 * (but note that this could change at some point in the future)
 *
 * > BUT FOR NOW:
 * > High-level (anchor) validations are completely separate from the
 * > type safety checks here.  (The high-level validations are implemented
 * > elsewhere in Waterline.)
 *
 * --
 *
 * @param  {Ref} value
 *         The value to set (i.e. from the `valuesToSet` or `newRecord` query keys of a "stage 1 query").
 *         (If provided as `undefined`, it will be ignored)
 *         > WARNING:
 *         > IN SOME CASES (BUT NOT ALL!), THE PROVIDED VALUE WILL
 *         > UNDERGO DESTRUCTIVE, IN-PLACE CHANGES JUST BY PASSING IT
 *         > IN TO THIS UTILITY.
 *
 * @param {String} supposedAttrName
 *        The "supposed attribute name"; i.e. the LHS the provided value came from (e.g. "id" or "favoriteBrands")
 *        > Useful for looking up the appropriate attribute definition.
 *
 * @param {String} modelIdentity
 *        The identity of the model this value is for (e.g. "pet" or "user")
 *        > Useful for looking up the Waterline model and accessing its attribute definitions.
 *
 * @param {Ref} orm
 *        The Waterline ORM instance.
 *        > Useful for accessing the model definitions.
 *
 * @param {Boolean?} ensureTypeSafety
 *        Optional.  If provided and set to `true`, then `value` will be validated
 *        (and/or lightly coerced) vs. the logical type schema derived from the attribute
 *        definition.  If it fails, we throw instead of returning.
 *        > • Keep in mind this is separate from high-level validations (e.g. anchor)!!
 *        > • Also note that if this value is for an association, it is _always_
 *        >   checked, regardless of whether this flag is set to `true`.
 *
 * --
 *
 * @returns {Dictionary}
 *          The successfully-normalized value, ready for use in the `valuesToSet` or `newRecord`
 *          query keys in a stage 2 query.
 *
 * --
 *
 * @throws {Error} If the value should be ignored/stripped (e.g. because it is `undefined`, or because it
 *                 does not correspond with a recognized attribute, and the model def has `schema: true`)
 *         @property {String} code
 *                   - E_SHOULD_BE_IGNORED
 *
 *
 * @throws {Error} If it encounters incompatible usage in the provided `value`,
 *                 including e.g. the case where an invalid value is specified for
 *                 an association.
 *         @property {String} code
 *                   - E_HIGHLY_IRREGULAR
 *
 *
 * @throws {Error} If the provided `value` has an incompatible data type.
 *   |     @property {String} code
 *   |               - E_INVALID
 *   |
 *   | This is only versus the attribute's declared "type" --
 *   | failed validation versus associations results in a different error code
 *   | (see above).  Also note that this error is only possible when `ensureTypeSafety`
 *   | is enabled.
 *   |
 *   | Remember: This is NOT a high-level "anchor" validation failure!
 *   | This is the case where a _completely incorrect type of data_ was passed in.
 *   | > Unlike anchor validation errors, this error should never be negotiated/parsed/used
 *   | > for delivering error messages to end users of an application-- it is carved out
 *   | > separately purely to make things easier to follow for the developer.
 *
 *
 * @throws {Error} If anything else unexpected occurs.
 */
module.exports = function normalizeValueToSet(value, supposedAttrName, modelIdentity, orm, ensureTypeSafety) {

  // ================================================================================================
  assert(_.isString(supposedAttrName) && supposedAttrName !== '', new Error('Consistency violation: `supposedAttrName` must be a non-empty string.'));
  // (`modelIdentity` and `orm` will be automatically checked by calling `getModel()` below)
  // ================================================================================================

  // Look up the Waterline model.
  // > This is so that we can reference the original model definition.
  var WLModel;
  try {
    WLModel = getModel(modelIdentity, orm);
  } catch (e) {
    switch (e.code) {
      case 'E_MODEL_NOT_REGISTERED': throw new Error('Consistency violation: '+e.message);
      default: throw e;
    }
  }//</catch>

  // If this value is `undefined`, then bail early, indicating that it should be ignored.
  if (_.isUndefined(value)) {
    throw flaverr('E_SHOULD_BE_IGNORED', new Error(
      'This value is `undefined`.  Remember: in Sails/Waterline, we always treat keys with '+
      '`undefined` values as if they were never there in the first place.'
    ));
  }//-•

  // This local variable will be used to hold a reference to the attribute def
  // that corresponds with this value (if there is one).
  var correspondingAttrDef;

  //  ┌─┐┬ ┬┌─┐┌─┐┬┌─  ┌─┐┌┬┐┌┬┐┬─┐┬┌┐ ┬ ┬┌┬┐┌─┐  ┌┐┌┌─┐┌┬┐┌─┐
  //  │  ├─┤├┤ │  ├┴┐  ├─┤ │  │ ├┬┘│├┴┐│ │ │ ├┤   │││├─┤│││├┤
  //  └─┘┴ ┴└─┘└─┘┴ ┴  ┴ ┴ ┴  ┴ ┴└─┴└─┘└─┘ ┴ └─┘  ┘└┘┴ ┴┴ ┴└─┘

  // If this model declares `schema: true`...
  if (WLModel.hasSchema === true) {

    // Check that this key corresponds with a recognized attribute definition.
    try {
      correspondingAttrDef = getAttribute(supposedAttrName, modelIdentity, orm);
    } catch (e) {
      switch (e.code) {

        // If no such attribute exists, then fail gracefully by bailing early, indicating
        // that this value should be ignored (For example, this might cause this value to
        // be stripped out of the `newRecord` or `valuesToSet` query keys.)
        case 'E_ATTR_NOT_REGISTERED':
          throw flaverr('E_SHOULD_BE_IGNORED', new Error(
            'This model declares itself `schema: true`, but this value does not match '+
            'any recognized attribute (thus it will be ignored).'
          ));

        default:
          throw e;

      }
    }//</catch>

  }//</else if `hasSchema === true` >
  // ‡
  // Else if this model declares `schema: false`...
  else if (WLModel.hasSchema === false) {

    // Check that this key is a valid Waterline attribute name, at least.
    if (!isValidAttributeName(supposedAttrName)) {
      throw flaverr('E_HIGHLY_IRREGULAR', new Error('This is not a valid name for an attribute.'));
    }//-•

  }
  // ‡
  else {
    throw new Error(
      'Consistency violation: Every instantiated Waterline model should always have the `hasSchema` flag '+
      'as either `true` or `false` (should have been automatically derived from the `schema` model setting '+
      'shortly after construction.  And `schema` should have been verified as existing by waterline-schema).  '+
      'But somehow, this model\'s (`'+modelIdentity+'`) `hasSchema` property is as follows: '+
      util.inspect(WLModel.hasSchema, {depth:null})+''
    );
  }//</ else >

  //  ┌─┐┬ ┬┌─┐┌─┐┬┌─   ┬   ┌┬┐┌─┐┬ ┬┌┐ ┌─┐  ┌┐┌┌─┐┬─┐┌┬┐┌─┐┬  ┬┌─┐┌─┐  ┬  ┬┌─┐┬  ┬ ┬┌─┐
  //  │  ├─┤├┤ │  ├┴┐  ┌┼─  │││├─┤└┬┘├┴┐├┤   ││││ │├┬┘│││├─┤│  │┌─┘├┤   └┐┌┘├─┤│  │ │├┤
  //  └─┘┴ ┴└─┘└─┘┴ ┴  └┘   ┴ ┴┴ ┴ ┴ └─┘└─┘  ┘└┘└─┘┴└─┴ ┴┴ ┴┴─┘┴└─┘└─┘   └┘ ┴ ┴┴─┘└─┘└─┘
  // Validate+lightly coerce this value vs. the corresponding attribute definition's
  // declared `type`, `model`, or `collection`.
  //
  // > Only relevant if this value actually matches an attribute definition.
  if (!correspondingAttrDef) {

    // If this value doesn't match a recognized attribute def, then don't validate it
    // (it means this model must have `schema: false`)

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // FUTURE: In this case, validate/coerce this as `type: 'json'`.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  }//‡
  else {

    // First: Do some preprocessing for the special case where `value` is `null`
    if (_.isNull(value)) {

      // If the corresponding attribute is required, then throw an error.
      // (`null` is not allowed as the value for a required attribute)
      //
      // > This is a bit different than `required` elsewhere in the world of Node/RTTC/machines,
      // > because the world of data (i.e. JSON, databases, APIs, etc.) equates `undefined`
      // > and `null`.  But in Waterline, if the RHS of a key is `undefined`, it means the same
      // > thing as if the key wasn't provided at all.  So because of that, when we use `null`
      // > to indicate that we want to clear out an attribute value, it also means that, after
      // > doing so, `null` will ALSO represent the state that attribute value is in (where it
      // > "has no value").
      if (correspondingAttrDef.required) {
        throw flaverr('E_HIGHLY_IRREGULAR', new Error('Cannot use `null` as the value for required attribute (`'+supposedAttrName+'`).'));
      }
      // Otherwise, the corresponding attribute is NOT required, so since our value happens to be `null`,
      // then check for a `defaultsTo`, and if there is one, replace the `null` with the default value.
      else if (!_.isUndefined(correspondingAttrDef.defaultsTo)) {
        value = correspondingAttrDef.defaultsTo;
        // Remember: we're not cloning the `defaultsTo`, so we need to watch out in WL core!
      }

    }//>-•

    // Next:  Move on to a few more nuanced checks for the general case
    if (correspondingAttrDef.model) {

      // Ensure that this is either `null`, or that it matches the expected
      // data type for a pk value of the associated model (normalizing it,
      // if appropriate/possible.)
      if (_.isNull(value)) { /* `null` is ok (unless it's required, but we already dealt w/ that above) */ }
      else {
        try {
          value = normalizePkValue(value, getAttribute(getModel(correspondingAttrDef.model, orm).primaryKey, correspondingAttrDef.model, orm).type);
        } catch (e) {
          switch (e.code) {
            case 'E_INVALID_PK_VALUE':
              throw flaverr('E_HIGHLY_IRREGULAR', new Error('If specifying the value for a singular (`model`) association, you must do so by providing an appropriate id representing the associated record, or `null` to indicate there will be no associated "'+supposedAttrName+'".  But instead, for `'+supposedAttrName+'`, got: '+util.inspect(value, {depth:null})+''));
            default: throw e;
          }
        }
      }// >-•   </ else (i.e. anything other than `null`)>

    }//‡
    else if (correspondingAttrDef.collection) {

      // Ensure that this is an array, and that each item in the array matches
      // the expected data type for a pk value of the associated model.
      try {
        value = normalizePkValues(value, getAttribute(getModel(correspondingAttrDef.collection, orm).primaryKey, correspondingAttrDef.collection, orm).type);
      } catch (e) {
        switch (e.code) {
          case 'E_INVALID_PK_VALUE':
            throw flaverr('E_HIGHLY_IRREGULAR', new Error('If specifying the value for a plural (`collection`) association, you must do so by providing an array of associated ids representing the associated records.  But instead, for `'+supposedAttrName+'`, got: '+util.inspect(value, {depth:null})+''));
          default: throw e;
        }
      }

    }//‡
    else {
      assert(_.isString(correspondingAttrDef.type) && correspondingAttrDef.type !== '', new Error('Consistency violation: There is no way this attribute (`'+supposedAttrName+'`) should have been allowed to be registered with neither a `type`, `model`, nor `collection`!  Here is the attr def: '+util.inspect(correspondingAttrDef, {depth:null})+''));

      // Only bother doing the type safety check if `ensureTypeSafety` was enabled.
      //
      // > Note: This is just like normal RTTC validation ("loose" mode), with one major exception:
      // > • We tolerate `null` regardless of the type being validated against
      // >  (whereas in RTTC, it'd only be valid vs. `json` and `ref`.)
      // >
      // > This is because, in most databases, `null` is allowed as an implicit base value
      // > for any type of data.  This sorta serves the same purpose as `undefined` in
      // > JavaScript.  (Review the "required"-ness checks above for more on that.)
      if (ensureTypeSafety) {

        if (_.isNull(value)) { /* `null` is always (unless it's required, but we already dealt w/ that above) */ }
        else {

          // Verify that this matches the expected type, and potentially coerce the value
          // at the same time.  This throws an E_INVALID error if validation fails.
          value = rttc.validate(correspondingAttrDef.type, value);

        }//>-•

      }//>-•

    }//</else (i.e. corresponding attr def is just a normal attr--not an association)>

  }//</else (i.e. there is a corresponding attr of some kind>

  // Return the normalized value.
  return value;

};
<|endoftext|>


<commit_before>export default function (db, idGeschaeft, idKontakt) {
  return new Promise((resolve, reject) => {
    const sql = `
      DELETE FROM
        geschaefteKontakteExtern
      WHERE
        idGeschaeft = ${idGeschaeft}
        AND idKontakt = ${idKontakt}`

    db.run(sql, (error) => {
      if (error) reject(error)
      resolve(true)
    })
  })
}
<commit_msg>move db<commit_after>export default (db, idGeschaeft, idKontakt) => {
  const sql = `
    DELETE FROM
      geschaefteKontakteExtern
    WHERE
      idGeschaeft = @idGeschaeft
      AND idKontakt = @idKontakt`

  try {
    db.prepare(sql).run({ idGeschaeft, idKontakt })
  } catch (error) {
    throw error
  }
  return true
}
<|endoftext|>


<commit_before>window.Rendxx = window.Rendxx || {};
window.Rendxx.Game = window.Rendxx.Game || {};
window.Rendxx.Game.Ghost = window.Rendxx.Game.Ghost || {};
window.Rendxx.Game.Ghost.System = window.Rendxx.Game.Ghost.System || {};

/**
 * Core entry of Game.Ghost system
 */
(function (SYSTEM) {
    var Data = SYSTEM.Data;
    /**
     * Game Entity
     */
    var Core = function () {
        // data ---------------------------------------------------
        var that = this,
            isStarted = false,
            gameData = {},          // store all data in the game, use to render
            intervalFunc = null,
            flag_started = false,
            flag_setuped = false,
            check_count = 0;        // count left to send full data

        // component ----------------------------------------------
        this.map = null;
        this.sound = null;
        this.noise = null;
        this.effort = null;
        this.quickTimeEvent = null;
        this.message = null;
        this.userInput = null;
        this.interAction = null;
        this.characterManager = null;

        // message -----------------------------------------------
        this.send = null;

        this.receive = function (msg) {
        };

        this.action = function (clientId, dat) {
            if (!isStarted) return;
            this.userInput.action(clientId, dat);
        };

        // callback -----------------------------------------------
        this.onUpdated = null;       // callback for render
        this.onSetuped = null;
        this.clientSetup = null;    // (target, clientData)
        this.clientUpdate = null;   // (target, clientData)
        this.onEnd = null;          // (isWin)

        // public method ------------------------------------------
        // reset game with given data
        this.reset = function (setupData_in, gameData_in) {
            if (setupData_in === undefined || setupData_in === null) return;
            gameData.map = [{}, {}];                // [ all data , modified data ]
            gameData.characters = [[], []];         // [ basic data , assist data ]
            gameData.qte = {};
            gameData.map[0] = gameData_in[0];
            gameData.characters[0] = gameData_in[1];
            initComponent(setupData_in.model, setupData_in.map, setupData_in.player);
            this.characterManager.reset(setupData_in.player, (gameData_in !== null && gameData_in !== undefined) ? gameData_in[1] : null);
            this.map.reset(setupData_in.mapSetup);
            this.interAction.reset();
            this.userInput.reset(this.characterManager.characters, this.characterManager.index2Id);
            flag_setuped = true;
            if (flag_started && !isStarted) this.start();
        };

        // setup game
        this.setup = function (modelData, mapData, playerData) {
            gameData.map = [{}, {}];                // [ all data , modified data ]
            gameData.characters = [[], []];         // [ basic data , assist data ]
            gameData.qte = {};
            initComponent(modelData, mapData, playerData);
            this.map.setup();
            this.interAction.reset();
            this.characterManager.setup(this.map.position.survivor, this.map.position.ghost);
            this.map.setElecticNeed(this.characterManager.survivorNumber+1);
            this.userInput.reset(this.characterManager.characters, this.characterManager.index2Id);
            var setupData = {
                'model': modelData,
                'map': mapData,
                'mapSetup': this.map.setupData,
                'player': this.characterManager.setupData
            };

            flag_setuped = true;
            for (var i in playerData) {
                this.clientSetup([i], {
                    role: playerData[i].role,
                    portrait: this.characterManager.characters[this.characterManager.id2Index[i]].modelData.portrait,
                    color: this.characterManager.characters[this.characterManager.id2Index[i]].color,
                    game: setupData
                });
            }
            this.onSetuped(setupData);
            if (flag_started && !isStarted) this.start();
        };

        // game ------------------------------------------------
        // start game
        this.start = function () {
            flag_started = true;
            if (flag_setuped === false) return;
            isStarted = true;
            if (intervalFunc !== null) clearInterval(intervalFunc);
            intervalFunc = setInterval(function () { nextInterval(); }, 40);
        };

        // end game
        this.end = function () {
            isStarted = false;
            if (intervalFunc !== null) clearInterval(intervalFunc);

            gameData['end'] = this.characterManager.getEndInfo();
        };

        // renew game
        this.renew = function () {
            // to do
            isStarted = false;
            if (intervalFunc !== null) clearInterval(intervalFunc);

            intervalFunc = null;
        };

        // pause game
        this.pause = function () { };

        // continue game
        this.continue = function () { };

        // private method -----------------------------------------
        // handler update data
        var _update = function () {
            if (--check_count < 0) {
                check_count = 200;
                // full data

                for (var i = 0, len = that.characterManager.characters.length; i < len; i++) {
                    //if (that.characterManager.characters[i].role !== 'ghost') continue;
                    var id = that.characterManager.index2Id[i];
                    var assist = [];
                    assist[i] = gameData.characters[1][i];
                    that.clientUpdate([id], [
                        gameData.map[0],
                        gameData.characters[0],
                        assist,
                        gameData.message,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte
                    ]);
                }

                if (that.onUpdated) that.onUpdated(
                    [   // to RENDERER
                        gameData.map[0],
                        gameData.characters[0],
                        gameData.characters[1],
                        gameData.message,
                        gameData.sound,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte,
                        gameData.end
                    ],
                    [   // to SERVER
                        gameData.map[0],
                        gameData.characters[0]
                    ]);
            } else {
                for (var i = 0, len = that.characterManager.characters.length; i < len; i++) {
                    //if (that.characterManager.characters[i].role !== 'ghost') continue;
                    var id = that.characterManager.index2Id[i];
                    var assist = [];
                    assist[i] = gameData.characters[1][i];
                    that.clientUpdate([id], [
                        gameData.map[1],
                        gameData.characters[0],
                        assist,
                        gameData.message,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte
                    ]);
                }

                if (that.onUpdated) that.onUpdated(
                    [   // to RENDERER
                        gameData.map[1],
                        gameData.characters[0],
                        gameData.characters[1],
                        gameData.message,
                        gameData.sound,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte,
                        gameData.end
                    ],
                    [   // to SERVER
                        gameData.map[0],
                        gameData.characters[0]
                    ]);
            }
            gameData.map.updateData = {};
        };

        //var _test = 100;
        // called every time frame
        var nextInterval = function () {
            try {
                // ---------------------------------------
                //if (_test <= 0) {
                //    //that.noise.once(SYSTEM.Noise.Data.Name.Key, 10, 10);
                //    that.noise.once(Math.floor(Math.random() * 4), 10 + Math.floor(Math.random() * 20), 10 + Math.floor(Math.random() * 20));
                //    _test=30;
                //} else
                //_test--;

                // ---------------------------------------
                that.interAction.update();
                that.characterManager.update();
                that.quickTimeEvent.update();
                gameData.message = that.message.getNewMsg();
                gameData.sound = that.sound.getSoundDat();
                gameData.noise = that.noise.getNoiseDat();
                gameData.effort = that.effort.getEffortDat();
                var _isEnd = that.characterManager.checkEnd();
                if (_isEnd) { that.end(); }
                _update();
                if (_isEnd && that.onEnd) that.onEnd(gameData['end']);
            } catch (e) {
                //console.log(e);
            }
        };

        // init component
        var initComponent = function (modelData, mapData, playerData) {
            that.map = new SYSTEM.Map(that, modelData, mapData, gameData.map);
            that.characterManager = new SYSTEM.CharacterManager(that, modelData, playerData, gameData.characters);
            that.interAction = new SYSTEM.InterAction(that);
            that.message = new SYSTEM.Message();
            that.sound = new SYSTEM.Sound();
            that.noise = new SYSTEM.Noise(that);
            that.effort = new SYSTEM.Effort(that);
            that.quickTimeEvent = new SYSTEM.QuickTimeEvent(that, gameData.qte);
            that.userInput = new SYSTEM.UserInput(that);
        };
    };

    SYSTEM.Core = Core;
})(window.Rendxx.Game.Ghost.System);<commit_msg>disable survivor small screen<commit_after>window.Rendxx = window.Rendxx || {};
window.Rendxx.Game = window.Rendxx.Game || {};
window.Rendxx.Game.Ghost = window.Rendxx.Game.Ghost || {};
window.Rendxx.Game.Ghost.System = window.Rendxx.Game.Ghost.System || {};

/**
 * Core entry of Game.Ghost system
 */
(function (SYSTEM) {
    var Data = SYSTEM.Data;
    /**
     * Game Entity
     */
    var Core = function () {
        // data ---------------------------------------------------
        var that = this,
            isStarted = false,
            gameData = {},          // store all data in the game, use to render
            intervalFunc = null,
            flag_started = false,
            flag_setuped = false,
            check_count = 0;        // count left to send full data

        // component ----------------------------------------------
        this.map = null;
        this.sound = null;
        this.noise = null;
        this.effort = null;
        this.quickTimeEvent = null;
        this.message = null;
        this.userInput = null;
        this.interAction = null;
        this.characterManager = null;

        // message -----------------------------------------------
        this.send = null;

        this.receive = function (msg) {
        };

        this.action = function (clientId, dat) {
            if (!isStarted) return;
            this.userInput.action(clientId, dat);
        };

        // callback -----------------------------------------------
        this.onUpdated = null;       // callback for render
        this.onSetuped = null;
        this.clientSetup = null;    // (target, clientData)
        this.clientUpdate = null;   // (target, clientData)
        this.onEnd = null;          // (isWin)

        // public method ------------------------------------------
        // reset game with given data
        this.reset = function (setupData_in, gameData_in) {
            if (setupData_in === undefined || setupData_in === null) return;
            gameData.map = [{}, {}];                // [ all data , modified data ]
            gameData.characters = [[], []];         // [ basic data , assist data ]
            gameData.qte = {};
            gameData.map[0] = gameData_in[0];
            gameData.characters[0] = gameData_in[1];
            initComponent(setupData_in.model, setupData_in.map, setupData_in.player);
            this.characterManager.reset(setupData_in.player, (gameData_in !== null && gameData_in !== undefined) ? gameData_in[1] : null);
            this.map.reset(setupData_in.mapSetup);
            this.interAction.reset();
            this.userInput.reset(this.characterManager.characters, this.characterManager.index2Id);
            flag_setuped = true;
            if (flag_started && !isStarted) this.start();
        };

        // setup game
        this.setup = function (modelData, mapData, playerData) {
            gameData.map = [{}, {}];                // [ all data , modified data ]
            gameData.characters = [[], []];         // [ basic data , assist data ]
            gameData.qte = {};
            initComponent(modelData, mapData, playerData);
            this.map.setup();
            this.interAction.reset();
            this.characterManager.setup(this.map.position.survivor, this.map.position.ghost);
            this.map.setElecticNeed(this.characterManager.survivorNumber+1);
            this.userInput.reset(this.characterManager.characters, this.characterManager.index2Id);
            var setupData = {
                'model': modelData,
                'map': mapData,
                'mapSetup': this.map.setupData,
                'player': this.characterManager.setupData
            };

            flag_setuped = true;
            for (var i in playerData) {
                this.clientSetup([i], {
                    role: playerData[i].role,
                    portrait: this.characterManager.characters[this.characterManager.id2Index[i]].modelData.portrait,
                    color: this.characterManager.characters[this.characterManager.id2Index[i]].color,
                    game: setupData
                });
            }
            this.onSetuped(setupData);
            if (flag_started && !isStarted) this.start();
        };

        // game ------------------------------------------------
        // start game
        this.start = function () {
            flag_started = true;
            if (flag_setuped === false) return;
            isStarted = true;
            if (intervalFunc !== null) clearInterval(intervalFunc);
            intervalFunc = setInterval(function () { nextInterval(); }, 40);
        };

        // end game
        this.end = function () {
            isStarted = false;
            if (intervalFunc !== null) clearInterval(intervalFunc);

            gameData['end'] = this.characterManager.getEndInfo();
        };

        // renew game
        this.renew = function () {
            // to do
            isStarted = false;
            if (intervalFunc !== null) clearInterval(intervalFunc);

            intervalFunc = null;
        };

        // pause game
        this.pause = function () { };

        // continue game
        this.continue = function () { };

        // private method -----------------------------------------
        // handler update data
        var _update = function () {
            if (--check_count < 0) {
                check_count = 200;
                // full data

                for (var i = 0, len = that.characterManager.characters.length; i < len; i++) {
                    if (that.characterManager.characters[i].role !== 'ghost') continue;
                    var id = that.characterManager.index2Id[i];
                    var assist = [];
                    assist[i] = gameData.characters[1][i];
                    that.clientUpdate([id], [
                        gameData.map[0],
                        gameData.characters[0],
                        assist,
                        gameData.message,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte
                    ]);
                }

                if (that.onUpdated) that.onUpdated(
                    [   // to RENDERER
                        gameData.map[0],
                        gameData.characters[0],
                        gameData.characters[1],
                        gameData.message,
                        gameData.sound,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte,
                        gameData.end
                    ],
                    [   // to SERVER
                        gameData.map[0],
                        gameData.characters[0]
                    ]);
            } else {
                for (var i = 0, len = that.characterManager.characters.length; i < len; i++) {
                    if (that.characterManager.characters[i].role !== 'ghost') continue;
                    var id = that.characterManager.index2Id[i];
                    var assist = [];
                    assist[i] = gameData.characters[1][i];
                    that.clientUpdate([id], [
                        gameData.map[1],
                        gameData.characters[0],
                        assist,
                        gameData.message,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte
                    ]);
                }

                if (that.onUpdated) that.onUpdated(
                    [   // to RENDERER
                        gameData.map[1],
                        gameData.characters[0],
                        gameData.characters[1],
                        gameData.message,
                        gameData.sound,
                        gameData.noise,
                        gameData.effort,
                        gameData.qte,
                        gameData.end
                    ],
                    [   // to SERVER
                        gameData.map[0],
                        gameData.characters[0]
                    ]);
            }
            gameData.map.updateData = {};
        };

        //var _test = 100;
        // called every time frame
        var nextInterval = function () {
            try {
                // ---------------------------------------
                //if (_test <= 0) {
                //    //that.noise.once(SYSTEM.Noise.Data.Name.Key, 10, 10);
                //    that.noise.once(Math.floor(Math.random() * 4), 10 + Math.floor(Math.random() * 20), 10 + Math.floor(Math.random() * 20));
                //    _test=30;
                //} else
                //_test--;

                // ---------------------------------------
                that.interAction.update();
                that.characterManager.update();
                that.quickTimeEvent.update();
                gameData.message = that.message.getNewMsg();
                gameData.sound = that.sound.getSoundDat();
                gameData.noise = that.noise.getNoiseDat();
                gameData.effort = that.effort.getEffortDat();
                var _isEnd = that.characterManager.checkEnd();
                if (_isEnd) { that.end(); }
                _update();
                if (_isEnd && that.onEnd) that.onEnd(gameData['end']);
            } catch (e) {
                //console.log(e);
            }
        };

        // init component
        var initComponent = function (modelData, mapData, playerData) {
            that.map = new SYSTEM.Map(that, modelData, mapData, gameData.map);
            that.characterManager = new SYSTEM.CharacterManager(that, modelData, playerData, gameData.characters);
            that.interAction = new SYSTEM.InterAction(that);
            that.message = new SYSTEM.Message();
            that.sound = new SYSTEM.Sound();
            that.noise = new SYSTEM.Noise(that);
            that.effort = new SYSTEM.Effort(that);
            that.quickTimeEvent = new SYSTEM.QuickTimeEvent(that, gameData.qte);
            that.userInput = new SYSTEM.UserInput(that);
        };
    };

    SYSTEM.Core = Core;
})(window.Rendxx.Game.Ghost.System);<|endoftext|>


<commit_before>var Application = Application || {};

Application.Constants = angular.module('application.core.constants', []);
Application.Services = angular.module('application.core.services', []);
Application.Controllers = angular.module('application.core.controllers', []);
Application.Filters = angular.module('application.core.filters', []);
Application.Directives = angular.module('application.core.directives', []);

Application.Provenance = {};
Application.Provenance.Constants = angular.module('application.provenance.constants', []);
Application.Provenance.Services = angular.module('application.provenance.services', []);
Application.Provenance.Controllers = angular.module('application.provenance.controllers', []);
Application.Provenance.Filters = angular.module('application.provenance.filters', []);
Application.Provenance.Directives = angular.module('application.provenance.directives', []);

var app = angular.module('materialscommons',
    [
        'ui',
        'ui.bootstrap',
        'ngCookies',
        'ui.router',
        'ngQuickDate',
        'btford.socket-io',
        'restangular',
        'jmdobry.angular-cache',
        'application.core.constants', 'application.core.services', 'application.core.controllers',
        'application.core.filters', 'application.core.directives',
        'application.provenance.constants', 'application.provenance.services', 'application.provenance.controllers',
        'application.provenance.filters', 'application.provenance.directives']);
// This factory needs to hang off of this module for some reason
app.factory('msocket', ["socketFactory", function (socketFactory) {
    var msocket = socketFactory({
        ioSocket: io.connect('http://localhost:8082')
    });
    msocket.forward('file');
    msocket.forward('connect');
    msocket.forward('disconnect');
    msocket.forward('error');
    return msocket;
}]);

app.config(["$stateProvider", function ($stateProvider) {
    mcglobals = {};
    doConfig();
    $stateProvider
        // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/home/home.html'
        })
        .state('toolbar', {
            url: '/toolbar',
            templateUrl: 'application/core/toolbar/toolbar.html'
        })
        .state('about', {
            url: '/about',
            templateUrl: 'application/core/about/about.html'
        })
        .state('contact', {
            url: '/contact',
            templateUrl: 'application/core/contact/contact.html'
        })
        .state('help', {
            url: '/help',
            templateUrl: 'application/core/help/help.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'logout'
        })

        // Account
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.groupcreate', {
            url: '/groupcreate',
            templateUrl: 'application/core/account/groupcreate/groupcreate.html'
        })
        .state('account.groupusers', {
            url: '/groupusers/:id',
            templateUrl: 'application/core/account/groupusers/groupusers.html'
        })
        // Toolbar drafts
        .state('toolbar.drafts', {
            url: '/drafts',
            templateUrl: 'application/core/toolbar/drafts/drafts.html'
        })
        // Toolbar Data Views
        .state('toolbar.mydatapage', {
            url: '/mydatapage',
            templateUrl: 'application/core/toolbar/mydatapage/mydatapage.html'
        })
        .state('toolbar.mydata', {
            url: '/mydata',
            templateUrl: 'application/core/toolbar/mydata/mydata.html'
        })
        .state('toolbar.thumbnails', {
            url: '/thumbnails',
            templateUrl: 'application/core/toolbar/thumbnails/thumbnails.html'
        })
        .state('toolbar.dataedit', {
            url: '/dataedit/:id',
            templateUrl: 'application/core/toolbar/dataedit/dataedit.html'
        })
        .state('toolbar.databytag', {
            url: '/databytag/:name',
            templateUrl: 'application/core/toolbar/databytag/databytag.html'
        })

        // Toolbar tag views
        .state('toolbar.tagspage', {
            url: '/tagspage',
            templateUrl: 'application/core/toolbar/tagspage/tagspage.html'
        })
        .state('toolbar.tags', {
            url: '/tags',
            templateUrl: 'application/core/toolbar/tags/tags.html'
        })
        .state('toolbar.globaltagcloud', {
            url: '/globaltagcloud',
            templateUrl: 'application/core/toolbar/globaltagcloud/globaltagcloud.html'
        })

        // Toolbar review views
        .state('toolbar.reviews', {
            url: '/reviews',
            templateUrl: 'application/core/toolbar/reviews/reviews.html'
        })

        // Toolbar machine views
        .state('toolbar.machines', {
            url: '/machines',
            templateUrl: 'application/core/toolbar/machines/machines.html'
        })

        // Toolbar materials views
//        .state('toolbar.materials', {
//            url: '/materials',
//            templateUrl: 'application/core/toolbar/materials/materials.html'
//        })

        // Toolbar materials views
        .state('toolbar.samples', {
            url: '/samples',
            templateUrl: 'application/core/toolbar/samples/samples.html'
        })

        // Toolbar overview
        .state('toolbar.overview', {
            url: '/overview',
            templateUrl: 'application/core/toolbar/overview/overview.html'
        })

        // Toolbar projectspage views
        .state('toolbar.projectspage', {
            url: '/projectspage/:id/:draft_id',
            templateUrl: 'application/core/toolbar/projectspage/projectspage.html',
            resolve: {
                ProvDrafts: "ProvDrafts"
            },
            onExit: function (ProvDrafts) {
                if (ProvDrafts.current && ProvDrafts.current.attributes.process.name !== "") {
                    ProvDrafts.saveDraft();
                }
            }
        })
        .state('toolbar.projectspage.overview', {
            url: '/overview',
            templateUrl: 'application/core/toolbar/projectspage/overview/overview.html'
        })
        .state('toolbar.projectspage.provenance', {
            url: '/provenance',
            templateUrl: 'application/provenance/provenance.html'
        })
        .state('toolbar.projectspage.provenance.process', {
            url: '/process',
            templateUrl: 'application/provenance/process/process.html'

        })
        .state('toolbar.projectspage.provenance.iosteps', {
            url: '/iosteps:iosteps',
            templateUrl: 'application/provenance/iosteps/iosteps.html'
        })
        .state('toolbar.projectspage.provenance.iosteps.iostep', {
            url: '/iostep:iostep',
            templateUrl: 'application/provenance/iosteps/iostep/iostep.html'
        })
        .state('toolbar.projectspage.provenance.iosteps.files', {
            url: '/files:iostep',
            templateUrl: 'application/provenance/iosteps/files/files.html'
        })
        .state('toolbar.projectspage.provenance.finish', {
            url: '/finish',
            templateUrl: 'application/provenance/finish/finish.html'
        })
        // File services
        .state('toolbar.fileservices', {
            url: '/fileservices',
            templateUrl: 'application/core/toolbar/fileservices/fileservices.html'
        })
        .state('toolbar.fileservices.projects', {
            url: '/projects',
            templateUrl: 'application/core/toolbar/fileservices/projects/projects.html'
        })
        .state('toolbar.fileservices.events', {
            url: '/events',
            templateUrl: 'application/core/toolbar/fileservices/events/events.html'
        })
        .state('toolbar.fileservices.config', {
            url: '/config',
            templateUrl: 'application/core/toolbar/fileservices/config/config.html'
        });
}]);

app.run(["$rootScope", "User", function ($rootScope, User) {
    $rootScope.$on('$stateChangeStart', function () {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
        }
    });
}]);
<commit_msg>Right now comment out socketio calls.<commit_after>var Application = Application || {};

Application.Constants = angular.module('application.core.constants', []);
Application.Services = angular.module('application.core.services', []);
Application.Controllers = angular.module('application.core.controllers', []);
Application.Filters = angular.module('application.core.filters', []);
Application.Directives = angular.module('application.core.directives', []);

Application.Provenance = {};
Application.Provenance.Constants = angular.module('application.provenance.constants', []);
Application.Provenance.Services = angular.module('application.provenance.services', []);
Application.Provenance.Controllers = angular.module('application.provenance.controllers', []);
Application.Provenance.Filters = angular.module('application.provenance.filters', []);
Application.Provenance.Directives = angular.module('application.provenance.directives', []);

var app = angular.module('materialscommons',
    [
        'ui',
        'ui.bootstrap',
        'ngCookies',
        'ui.router',
        'ngQuickDate',
        'btford.socket-io',
        'restangular',
        'jmdobry.angular-cache',
        'application.core.constants', 'application.core.services', 'application.core.controllers',
        'application.core.filters', 'application.core.directives',
        'application.provenance.constants', 'application.provenance.services', 'application.provenance.controllers',
        'application.provenance.filters', 'application.provenance.directives']);
/*
// This factory needs to hang off of this module for some reason
app.factory('msocket', ["socketFactory", function (socketFactory) {
    var msocket = socketFactory({
        ioSocket: io.connect('http://localhost:8082')
    });
    msocket.forward('file');
    msocket.forward('connect');
    msocket.forward('disconnect');
    msocket.forward('error');
    return msocket;
}]);
*/

app.config(["$stateProvider", function ($stateProvider) {
    mcglobals = {};
    doConfig();
    $stateProvider
        // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/home/home.html'
        })
        .state('toolbar', {
            url: '/toolbar',
            templateUrl: 'application/core/toolbar/toolbar.html'
        })
        .state('about', {
            url: '/about',
            templateUrl: 'application/core/about/about.html'
        })
        .state('contact', {
            url: '/contact',
            templateUrl: 'application/core/contact/contact.html'
        })
        .state('help', {
            url: '/help',
            templateUrl: 'application/core/help/help.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'logout'
        })

        // Account
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.groupcreate', {
            url: '/groupcreate',
            templateUrl: 'application/core/account/groupcreate/groupcreate.html'
        })
        .state('account.groupusers', {
            url: '/groupusers/:id',
            templateUrl: 'application/core/account/groupusers/groupusers.html'
        })
        // Toolbar drafts
        .state('toolbar.drafts', {
            url: '/drafts',
            templateUrl: 'application/core/toolbar/drafts/drafts.html'
        })
        // Toolbar Data Views
        .state('toolbar.mydatapage', {
            url: '/mydatapage',
            templateUrl: 'application/core/toolbar/mydatapage/mydatapage.html'
        })
        .state('toolbar.mydata', {
            url: '/mydata',
            templateUrl: 'application/core/toolbar/mydata/mydata.html'
        })
        .state('toolbar.thumbnails', {
            url: '/thumbnails',
            templateUrl: 'application/core/toolbar/thumbnails/thumbnails.html'
        })
        .state('toolbar.dataedit', {
            url: '/dataedit/:id',
            templateUrl: 'application/core/toolbar/dataedit/dataedit.html'
        })
        .state('toolbar.databytag', {
            url: '/databytag/:name',
            templateUrl: 'application/core/toolbar/databytag/databytag.html'
        })

        // Toolbar tag views
        .state('toolbar.tagspage', {
            url: '/tagspage',
            templateUrl: 'application/core/toolbar/tagspage/tagspage.html'
        })
        .state('toolbar.tags', {
            url: '/tags',
            templateUrl: 'application/core/toolbar/tags/tags.html'
        })
        .state('toolbar.globaltagcloud', {
            url: '/globaltagcloud',
            templateUrl: 'application/core/toolbar/globaltagcloud/globaltagcloud.html'
        })

        // Toolbar review views
        .state('toolbar.reviews', {
            url: '/reviews',
            templateUrl: 'application/core/toolbar/reviews/reviews.html'
        })

        // Toolbar machine views
        .state('toolbar.machines', {
            url: '/machines',
            templateUrl: 'application/core/toolbar/machines/machines.html'
        })

        // Toolbar materials views
//        .state('toolbar.materials', {
//            url: '/materials',
//            templateUrl: 'application/core/toolbar/materials/materials.html'
//        })

        // Toolbar materials views
        .state('toolbar.samples', {
            url: '/samples',
            templateUrl: 'application/core/toolbar/samples/samples.html'
        })

        // Toolbar overview
        .state('toolbar.overview', {
            url: '/overview',
            templateUrl: 'application/core/toolbar/overview/overview.html'
        })

        // Toolbar projectspage views
        .state('toolbar.projectspage', {
            url: '/projectspage/:id/:draft_id',
            templateUrl: 'application/core/toolbar/projectspage/projectspage.html',
            resolve: {
                ProvDrafts: "ProvDrafts"
            },
            onExit: function (ProvDrafts) {
                if (ProvDrafts.current && ProvDrafts.current.attributes.process.name !== "") {
                    ProvDrafts.saveDraft();
                }
            }
        })
        .state('toolbar.projectspage.overview', {
            url: '/overview',
            templateUrl: 'application/core/toolbar/projectspage/overview/overview.html'
        })
        .state('toolbar.projectspage.provenance', {
            url: '/provenance',
            templateUrl: 'application/provenance/provenance.html'
        })
        .state('toolbar.projectspage.provenance.process', {
            url: '/process',
            templateUrl: 'application/provenance/process/process.html'

        })
        .state('toolbar.projectspage.provenance.iosteps', {
            url: '/iosteps:iosteps',
            templateUrl: 'application/provenance/iosteps/iosteps.html'
        })
        .state('toolbar.projectspage.provenance.iosteps.iostep', {
            url: '/iostep:iostep',
            templateUrl: 'application/provenance/iosteps/iostep/iostep.html'
        })
        .state('toolbar.projectspage.provenance.iosteps.files', {
            url: '/files:iostep',
            templateUrl: 'application/provenance/iosteps/files/files.html'
        })
        .state('toolbar.projectspage.provenance.finish', {
            url: '/finish',
            templateUrl: 'application/provenance/finish/finish.html'
        })
        // File services
        .state('toolbar.fileservices', {
            url: '/fileservices',
            templateUrl: 'application/core/toolbar/fileservices/fileservices.html'
        })
        .state('toolbar.fileservices.projects', {
            url: '/projects',
            templateUrl: 'application/core/toolbar/fileservices/projects/projects.html'
        })
        .state('toolbar.fileservices.events', {
            url: '/events',
            templateUrl: 'application/core/toolbar/fileservices/events/events.html'
        })
        .state('toolbar.fileservices.config', {
            url: '/config',
            templateUrl: 'application/core/toolbar/fileservices/config/config.html'
        });
}]);

app.run(["$rootScope", "User", function ($rootScope, User) {
    $rootScope.$on('$stateChangeStart', function () {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
        }
    });
}]);
<|endoftext|>


<commit_before>var Application = Application || {};

Application.Constants = angular.module('application.core.constants', []);
Application.Services = angular.module('application.core.services', []);
Application.Controllers = angular.module('application.core.controllers', []);
Application.Filters = angular.module('application.core.filters', []);
Application.Directives = angular.module('application.core.directives', []);

var app = angular.module('materialscommons',
                         [
                             'ui',
                             'ngCookies',
                             'ui.router',
                             'btford.socket-io',
                             'restangular',
                             'jmdobry.angular-cache',
                             'validation', 'validation.rule',  'wu.masonry',
                             'textAngular',
                             'treeGrid',
                             'ngDragDrop',
                             'ng-context-menu',
                             "cfp.hotkeys",
                             '$strap.directives', 'ui.bootstrap', 'toastr',
                             'application.core.constants', 'application.core.services', 'application.core.controllers',
                             'application.core.filters', 'application.core.directives']);

// This factory needs to hang off of this module for some reason
app.factory('msocket', ["socketFactory", function (socketFactory) {
    var msocket = socketFactory({
        ioSocket: io.connect('https://localhost:8082')
    });
    msocket.forward('file');
    msocket.forward('connect');
    msocket.forward('disconnect');
    msocket.forward('error');
    return msocket;
}]);

app.config(["$stateProvider", "$validationProvider", function ($stateProvider, $validationProvider) {

    mcglobals = {};
    doConfig();
    $stateProvider
    // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/home/home.html'
        })
        .state('about', {
            url: '/about',
            templateUrl: 'application/core/about/about.html'
        })
        .state('modal', {
            url: '/modal',
            templateUrl: 'application/core/modal/test.html'
        })
        .state('sub', {
            url: '/sub',
            templateUrl: 'application/core/modal/sub.html'
        })
        .state('contact', {
            url: '/contact',
            templateUrl: 'application/core/contact/contact.html'
        })
        .state('help', {
            url: '/help',
            templateUrl: 'application/core/help/help.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'logout'
        })
        .state('reviews', {
            url: '/reviews',
            templateUrl: 'application/core/reviews/reviews.html'
        })
        .state('machines', {
            url: '/machines',
            templateUrl: 'application/core/machines/machines.html'
        })

    /*
     ########################################################################
     ####################### Account ##################################
     ########################################################################
     */
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.password', {
            url: '/password',
            templateUrl: 'application/core/account/password/password.html'
        })
        .state('account.apikey', {
            url: '/apikey',
            templateUrl: 'application/core/account/apikey/apikey.html'
        })
        .state('account.usergroup', {
            url: '/usergroup',
            templateUrl: 'application/core/account/usergroups/usergroup.html'
        })
        .state('account.usergroup.users', {
            url: '/users/:id',
            templateUrl: 'application/core/account/usergroups/users.html'
        })
        .state('account.templates', {
            url: '/templates',
            templateUrl: 'application/core/account/templates/templates.html'
        })

    /*
     ########################################################################
     ########################### Projects ###################################
     ########################################################################
     */
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
            resolve: {
                Projects: "model.projects",
                projects: function (Projects) {
                    return Projects.getList();
                },

                Templates: "model.templates",
                templates: function(Templates) {
                    return Templates.getList();
                }
            }
        })
        .state('projects.project', {
            url: '/project/:id',
            templateUrl: 'application/core/projects/project/project.html',
            resolve: {
                project: ["$stateParams", "model.projects", "projects", "templates", function ($stateParams, Projects, projects, templates) {
                    // We use templates as a dependency so that they are all loaded before getting to this step.
                    // Otherwise the order of items being resolved isn't in the order we need them.
                    return Projects.get($stateParams.id);
                }]
            },
            controller: "projectsProject"
        })
        .state('projects.project.home', {
            url: '/home',
            templateUrl: 'application/core/projects/project/home/home.html',
            controller: "projectHome"
        })
        .state('projects.project.files', {
            url: '/files',
            templateUrl: 'application/core/projects/project/files/files.html'
        })
        .state('projects.project.files.view', {
            url: '/view',
            templateUrl: 'application/core/projects/project/files/view.html'
        })
        .state('projects.project.samples', {
            url: '/samples',
            templateUrl: 'application/core/projects/project/samples/samples.html',
            controller: "projectSamples"
        })
        .state('projects.project.samples.overview', {
            url: '/overview',
            templateUrl: "application/core/projects/project/samples/overview.html",
            controller: "projectSamplesOverview"
        })
        .state('projects.project.samples.create', {
            url: '/create',
            templateUrl: 'application/core/projects/project/samples/create.html',
            controller: "projectSamplesCreate"
        })
        .state('projects.project.provenance', {
            url: '/provenance',
            templateUrl: 'application/core/projects/project/provenance/provenance.html',
            controller: "projectProvenance"
        })
        .state('projects.project.provenance.overview', {
            url: '/overview',
            templateUrl: 'application/core/projects/project/provenance/overview.html',
            controller: 'projectProvenanceOverview'
        })
        .state('projects.project.provenance.create', {
            url: '/create/:sid',
            templateUrl: 'application/core/projects/project/provenance/create.html',
            controller: "projectProvenanceCreate"
        })
        .state('projects.project.reviews', {
            url: '/reviews',
            templateUrl: 'application/core/projects/project/reviews/reviews.html',
            controller: "projectReviews"
        })
        .state('projects.project.reviews.overview', {
            url: "/createreview",
            templateUrl: "application/core/projects/project/reviews/overview.html",
            controller: "projectReviewsOverview"
        })
        .state('projects.project.reviews.create', {
            url: "/createreview",
            templateUrl: "application/core/projects/project/reviews/create.html",
            controller: "projectReviewsCreate"
        })
        .state('projects.project.notes', {
            url: '/notes',
            templateUrl: 'application/core/projects/project/notes/notes.html',
            controller: "projectNotes"
        })
        .state('projects.project.createnote', {
            url: '/createnote',
            templateUrl: "application/core/projects/project/notes/create.html",
            controller: "projectNotesCreate"
        });

    $validationProvider.setErrorHTML(function (msg) {
        return '' + msg + '';
    });

    $validationProvider.setSuccessHTML(function (msg) {
        return '' + msg + '';
    });

}]);

app.run(["$rootScope", "User", "Restangular", "recent", appRun]);

function appRun($rootScope, User, Restangular, recent) {
    Restangular.setBaseUrl(mcglobals.apihost);

    $rootScope.$on('$stateChangeStart', function () {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
        }
    });

    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
        var projectID = fromParams.id;
        if (!fromState.abstract) {
            recent.setLast(projectID, "ignore", fromState.name, fromParams);
        }
    });
}
<commit_msg>Add routes for notes and correct for reviews. Set last correctly and hide files as appropriate.<commit_after>var Application = Application || {};

Application.Constants = angular.module('application.core.constants', []);
Application.Services = angular.module('application.core.services', []);
Application.Controllers = angular.module('application.core.controllers', []);
Application.Filters = angular.module('application.core.filters', []);
Application.Directives = angular.module('application.core.directives', []);

var app = angular.module('materialscommons',
                         [
                             'ui',
                             'ngCookies',
                             'ui.router',
                             'btford.socket-io',
                             'restangular',
                             'jmdobry.angular-cache',
                             'validation', 'validation.rule',  'wu.masonry',
                             'textAngular',
                             'treeGrid',
                             'ngDragDrop',
                             'ng-context-menu',
                             "cfp.hotkeys",
                             '$strap.directives', 'ui.bootstrap', 'toastr',
                             'application.core.constants', 'application.core.services', 'application.core.controllers',
                             'application.core.filters', 'application.core.directives']);

// This factory needs to hang off of this module for some reason
app.factory('msocket', ["socketFactory", function (socketFactory) {
    var msocket = socketFactory({
        ioSocket: io.connect('https://localhost:8082')
    });
    msocket.forward('file');
    msocket.forward('connect');
    msocket.forward('disconnect');
    msocket.forward('error');
    return msocket;
}]);

app.config(["$stateProvider", "$validationProvider", function ($stateProvider, $validationProvider) {

    mcglobals = {};
    doConfig();
    $stateProvider
    // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/home/home.html'
        })
        .state('about', {
            url: '/about',
            templateUrl: 'application/core/about/about.html'
        })
        .state('modal', {
            url: '/modal',
            templateUrl: 'application/core/modal/test.html'
        })
        .state('sub', {
            url: '/sub',
            templateUrl: 'application/core/modal/sub.html'
        })
        .state('contact', {
            url: '/contact',
            templateUrl: 'application/core/contact/contact.html'
        })
        .state('help', {
            url: '/help',
            templateUrl: 'application/core/help/help.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'logout'
        })
        .state('reviews', {
            url: '/reviews',
            templateUrl: 'application/core/reviews/reviews.html'
        })
        .state('machines', {
            url: '/machines',
            templateUrl: 'application/core/machines/machines.html'
        })

    /*
     ########################################################################
     ####################### Account ##################################
     ########################################################################
     */
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.password', {
            url: '/password',
            templateUrl: 'application/core/account/password/password.html'
        })
        .state('account.apikey', {
            url: '/apikey',
            templateUrl: 'application/core/account/apikey/apikey.html'
        })
        .state('account.usergroup', {
            url: '/usergroup',
            templateUrl: 'application/core/account/usergroups/usergroup.html'
        })
        .state('account.usergroup.users', {
            url: '/users/:id',
            templateUrl: 'application/core/account/usergroups/users.html'
        })
        .state('account.templates', {
            url: '/templates',
            templateUrl: 'application/core/account/templates/templates.html'
        })

    /*
     ########################################################################
     ########################### Projects ###################################
     ########################################################################
     */
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
            resolve: {
                Projects: "model.projects",
                projects: function (Projects) {
                    return Projects.getList();
                },

                Templates: "model.templates",
                templates: function(Templates) {
                    return Templates.getList();
                }
            }
        })
        .state('projects.project', {
            url: '/project/:id',
            templateUrl: 'application/core/projects/project/project.html',
            resolve: {
                project: ["$stateParams", "model.projects", "projects", "templates", function ($stateParams, Projects, projects, templates) {
                    // We use templates as a dependency so that they are all loaded before getting to this step.
                    // Otherwise the order of items being resolved isn't in the order we need them.
                    return Projects.get($stateParams.id);
                }]
            },
            controller: "projectsProject"
        })
        .state('projects.project.home', {
            url: '/home',
            templateUrl: 'application/core/projects/project/home/home.html',
            controller: "projectHome"
        })
        .state('projects.project.files', {
            url: '/files',
            templateUrl: 'application/core/projects/project/files/files.html'
        })
        .state('projects.project.files.view', {
            url: '/view',
            templateUrl: 'application/core/projects/project/files/view.html'
        })
        .state('projects.project.samples', {
            url: '/samples',
            templateUrl: 'application/core/projects/project/samples/samples.html',
            controller: "projectSamples"
        })
        .state('projects.project.samples.overview', {
            url: '/overview',
            templateUrl: "application/core/projects/project/samples/overview.html",
            controller: "projectSamplesOverview"
        })
        .state('projects.project.samples.create', {
            url: '/create/:sid',
            templateUrl: 'application/core/projects/project/samples/create.html',
            controller: "projectSamplesCreate"
        })
        .state('projects.project.provenance', {
            url: '/provenance',
            templateUrl: 'application/core/projects/project/provenance/provenance.html',
            controller: "projectProvenance"
        })
        .state('projects.project.provenance.overview', {
            url: '/overview',
            templateUrl: 'application/core/projects/project/provenance/overview.html',
            controller: 'projectProvenanceOverview'
        })
        .state('projects.project.provenance.create', {
            url: '/create/:sid',
            templateUrl: 'application/core/projects/project/provenance/create.html',
            controller: "projectProvenanceCreate"
        })
        .state('projects.project.reviews', {
            url: '/reviews',
            templateUrl: 'application/core/projects/project/reviews/reviews.html',
            controller: "projectReviews"
        })
        .state('projects.project.reviews.overview', {
            url: "/overview",
            templateUrl: "application/core/projects/project/reviews/overview.html",
            controller: "projectReviewsOverview"
        })
        .state('projects.project.reviews.create', {
            url: "/create/:sid",
            templateUrl: "application/core/projects/project/reviews/create.html",
            controller: "projectReviewsCreate"
        })
        .state('projects.project.notes', {
            url: '/notes',
            templateUrl: 'application/core/projects/project/notes/notes.html',
            controller: "projectNotes"
        })
        .state('projects.project.notes.overview', {
            url: '/overview',
            templateUrl: "application/core/projects/project/notes/overview.html",
            controller: "projectNotesOverview"
        })
        .state('projects.project.notes.create', {
            url: '/create/:sid',
            templateUrl: "application/core/projects/project/notes/create.html",
            controller: "projectNotesCreate"
        });

    $validationProvider.setErrorHTML(function (msg) {
        return '' + msg + '';
    });

    $validationProvider.setSuccessHTML(function (msg) {
        return '' + msg + '';
    });

}]);

app.run(["$rootScope", "User", "Restangular", "recent", "ui", appRun]);

function appRun($rootScope, User, Restangular, recent, ui) {
    Restangular.setBaseUrl(mcglobals.apihost);

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
            ui.setShowFiles(toParams.id, false);
        }
    });

    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
        var projectID = fromParams.id;
        if (!fromState.abstract) {
            recent.pushLast(projectID, "ignore", fromState.name, fromParams);
        }
    });
}
<|endoftext|>


<commit_before>/*!
 * Module dependencies.
 */

var _ = require('underscore'),
	util = require('util'),
	utils = require('keystone-utils'),
	marked = require('marked'),
	super_ = require('../field');

/**
 * Markdown FieldType Constructor
 * @extends Field
 * @api public
 */

function markdown(list, path, options) {

	// TODO: implement filtering, usage disabled for now
	options.nofilter = true;

	this.height = options.height || 90;
	markdown.super_.call(this, list, path, options);

}

/*!
 * Inherit from Field
 */

util.inherits(markdown, super_);

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * Adds String properties for .markdown and .html markdown, and a setter
 * for .markdown that generates html when it is updated.
 *
 * @api public
 */

markdown.prototype.addToSchema = function() {

	var schema = this.list.schema;

	var paths = this.paths = {
		md: this._path.append('.md'),
		html: this._path.append('.html')
	};

	var setMarkdown = function(value) {

		if (value == this.get(paths.md)) {
			return value;
		}

		if (typeof value == 'string') {
			this.set(paths.html, marked(value));
			return value;
		} else {
			this.set(paths.html, undefined);
			return undefined;
		}

	};

	schema.nested[this.path] = true;
	schema.add({
		html: { type: String },
		md: { type: String, set: setMarkdown }
	}, this.path + '.');

	this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 *
 * @api public
 */

markdown.prototype.format = function(item) {
	return item.get(this.paths.html);
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * Will accept either the field path, or paths.md
 *
 * @api public
 */

markdown.prototype.validateInput = function(data, required, item) {

	if (!(this.path in data || this.paths.md in data) && item && item.get(this.paths.md)) return true;

	return (!required || data[this.path] || data[this.paths.md]) ? true : false;

};

/**
 * Detects whether the field has been modified
 *
 * @api public
 */

markdown.prototype.isModified = function(item) {
	return item.isModified(this.paths.md);
};

/**
 * Updates the value for this field in the item from a data object
 *
 * Will accept either the field path, or paths.md
 *
 * @api public
 */

markdown.prototype.updateItem = function(item, data) {

	if (this.path in data) {
		item.set(this.paths.md, data[this.path]);
	} else if (this.paths.md in data) {
		item.set(this.paths.md, data[this.paths.md]);
	}

};

/*!
 * Export class
 */

exports = module.exports = markdown;
<commit_msg>Fixing linter errors in fieldTypes/markdown<commit_after>/*!
 * Module dependencies.
 */

var util = require('util'),
	marked = require('marked'),
	super_ = require('../field');

/**
 * Markdown FieldType Constructor
 * @extends Field
 * @api public
 */

function markdown(list, path, options) {

	// TODO: implement filtering, usage disabled for now
	options.nofilter = true;

	this.height = options.height || 90;
	markdown.super_.call(this, list, path, options);

}

/*!
 * Inherit from Field
 */

util.inherits(markdown, super_);

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * Adds String properties for .markdown and .html markdown, and a setter
 * for .markdown that generates html when it is updated.
 *
 * @api public
 */

markdown.prototype.addToSchema = function() {

	var schema = this.list.schema;

	var paths = this.paths = {
		md: this._path.append('.md'),
		html: this._path.append('.html')
	};

	var setMarkdown = function(value) {

		if (value === this.get(paths.md)) {
			return value;
		}

		if (typeof value === 'string') {
			this.set(paths.html, marked(value));
			return value;
		} else {
			this.set(paths.html, undefined);
			return undefined;
		}

	};

	schema.nested[this.path] = true;
	schema.add({
		html: { type: String },
		md: { type: String, set: setMarkdown }
	}, this.path + '.');

	this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 *
 * @api public
 */

markdown.prototype.format = function(item) {
	return item.get(this.paths.html);
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * Will accept either the field path, or paths.md
 *
 * @api public
 */

markdown.prototype.validateInput = function(data, required, item) {

	if (!(this.path in data || this.paths.md in data) && item && item.get(this.paths.md)) return true;

	return (!required || data[this.path] || data[this.paths.md]) ? true : false;

};

/**
 * Detects whether the field has been modified
 *
 * @api public
 */

markdown.prototype.isModified = function(item) {
	return item.isModified(this.paths.md);
};

/**
 * Updates the value for this field in the item from a data object
 *
 * Will accept either the field path, or paths.md
 *
 * @api public
 */

markdown.prototype.updateItem = function(item, data) {

	if (this.path in data) {
		item.set(this.paths.md, data[this.path]);
	} else if (this.paths.md in data) {
		item.set(this.paths.md, data[this.paths.md]);
	}

};

/*!
 * Export class
 */

exports = module.exports = markdown;
<|endoftext|>


<commit_before>var Slm = require('./slm');

function Interpolate() {
  this._escapedInterpolationRe = /^\\\$\{/;
  this._interpolationRe = /^\$\{/;
  this._staticTextRe = /^([\$\\]?[^\$\\]*([\$\\][^\\\$\{][^\$\\]*)*)/;
}

var InterpolateProto = Interpolate.prototype = new Slm();

InterpolateProto.on_slm_interpolate = function(exps) {
  var str = exps[2], m, code;

  // Interpolate variables in text (${variable}).
  // Split the text into multiple dynamic and static parts.
  var block = ['multi'];
  do {
    // Escaped interpolation
    m = this._escapedInterpolationRe.exec(str);
    if (m) {
      block.push(['static', '${']);
      str = str.slice(m[0].length);
    } else if (m = this._interpolationRe.exec(str)) {
      // Interpolation
      var res = this._parseExpression(str.slice(m[0].length));
      str = res[0];
      code = res[1];
      var escape = code[0] !== '=';
      block.push(['slm', 'output', escape, escape ? code : code.slice(1), ['multi']]);
    } else {
      m = this._staticTextRe.exec(str);
      // static text
      block.push(['static', m[0]]);
      str = str.slice(m[0].length);
    }
  } while (str.length);

  return block;
};

InterpolateProto._parseExpression = function(str) {
  for (var count = 1, i = 0, l = str.length; i < l && count; i++) {
    if (str[i] === '{') {
      count++;
    } else if (str[i] === '}') {
      count--;
    }
  }

  if (count) {
    throw new Error('Text interpolation: Expected closing }');
  }

  return [str.slice(i), str.substring(0, i - 1)];
};

module.exports = Interpolate;
<commit_msg>Code style<commit_after>var Slm = require('./slm');

var _escapedInterpolationRe = /^\\\$\{/;
var _interpolationRe = /^\$\{/;
var _staticTextRe = /^([\$\\]?[^\$\\]*([\$\\][^\\\$\{][^\$\\]*)*)/;

function Interpolate() {}

var InterpolateProto = Interpolate.prototype = new Slm();

InterpolateProto.on_slm_interpolate = function(exps) {
  var str = exps[2], m, code;

  // Interpolate variables in text (${variable}).
  // Split the text into multiple dynamic and static parts.
  var block = ['multi'];
  do {
    // Escaped interpolation
    m = _escapedInterpolationRe.exec(str);
    if (m) {
      block.push(['static', '${']);
      str = str.slice(m[0].length);
      continue;
    }
    m = _interpolationRe.exec(str);
    if (m) {
      // Interpolation
      var res = this._parseExpression(str.slice(m[0].length));
      str = res[0];
      code = res[1];
      var escape = code[0] !== '=';
      block.push(['slm', 'output', escape, escape ? code : code.slice(1), ['multi']]);
    } else {
      m = _staticTextRe.exec(str);
      // static text
      block.push(['static', m[0]]);
      str = str.slice(m[0].length);
    }
  } while (str.length);

  return block;
};

InterpolateProto._parseExpression = function(str) {
  for (var count = 1, i = 0, l = str.length; i < l && count; i++) {
    if (str[i] === '{') {
      count++;
    } else if (str[i] === '}') {
      count--;
    }
  }

  if (count) {
    throw new Error('Text interpolation: Expected closing }');
  }

  return [str.slice(i), str.substring(0, i - 1)];
};

module.exports = Interpolate;
<|endoftext|>