<commit_before>gimel.module('imageTemplate').extend(function(moduleContent) {
    gimel.imageTemplate.extend(function(GimelImage) {
        /**
         * Convolve the image with the given kernel
         * @param {IntMask} kernel mask (image with one channel)
         * @param {boolean} normalize
         * @return {GimelImage} convolved image
         * @todo handle the sides
         */
        GimelImage.prototype.convolve = function(kernel, normalize) {
            console.assert(kernel.CHANNELS === 1, 'AbstractImage::convolute: Mask must have just one channel');
            console.assert(kernel.width === kernel.height, 'AbstractImage::convolute: Mask must be square');

            var convolvedImage = this.cloneStructure();
            var destData = convolvedImage.data;
            var srcData = this.data;
            var t = 0, tt = 0, tSrc = 0;

            var uu = kernel.width;
            var vv = kernel.height;
            var uu2 = kernel.width >> 1;
            var vv2 = kernel.height >> 1;

            var dx = this.dx;
            var dy = this.dy;
            var xx = this.width;
            var yy = this.height;
            var xx2 = xx - uu2;
            var yy2 = yy - vv2;

            var srcX, srcY;
            var u, v, x, y;
            var muv, offset;

            for (v = 0; v < vv; ++v) {
                for (u = 0; u < uu; ++u) {
                    muv = kernel.data[v*kernel.width + u];
                    for (y = 0; y < vv2; ++y) {
                        for (x = 0; x < xx2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = yy2; y < yy; ++y) {
                        for (x = 0; x < xx2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < yy ? srcY : 2*yy - srcY - 1)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = vv2; y < yy2; ++y) {
                        for (x = 0; x < uu2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = 0; y < yy2; ++y) {
                        for (x = xx2; x < xx; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < xx ? srcX : 2*xx - srcX - 1)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = yy2; y < yy; ++y) {
                        for (x = xx2; x < xx; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < xx ? srcX : 2*xx - srcX - 1)*dx + (srcY < yy ? srcY : 2*yy - srcY - 1)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }
                }
            }

            for (v = 0; v < vv; ++v) {
                for (u = 0; u < uu; ++u) {
                    muv = kernel.data[v*kernel.width + u];
                    offset = (u - uu2)*dx + (v - vv2)*dy;
                    for (y = vv2; y < yy2; ++y) {
                        var t0 = y*xx;
                        for (x = uu2; x < xx2; ++x) {
                            t = (t0 + x)*4;
                            destData[t] += srcData[t + offset]*muv;
                            destData[t + 1] += srcData[t + offset + 1]*muv;
                            destData[t + 2] += srcData[t + offset + 2]*muv;
                        }
                    }
                }
            }

            if (normalize) {
                var maskSum = 0;
                for (t = 0, tt = kernel.length; t < tt; ++t) {
                    maskSum += kernel.data[t];
                }

                if (maskSum !== 0) {
                    for (t = 0, tt = this.length; t < tt; t += 4) {
                        destData[t] /= maskSum;
                        destData[t + 1] /= maskSum;
                        destData[t + 2] /= maskSum;
                    }
                }
            }

            return convolvedImage;
        };

        /**
         * Compute image gradient using convolution
         * @return {GimelImage} Gradient image (new)
         * @todo kernel type according to image type (int or float)
         */
        GimelImage.prototype.gradient = function() {
            var kernel = new gimel.Int8T1ChImage(3, 3, [ 0, -1,  0,
                                                        -1,  0, +1,
                                                         0, +1,  0]);
            return this.convolve(kernel, false);
        }
    });

    return false;
});<commit_msg>Correct asserts<commit_after>gimel.module('imageTemplate').extend(function(moduleContent) {
    gimel.imageTemplate.extend(function(GimelImage) {
        /**
         * Convolve the image with the given kernel
         * @param {IntMask} kernel mask (image with one channel)
         * @param {boolean} normalize
         * @return {GimelImage} convolved image
         * @todo handle the sides
         */
        GimelImage.prototype.convolve = function(kernel, normalize) {
            console.assert(kernel.CHANNELS === 1, 'AbstractImage::convolve: Mask must have just one channel');
            console.assert(kernel.width === kernel.height, 'AbstractImage::convolve: Mask must be square');

            var convolvedImage = this.cloneStructure();
            var destData = convolvedImage.data;
            var srcData = this.data;
            var t = 0, tt = 0, tSrc = 0;

            var uu = kernel.width;
            var vv = kernel.height;
            var uu2 = kernel.width >> 1;
            var vv2 = kernel.height >> 1;

            var dx = this.dx;
            var dy = this.dy;
            var xx = this.width;
            var yy = this.height;
            var xx2 = xx - uu2;
            var yy2 = yy - vv2;

            var srcX, srcY;
            var u, v, x, y;
            var muv, offset;

            for (v = 0; v < vv; ++v) {
                for (u = 0; u < uu; ++u) {
                    muv = kernel.data[v*kernel.width + u];
                    for (y = 0; y < vv2; ++y) {
                        for (x = 0; x < xx2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = yy2; y < yy; ++y) {
                        for (x = 0; x < xx2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < yy ? srcY : 2*yy - srcY - 1)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = vv2; y < yy2; ++y) {
                        for (x = 0; x < uu2; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < 0 ? 1 - srcX : srcX)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = 0; y < yy2; ++y) {
                        for (x = xx2; x < xx; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < xx ? srcX : 2*xx - srcX - 1)*dx + (srcY < 0 ? 1 - srcY : srcY)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }

                    for (y = yy2; y < yy; ++y) {
                        for (x = xx2; x < xx; ++x) {
                            srcX = x + u - uu2;
                            srcY = y + v - vv2;
                            tSrc = x*dx + y*dy;
                            t = (srcX < xx ? srcX : 2*xx - srcX - 1)*dx + (srcY < yy ? srcY : 2*yy - srcY - 1)*dy;
                            destData[tSrc] += srcData[t]*muv;
                            destData[tSrc + 1] += srcData[t + 1]*muv;
                            destData[tSrc + 2] += srcData[t + 2]*muv;
                        }
                    }
                }
            }

            for (v = 0; v < vv; ++v) {
                for (u = 0; u < uu; ++u) {
                    muv = kernel.data[v*kernel.width + u];
                    offset = (u - uu2)*dx + (v - vv2)*dy;
                    for (y = vv2; y < yy2; ++y) {
                        var t0 = y*xx;
                        for (x = uu2; x < xx2; ++x) {
                            t = (t0 + x)*4;
                            destData[t] += srcData[t + offset]*muv;
                            destData[t + 1] += srcData[t + offset + 1]*muv;
                            destData[t + 2] += srcData[t + offset + 2]*muv;
                        }
                    }
                }
            }

            if (normalize) {
                var maskSum = 0;
                for (t = 0, tt = kernel.length; t < tt; ++t) {
                    maskSum += kernel.data[t];
                }

                if (maskSum !== 0) {
                    for (t = 0, tt = this.length; t < tt; t += 4) {
                        destData[t] /= maskSum;
                        destData[t + 1] /= maskSum;
                        destData[t + 2] /= maskSum;
                    }
                }
            }

            return convolvedImage;
        };

        /**
         * Compute image gradient using convolution
         * @return {GimelImage} Gradient image (new)
         * @todo kernel type according to image type (int or float)
         */
        GimelImage.prototype.gradient = function() {
            var kernel = new gimel.Int8T1ChImage(3, 3, [ 0, -1,  0,
                                                        -1,  0, +1,
                                                         0, +1,  0]);
            return this.convolve(kernel, false);
        }

        /**
         * Convolve image with gaussian kernel (blur)
         * Gaussian function: e^((-(x^2)-(y^2))/((s^2)/2))
         * @return {GimelImage} convolved image (new)
         * @todo kernel type according to image type (int or float)
         */
        GimelImage.prototype.gaussian = function(size) {
            console.assert(size & 1,  'AbstractImage::gaussian: Size has to be odd');
            console.assert(size >= 3, 'AbstractImage::gaussian: Size has to be at least 3');
            var kernel;
            switch (size) {
            case 3: kernel = new gimel.Float32T1ChImage(3, 3, [0.02, 0.14, 0.02,
                                                               0.14, 1.00, 0.14,
                                                               0.02, 0.14, 0.02]);
              break;
            case 5: kernel = new gimel.Float32T1ChImage(5, 5, [0.02, 0.08, 0.14, 0.08, 0.02,
                                                               0.08, 0.37, 0.61, 0.37, 0.08,
                                                               0.14, 0.61, 1.00, 0.61, 0.14,
                                                               0.08, 0.37, 0.61, 0.37, 0.08,
                                                               0.02, 0.08, 0.14, 0.08, 0.02]);
              break;
            case 7: kernel = new gimel.Float32T1ChImage(7, 7, [0.02, 0.06, 0.11, 0.14, 0.11, 0.06, 0.02,
                                                               0.06, 0.17, 0.33, 0.41, 0.33, 0.17, 0.06,
                                                               0.11, 0.33, 0.64, 0.80, 0.64, 0.33, 0.11,
                                                               0.14, 0.41, 0.80, 1.00, 0.80, 0.41, 0.14,
                                                               0.11, 0.33, 0.64, 0.80, 0.64, 0.33, 0.11,
                                                               0.06, 0.17, 0.33, 0.41, 0.33, 0.17, 0.06,
                                                               0.02, 0.06, 0.11, 0.14, 0.11, 0.06, 0.02]);
              break;
            default:
              var size2 = (size - 1) >> 1
              var data = [];
              for (i = 1, ii = size2 + 1; i < ii; i++) {
                for (j = 0, jj = size2 + 1; j < jj; j++) {
                  var value = Math.exp();
                  data[size2 + i][size2 + j] = value;
                  data[size2 + i][size2 - j] = value;
                  data[size2 - i][size2 + j] = value;
                  data[size2 - i][size2 - j] = value;
                  data[size2 + j][size2 + i] = value;
                  data[size2 + j][size2 - i] = value;
                  data[size2 - j][size2 + i] = value;
                  data[size2 - j][size2 - i] = value;
                }
              }
            }
            return this.convolve(kernel, true);
        }
    });

    return false;
});<|endoftext|>


<commit_before>var pkgVersion = require("./package.json").version;
var Ajv = require("ajv");
var util = require("util");

var contractObjectSchema = require("./spec/contract-object.spec.json");
var networkObjectSchema = require("./spec/network-object.spec.json");
var abiSchema = require("./spec/abi.spec.json");

/**
 * Property definitions for Contract Objects
 *
 * Describes canonical output properties as sourced from some "dirty" input
 * object. Describes normalization process to account for deprecated and/or
 * nonstandard keys and values.
 *
 * Maps (key -> property) where:
 *  - `key` is the top-level output key matching up with those in the schema
 *  - `property` is an object with optional values:
 *      - `sources`: list of sources (see below); default `key`
 *      - `transform`: function(value) -> transformed value; default x -> x
 *
 * Each source represents a means to select a value from dirty object.
 * Allows:
 *  - dot-separated (`.`) string, corresponding to path to value in dirty
 *    object
 *  - function(dirtyObj) -> (cleanValue | undefined)
 *
 * The optional `transform` parameter standardizes value regardless of source,
 * for purposes of ensuring data type and/or string schemas.
 */
var properties = {
  contractName: {
    sources: ["contractName", "contract_name"]
  },
  abi: {
    sources: ["abi", "interface"],
    transform: function(value) {
      if (typeof value === "string") {
        try {
          value = JSON.parse(value);
        } catch (e) {
          value = undefined;
        }
      } else if (typeof value === "object") {
        value.forEach(item => delete item.signature);
      }
      return value;
    }
  },
  metadata: {
    sources: ["metadata"]
  },
  bytecode: {
    sources: ["bytecode", "binary", "unlinked_binary", "evm.bytecode.object"],
    transform: function(value) {
      if (value && value.indexOf("0x") !== 0) {
        value = "0x" + value;
      }
      return value;
    }
  },
  deployedBytecode: {
    sources: [
      "deployedBytecode",
      "runtimeBytecode",
      "evm.deployedBytecode.object"
    ],
    transform: function(value) {
      if (value && value.indexOf("0x") !== 0) {
        value = "0x" + value;
      }
      return value;
    }
  },
  sourceMap: {
    sources: ["sourceMap", "srcmap", "evm.bytecode.sourceMap"]
  },
  deployedSourceMap: {
    sources: [
      "deployedSourceMap",
      "srcmapRuntime",
      "evm.deployedBytecode.sourceMap"
    ]
  },
  source: {},
  sourcePath: {},
  ast: {},
  legacyAST: {
    transform: function(value, obj) {
      var schemaVersion = obj.schemaVersion || "0.0.0";

      // legacyAST introduced in v2.0.0
      if (schemaVersion[0] < 2) {
        return obj.ast;
      } else {
        return value;
      }
    }
  },
  compiler: {},
  networks: {
    transform: function(value) {
      if (value === undefined) {
        value = {};
      }
      return value;
    }
  },
  schemaVersion: {
    sources: ["schemaVersion", "schema_version"]
  },
  updatedAt: {
    sources: ["updatedAt", "updated_at"],
    transform: function(value) {
      if (typeof value === "number") {
        value = new Date(value).toISOString();
      }
      return value;
    }
  },
  devdoc: {},
  userdoc: {}
};

/**
 * Construct a getter for a given key, possibly applying some post-retrieve
 * transformation on the resulting value.
 *
 * @return {Function} Accepting dirty object and returning value || undefined
 */
function getter(key, transform) {
  if (transform === undefined) {
    transform = function(x) {
      return x;
    };
  }

  return function(obj) {
    try {
      return transform(obj[key]);
    } catch (e) {
      return undefined;
    }
  };
}

/**
 * Chains together a series of function(obj) -> value, passing resulting
 * returned value to next function in chain.
 *
 * Accepts any number of functions passed as arguments
 * @return {Function} Accepting initial object, returning end-of-chain value
 *
 * Assumes all intermediary values to be objects, with well-formed sequence
 * of operations.
 */
function chain() {
  var getters = Array.prototype.slice.call(arguments);
  return function(obj) {
    return getters.reduce(function(cur, get) {
      return get(cur);
    }, obj);
  };
}

// Schema module
//

var TruffleContractSchema = {
  // Return a promise to validate a contract object
  // - Resolves as validated `contractObj`
  // - Rejects with list of errors from schema validator
  validate: function(contractObj) {
    var ajv = new Ajv({ verbose: true });
    ajv.addSchema(abiSchema);
    ajv.addSchema(networkObjectSchema);
    ajv.addSchema(contractObjectSchema);
    if (ajv.validate("contract-object.spec.json", contractObj)) {
      return contractObj;
    } else {
      const message = `Schema validation failed. Errors:\n\n${ajv.errors
        .map(
          ({
            keyword,
            dataPath,
            schemaPath,
            params,
            message,
            data,
            schema, // eslint-disable-line no-unused-vars
            parentSchema
          }) =>
            util.format(
              "%s (%s):\n%s\n",
              message,
              keyword,
              util.inspect(
                {
                  dataPath,
                  schemaPath,
                  params,
                  data,
                  parentSchema
                },
                { depth: 5 }
              )
            )
        )
        .join("\n")}`;
      const error = new Error(message);
      error.errors = ajv.errors;
      throw error;
    }
  },

  // accepts as argument anything that can be turned into a contract object
  // returns a contract object
  normalize: function(objDirty, options) {
    options = options || {};
    var normalized = {};

    // iterate over each property
    Object.keys(properties).forEach(function(key) {
      var property = properties[key];
      var value; // normalized value || undefined

      // either used the defined sources or assume the key will only ever be
      // listed as its canonical name (itself)
      var sources = property.sources || [key];

      // iterate over sources until value is defined or end of list met
      for (var i = 0; value === undefined && i < sources.length; i++) {
        var source = sources[i];
        // string refers to path to value in objDirty, split and chain
        // getters
        if (typeof source === "string") {
          var traversals = source.split(".").map(function(k) {
            return getter(k);
          });
          source = chain.apply(null, traversals);
        }

        // source should be a function that takes the objDirty and returns
        // value or undefined
        value = source(objDirty);
      }

      // run source-agnostic transform on value
      // (e.g. make sure bytecode begins 0x)
      if (property.transform) {
        value = property.transform(value, objDirty);
      }

      // add resulting (possibly undefined) to normalized obj
      normalized[key] = value;
    });

    // Copy x- options
    Object.keys(objDirty).forEach(function(key) {
      if (key.indexOf("x-") === 0) {
        normalized[key] = getter(key)(objDirty);
      }
    });

    // update schema version
    normalized.schemaVersion = pkgVersion;

    if (options.validate) {
      this.validate(normalized);
    }

    return normalized;
  }
};

module.exports = TruffleContractSchema;
<commit_msg>clarify check for abi array & avoid mutating og dirty array<commit_after>var pkgVersion = require("./package.json").version;
var Ajv = require("ajv");
var util = require("util");

var contractObjectSchema = require("./spec/contract-object.spec.json");
var networkObjectSchema = require("./spec/network-object.spec.json");
var abiSchema = require("./spec/abi.spec.json");

/**
 * Property definitions for Contract Objects
 *
 * Describes canonical output properties as sourced from some "dirty" input
 * object. Describes normalization process to account for deprecated and/or
 * nonstandard keys and values.
 *
 * Maps (key -> property) where:
 *  - `key` is the top-level output key matching up with those in the schema
 *  - `property` is an object with optional values:
 *      - `sources`: list of sources (see below); default `key`
 *      - `transform`: function(value) -> transformed value; default x -> x
 *
 * Each source represents a means to select a value from dirty object.
 * Allows:
 *  - dot-separated (`.`) string, corresponding to path to value in dirty
 *    object
 *  - function(dirtyObj) -> (cleanValue | undefined)
 *
 * The optional `transform` parameter standardizes value regardless of source,
 * for purposes of ensuring data type and/or string schemas.
 */

// helper that ensures abi's do not contain function signatures
const sanitizedValue = dirtyValueArray => {
  let sanitizedValueArray = [];
  dirtyValueArray.forEach(item => {
    let sanitizedItem = Object.assign({}, item);
    delete sanitizedItem.signature;
    sanitizedValueArray.push(sanitizedItem);
  });
  return sanitizedValueArray;
};

var properties = {
  contractName: {
    sources: ["contractName", "contract_name"]
  },
  abi: {
    sources: ["abi", "interface"],
    transform: function(value) {
      if (typeof value === "string") {
        try {
          value = JSON.parse(value);
        } catch (e) {
          value = undefined;
        }
      }
      if (Array.isArray(value)) {
        return sanitizedValue(value);
      }
      return value;
    }
  },
  metadata: {
    sources: ["metadata"]
  },
  bytecode: {
    sources: ["bytecode", "binary", "unlinked_binary", "evm.bytecode.object"],
    transform: function(value) {
      if (value && value.indexOf("0x") !== 0) {
        value = "0x" + value;
      }
      return value;
    }
  },
  deployedBytecode: {
    sources: [
      "deployedBytecode",
      "runtimeBytecode",
      "evm.deployedBytecode.object"
    ],
    transform: function(value) {
      if (value && value.indexOf("0x") !== 0) {
        value = "0x" + value;
      }
      return value;
    }
  },
  sourceMap: {
    sources: ["sourceMap", "srcmap", "evm.bytecode.sourceMap"]
  },
  deployedSourceMap: {
    sources: [
      "deployedSourceMap",
      "srcmapRuntime",
      "evm.deployedBytecode.sourceMap"
    ]
  },
  source: {},
  sourcePath: {},
  ast: {},
  legacyAST: {
    transform: function(value, obj) {
      var schemaVersion = obj.schemaVersion || "0.0.0";

      // legacyAST introduced in v2.0.0
      if (schemaVersion[0] < 2) {
        return obj.ast;
      } else {
        return value;
      }
    }
  },
  compiler: {},
  networks: {
    transform: function(value) {
      if (value === undefined) {
        value = {};
      }
      return value;
    }
  },
  schemaVersion: {
    sources: ["schemaVersion", "schema_version"]
  },
  updatedAt: {
    sources: ["updatedAt", "updated_at"],
    transform: function(value) {
      if (typeof value === "number") {
        value = new Date(value).toISOString();
      }
      return value;
    }
  },
  devdoc: {},
  userdoc: {}
};

/**
 * Construct a getter for a given key, possibly applying some post-retrieve
 * transformation on the resulting value.
 *
 * @return {Function} Accepting dirty object and returning value || undefined
 */
function getter(key, transform) {
  if (transform === undefined) {
    transform = function(x) {
      return x;
    };
  }

  return function(obj) {
    try {
      return transform(obj[key]);
    } catch (e) {
      return undefined;
    }
  };
}

/**
 * Chains together a series of function(obj) -> value, passing resulting
 * returned value to next function in chain.
 *
 * Accepts any number of functions passed as arguments
 * @return {Function} Accepting initial object, returning end-of-chain value
 *
 * Assumes all intermediary values to be objects, with well-formed sequence
 * of operations.
 */
function chain() {
  var getters = Array.prototype.slice.call(arguments);
  return function(obj) {
    return getters.reduce(function(cur, get) {
      return get(cur);
    }, obj);
  };
}

// Schema module
//

var TruffleContractSchema = {
  // Return a promise to validate a contract object
  // - Resolves as validated `contractObj`
  // - Rejects with list of errors from schema validator
  validate: function(contractObj) {
    var ajv = new Ajv({ verbose: true });
    ajv.addSchema(abiSchema);
    ajv.addSchema(networkObjectSchema);
    ajv.addSchema(contractObjectSchema);
    if (ajv.validate("contract-object.spec.json", contractObj)) {
      return contractObj;
    } else {
      const message = `Schema validation failed. Errors:\n\n${ajv.errors
        .map(
          ({
            keyword,
            dataPath,
            schemaPath,
            params,
            message,
            data,
            schema, // eslint-disable-line no-unused-vars
            parentSchema
          }) =>
            util.format(
              "%s (%s):\n%s\n",
              message,
              keyword,
              util.inspect(
                {
                  dataPath,
                  schemaPath,
                  params,
                  data,
                  parentSchema
                },
                { depth: 5 }
              )
            )
        )
        .join("\n")}`;
      const error = new Error(message);
      error.errors = ajv.errors;
      throw error;
    }
  },

  // accepts as argument anything that can be turned into a contract object
  // returns a contract object
  normalize: function(objDirty, options) {
    options = options || {};
    var normalized = {};

    // iterate over each property
    Object.keys(properties).forEach(function(key) {
      var property = properties[key];
      var value; // normalized value || undefined

      // either used the defined sources or assume the key will only ever be
      // listed as its canonical name (itself)
      var sources = property.sources || [key];

      // iterate over sources until value is defined or end of list met
      for (var i = 0; value === undefined && i < sources.length; i++) {
        var source = sources[i];
        // string refers to path to value in objDirty, split and chain
        // getters
        if (typeof source === "string") {
          var traversals = source.split(".").map(function(k) {
            return getter(k);
          });
          source = chain.apply(null, traversals);
        }

        // source should be a function that takes the objDirty and returns
        // value or undefined
        value = source(objDirty);
      }

      // run source-agnostic transform on value
      // (e.g. make sure bytecode begins 0x)
      if (property.transform) {
        value = property.transform(value, objDirty);
      }

      // add resulting (possibly undefined) to normalized obj
      normalized[key] = value;
    });

    // Copy x- options
    Object.keys(objDirty).forEach(function(key) {
      if (key.indexOf("x-") === 0) {
        normalized[key] = getter(key)(objDirty);
      }
    });

    // update schema version
    normalized.schemaVersion = pkgVersion;

    if (options.validate) {
      this.validate(normalized);
    }

    return normalized;
  }
};

module.exports = TruffleContractSchema;
<|endoftext|>


<commit_before>import {ref, keyFieldRef} from '../util';
import {Collect, Aggregate, MultiExtent, MultiValues, Sieve, Values} from '../transforms';
import {error, extend, isArray, isObject, isString, stringValue, toSet} from 'vega-util';

var FIELD_REF_ID = 0;

var types = [
  'identity',
  'ordinal', 'band', 'point',
  'linear', 'pow', 'sqrt', 'log', 'sequential',
  'time', 'utc',
  'quantize', 'quantile', 'threshold',
  'bin-linear', 'bin-ordinal'
];

var allTypes = toSet(types),
    ordinalTypes = toSet(types.slice(1, 4));

export function isOrdinal(type) {
  return ordinalTypes.hasOwnProperty(type);
}

export function isQuantile(type) {
  return type === 'quantile';
}

export default function(spec, scope) {
  var type = spec.type || 'linear',
      params, key;

  if (!allTypes.hasOwnProperty(type)) {
    error('Unrecognized scale type: ' + stringValue(type));
  }

  params = {
    type:   type,
    domain: parseScaleDomain(spec.domain, spec, scope)
  };

  if (spec.range != null) {
    params.range = parseScaleRange(spec, scope, params);
  }

  if (spec.interpolate != null) {
    parseScaleInterpolate(spec.interpolate, params);
  }

  for (key in spec) {
    if (params.hasOwnProperty(key) || key === 'name') continue;
    params[key] = parseLiteral(spec[key], scope);
  }

  scope.addScale(spec.name, params);
}

function parseLiteral(v, scope) {
  return !isObject(v) ? v
    : v.signal ? scope.signalRef(v.signal)
    : error('Unsupported object: ' + stringValue(v));
}

function parseArray(v, scope) {
  return v.signal
    ? scope.signalRef(v.signal)
    : v.map(function(v) { return parseLiteral(v, scope); });
}

function dataLookupError(name) {
  error('Can not find data set: ' + stringValue(name));
}

// -- SCALE DOMAIN ----

function parseScaleDomain(domain, spec, scope) {
  if (!domain) {
    if (spec.domainMin != null || spec.domainMax != null) {
      error('No scale domain defined for domainMin/domainMax to override.');
    }
    return; // default domain
  }

  return domain.signal ? scope.signalRef(domain.signal)
    : (isArray(domain) ? explicitDomain
    : domain.fields ? multipleDomain
    : singularDomain)(domain, spec, scope);
}

function explicitDomain(domain, spec, scope) {
  return domain.map(function(v) {
    return parseLiteral(v, scope);
  });
}

function singularDomain(domain, spec, scope) {
  var data = scope.getData(domain.data);
  if (!data) dataLookupError(domain.data);

  return isOrdinal(spec.type)
      ? data.valuesRef(scope, domain.field, parseSort(domain.sort, false))
      : isQuantile(spec.type) ? data.domainRef(scope, domain.field)
      : data.extentRef(scope, domain.field);
}

function multipleDomain(domain, spec, scope) {
  var data = domain.data,
      fields = domain.fields.reduce(function(dom, d) {
        d = isString(d) ? {data: data, field: d}
          : (isArray(d) || d.signal) ? fieldRef(d, scope)
          : d;
        return dom.push(d), dom;
      }, []);

  return (isOrdinal(spec.type) ? ordinalMultipleDomain
    : isQuantile(spec.type) ? quantileMultipleDomain
    : numericMultipleDomain)(domain, scope, fields);
}

function fieldRef(data, scope) {
  var name = '_:vega:_' + (FIELD_REF_ID++),
      coll = Collect({});

  if (isArray(data)) {
    coll.value = {$ingest: data};
  } else if (data.signal) {
    scope.signalRef('modify(' + stringValue(name)
      + ',' + data.signal + ', true)');
  }
  scope.addDataPipeline(name, [coll, Sieve({})]);
  return {data: name, field: 'data'};
}

function ordinalMultipleDomain(domain, scope, fields) {
  var counts, a, c, v;

  // get value counts for each domain field
  counts = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.countsRef(scope, f.field);
  });

  // sum counts from all fields
  a = scope.add(Aggregate({
    groupby: keyFieldRef,
    ops:['sum'], fields: [scope.fieldRef('count')], as:['count'],
    pulse: counts
  }));

  // collect aggregate output
  c = scope.add(Collect({pulse: ref(a)}));

  // extract values for combined domain
  v = scope.add(Values({
    field: keyFieldRef,
    sort:  scope.sortRef(parseSort(domain.sort, true)),
    pulse: ref(c)
  }));

  return ref(v);
}

function parseSort(sort, multidomain) {
  if (sort) {
    if (!sort.field && !sort.op) {
      if (isObject(sort)) sort.field = 'key';
      else sort = {field: 'key'};
    } else if (!sort.field && sort.op !== 'count') {
      error('No field provided for sort aggregate op: ' + sort.op);
    } else if (multidomain && sort.field) {
      error('Multiple domain scales can not sort by field.');
    } else if (multidomain && sort.op && sort.op !== 'count') {
      error('Multiple domain scales support op count only.');
    }
  }
  return sort;
}

function quantileMultipleDomain(domain, scope, fields) {
  // get value arrays for each domain field
  var values = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.domainRef(scope, f.field);
  });

  // combine value arrays
  return ref(scope.add(MultiValues({values: values})));
}

function numericMultipleDomain(domain, scope, fields) {
  // get extents for each domain field
  var extents = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.extentRef(scope, f.field);
  });

  // combine extents
  return ref(scope.add(MultiExtent({extents: extents})));
}

// -- SCALE INTERPOLATION -----

function parseScaleInterpolate(interpolate, params) {
  params.interpolate = parseLiteral(interpolate.type || interpolate);
  if (interpolate.gamma != null) {
    params.interpolateGamma = parseLiteral(interpolate.gamma);
  }
}

// -- SCALE RANGE -----

function parseScaleRange(spec, scope, params) {
  var range = spec.range,
      config = scope.config.range;

  if (range.signal) {
    return scope.signalRef(range.signal);
  } else if (isString(range)) {
    if (config && config.hasOwnProperty(range)) {
      spec = extend({}, spec, {range: config[range]});
      return parseScaleRange(spec, scope, params);
    } else if (range === 'width') {
      range = [0, {signal: 'width'}]
    } else if (range === 'height') {
      range = isOrdinal(spec.type)
        ? [0, {signal: 'height'}]
        : [{signal: 'height'}, 0]
    } else {
      error('Unrecognized scale range value: ' + stringValue(range));
    }
  } else if (range.scheme) {
    params.scheme = parseLiteral(range.scheme, scope);
    if (range.extent) params.schemeExtent = parseArray(range.extent, scope);
    if (range.count) params.schemeCount = parseLiteral(range.count, scope);
    return;
  } else if (range.step) {
    params.rangeStep = parseLiteral(range.step, scope);
    return;
  } else if (isOrdinal(spec.type) && !isArray(range)) {
    return parseScaleDomain(range, spec, scope);
  } else if (!isArray(range)) {
    error('Unsupported range type: ' + stringValue(range));
  }

  return range.map(function(v) {
    return parseLiteral(v, scope);
  });
}
<commit_msg>Treat bin-* scales as ordinal domain.<commit_after>import {ref, keyFieldRef} from '../util';
import {Collect, Aggregate, MultiExtent, MultiValues, Sieve, Values} from '../transforms';
import {error, extend, isArray, isObject, isString, stringValue, toSet} from 'vega-util';

var FIELD_REF_ID = 0;

var types = [
  'identity',
  'ordinal', 'band', 'point',
  'bin-linear', 'bin-ordinal',
  'linear', 'pow', 'sqrt', 'log', 'sequential',
  'time', 'utc',
  'quantize', 'quantile', 'threshold'
];

var allTypes = toSet(types),
    ordinalTypes = toSet(types.slice(1, 6));

export function isOrdinal(type) {
  return ordinalTypes.hasOwnProperty(type);
}

export function isQuantile(type) {
  return type === 'quantile';
}

export default function(spec, scope) {
  var type = spec.type || 'linear',
      params, key;

  if (!allTypes.hasOwnProperty(type)) {
    error('Unrecognized scale type: ' + stringValue(type));
  }

  params = {
    type:   type,
    domain: parseScaleDomain(spec.domain, spec, scope)
  };

  if (spec.range != null) {
    params.range = parseScaleRange(spec, scope, params);
  }

  if (spec.interpolate != null) {
    parseScaleInterpolate(spec.interpolate, params);
  }

  for (key in spec) {
    if (params.hasOwnProperty(key) || key === 'name') continue;
    params[key] = parseLiteral(spec[key], scope);
  }

  scope.addScale(spec.name, params);
}

function parseLiteral(v, scope) {
  return !isObject(v) ? v
    : v.signal ? scope.signalRef(v.signal)
    : error('Unsupported object: ' + stringValue(v));
}

function parseArray(v, scope) {
  return v.signal
    ? scope.signalRef(v.signal)
    : v.map(function(v) { return parseLiteral(v, scope); });
}

function dataLookupError(name) {
  error('Can not find data set: ' + stringValue(name));
}

// -- SCALE DOMAIN ----

function parseScaleDomain(domain, spec, scope) {
  if (!domain) {
    if (spec.domainMin != null || spec.domainMax != null) {
      error('No scale domain defined for domainMin/domainMax to override.');
    }
    return; // default domain
  }

  return domain.signal ? scope.signalRef(domain.signal)
    : (isArray(domain) ? explicitDomain
    : domain.fields ? multipleDomain
    : singularDomain)(domain, spec, scope);
}

function explicitDomain(domain, spec, scope) {
  return domain.map(function(v) {
    return parseLiteral(v, scope);
  });
}

function singularDomain(domain, spec, scope) {
  var data = scope.getData(domain.data);
  if (!data) dataLookupError(domain.data);

  return isOrdinal(spec.type)
      ? data.valuesRef(scope, domain.field, parseSort(domain.sort, false))
      : isQuantile(spec.type) ? data.domainRef(scope, domain.field)
      : data.extentRef(scope, domain.field);
}

function multipleDomain(domain, spec, scope) {
  var data = domain.data,
      fields = domain.fields.reduce(function(dom, d) {
        d = isString(d) ? {data: data, field: d}
          : (isArray(d) || d.signal) ? fieldRef(d, scope)
          : d;
        return dom.push(d), dom;
      }, []);

  return (isOrdinal(spec.type) ? ordinalMultipleDomain
    : isQuantile(spec.type) ? quantileMultipleDomain
    : numericMultipleDomain)(domain, scope, fields);
}

function fieldRef(data, scope) {
  var name = '_:vega:_' + (FIELD_REF_ID++),
      coll = Collect({});

  if (isArray(data)) {
    coll.value = {$ingest: data};
  } else if (data.signal) {
    scope.signalRef('modify(' + stringValue(name)
      + ',' + data.signal + ', true)');
  }
  scope.addDataPipeline(name, [coll, Sieve({})]);
  return {data: name, field: 'data'};
}

function ordinalMultipleDomain(domain, scope, fields) {
  var counts, a, c, v;

  // get value counts for each domain field
  counts = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.countsRef(scope, f.field);
  });

  // sum counts from all fields
  a = scope.add(Aggregate({
    groupby: keyFieldRef,
    ops:['sum'], fields: [scope.fieldRef('count')], as:['count'],
    pulse: counts
  }));

  // collect aggregate output
  c = scope.add(Collect({pulse: ref(a)}));

  // extract values for combined domain
  v = scope.add(Values({
    field: keyFieldRef,
    sort:  scope.sortRef(parseSort(domain.sort, true)),
    pulse: ref(c)
  }));

  return ref(v);
}

function parseSort(sort, multidomain) {
  if (sort) {
    if (!sort.field && !sort.op) {
      if (isObject(sort)) sort.field = 'key';
      else sort = {field: 'key'};
    } else if (!sort.field && sort.op !== 'count') {
      error('No field provided for sort aggregate op: ' + sort.op);
    } else if (multidomain && sort.field) {
      error('Multiple domain scales can not sort by field.');
    } else if (multidomain && sort.op && sort.op !== 'count') {
      error('Multiple domain scales support op count only.');
    }
  }
  return sort;
}

function quantileMultipleDomain(domain, scope, fields) {
  // get value arrays for each domain field
  var values = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.domainRef(scope, f.field);
  });

  // combine value arrays
  return ref(scope.add(MultiValues({values: values})));
}

function numericMultipleDomain(domain, scope, fields) {
  // get extents for each domain field
  var extents = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) dataLookupError(f.data);
    return data.extentRef(scope, f.field);
  });

  // combine extents
  return ref(scope.add(MultiExtent({extents: extents})));
}

// -- SCALE INTERPOLATION -----

function parseScaleInterpolate(interpolate, params) {
  params.interpolate = parseLiteral(interpolate.type || interpolate);
  if (interpolate.gamma != null) {
    params.interpolateGamma = parseLiteral(interpolate.gamma);
  }
}

// -- SCALE RANGE -----

function parseScaleRange(spec, scope, params) {
  var range = spec.range,
      config = scope.config.range;

  if (range.signal) {
    return scope.signalRef(range.signal);
  } else if (isString(range)) {
    if (config && config.hasOwnProperty(range)) {
      spec = extend({}, spec, {range: config[range]});
      return parseScaleRange(spec, scope, params);
    } else if (range === 'width') {
      range = [0, {signal: 'width'}]
    } else if (range === 'height') {
      range = isOrdinal(spec.type)
        ? [0, {signal: 'height'}]
        : [{signal: 'height'}, 0]
    } else {
      error('Unrecognized scale range value: ' + stringValue(range));
    }
  } else if (range.scheme) {
    params.scheme = parseLiteral(range.scheme, scope);
    if (range.extent) params.schemeExtent = parseArray(range.extent, scope);
    if (range.count) params.schemeCount = parseLiteral(range.count, scope);
    return;
  } else if (range.step) {
    params.rangeStep = parseLiteral(range.step, scope);
    return;
  } else if (isOrdinal(spec.type) && !isArray(range)) {
    return parseScaleDomain(range, spec, scope);
  } else if (!isArray(range)) {
    error('Unsupported range type: ' + stringValue(range));
  }

  return range.map(function(v) {
    return parseLiteral(v, scope);
  });
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
//
// This script loads the test file in the virtual machine and runs it in a
// context that only exposes a test variable with methods for testing and to
// spawn bots.
//
// Note: an important part of this script is to keep nodejs-isms away from test
// code and isolate it from implementation details.
var fs = require('fs');
var vm = require('vm');
var BotManager = require('./botmanager.js');

function Test(botType) {
  // Make the test fail if not completed in 3 seconds.
  this.timeout_ = setTimeout(
      this.fail.bind(this, "Test timeout!"),
      5000);
  this.botType_ = botType;
}

Test.prototype = {
  log: function () {
    console.log.apply(console.log, arguments);
  },

  abort: function (error) {
    var error = error || new Error("Test aborted");
    console.log(error.stack);
    process.exit(1);
  },

  assert: function (value, message) {
    if (value !== true) {
      this.abort(message || "Assert failed.");
    }
  },

  fail: function () {
    this.assert(false, "Test failed.");
  },

  done: function () {
    clearTimeout(this.timeout_);
    console.log("Test succeeded");
    process.exit(0);
  },

  // Utility method to wait for multiple callbacks to be executed.
  //  functions - array of functions to call with a callback.
  //  doneCallback - called when all callbacks on the array have completed.
  wait: function (functions, doneCallback) {
    var result = new Array(functions.length);
    var missingResult = functions.length;
    for (var i = 0; i != functions.length; ++i)
      functions[i](complete.bind(this, i));

    function complete(index, value) {
      missingResult--;
      result[index] = value;
      if (missingResult == 0)
        doneCallback.apply(null, result);
    }
  },

  spawnBot: function (name, doneCallback) {
    // Lazy initialization of botmanager.
    if (!this.botManager_)
      this.botManager_ = new BotManager();
    this.botManager_.spawnNewBot(name, this.botType_, doneCallback);
  },
}

function runTest(testfile) {
  console.log("Running test: " + testfile);
  var script = vm.createScript(fs.readFileSync(testfile), testfile);
  script.runInNewContext({ test: new Test(process.argv[2]) });
}

runTest("./test/simple_offer_answer.js");
<commit_msg>Fix printing of error stack in rtcbot when a test fails via test.fail().<commit_after>// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
//
// This script loads the test file in the virtual machine and runs it in a
// context that only exposes a test variable with methods for testing and to
// spawn bots.
//
// Note: an important part of this script is to keep nodejs-isms away from test
// code and isolate it from implementation details.
var fs = require('fs');
var vm = require('vm');
var BotManager = require('./botmanager.js');

function Test(botType) {
  // Make the test fail if not completed in 3 seconds.
  this.timeout_ = setTimeout(
      this.fail.bind(this, "Test timeout!"),
      5000);
  this.botType_ = botType;
}

Test.prototype = {
  log: function () {
    console.log.apply(console.log, arguments);
  },

  abort: function (error) {
    var error = new Error(error || "Test aborted");
    console.log(error.stack);
    process.exit(1);
  },

  assert: function (value, message) {
    if (value !== true) {
      this.abort(message || "Assert failed.");
    }
  },

  fail: function () {
    this.assert(false, "Test failed.");
  },

  done: function () {
    clearTimeout(this.timeout_);
    console.log("Test succeeded");
    process.exit(0);
  },

  // Utility method to wait for multiple callbacks to be executed.
  //  functions - array of functions to call with a callback.
  //  doneCallback - called when all callbacks on the array have completed.
  wait: function (functions, doneCallback) {
    var result = new Array(functions.length);
    var missingResult = functions.length;
    for (var i = 0; i != functions.length; ++i)
      functions[i](complete.bind(this, i));

    function complete(index, value) {
      missingResult--;
      result[index] = value;
      if (missingResult == 0)
        doneCallback.apply(null, result);
    }
  },

  spawnBot: function (name, doneCallback) {
    // Lazy initialization of botmanager.
    if (!this.botManager_)
      this.botManager_ = new BotManager();
    this.botManager_.spawnNewBot(name, this.botType_, doneCallback);
  },
}

function runTest(testfile) {
  console.log("Running test: " + testfile);
  var script = vm.createScript(fs.readFileSync(testfile), testfile);
  script.runInNewContext({ test: new Test(process.argv[2]) });
}

runTest("./test/simple_offer_answer.js");
<|endoftext|>


<commit_before>/*
 * dropdownToggle - Provides dropdown menu functionality
 * @restrict class or attribute
 * @example:

   My Dropdown Menu

       {{choice.text}}

 */
angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.foundation.mediaQueries' ])

.controller('DropdownToggleController', ['$scope', '$attrs', 'mediaQueries', function($scope, $attrs, mediaQueries) {
  this.small = function() {
    return mediaQueries.small() && !mediaQueries.medium();
  };
}])

.directive('dropdownToggle', ['$document', '$window', '$location', '$position', function ($document, $window, $location, $position) {
  var openElement = null,
      closeMenu   = angular.noop;
  return {
    restrict: 'CA',
    scope: {
      dropdownToggle: '@'
    },
    controller: 'DropdownToggleController',
    link: function(scope, element, attrs, controller) {
      var dropdown = angular.element($document[0].querySelector(scope.dropdownToggle));

      scope.$watch('$location.path', function() { closeMenu(); });
      element.bind('click', function (event) {
        dropdown = angular.element($document[0].querySelector(scope.dropdownToggle));
        var elementWasOpen = (element === openElement);

        event.preventDefault();
        event.stopPropagation();

        if (!!openElement) {
          closeMenu();
        }

        if (!elementWasOpen && !element.hasClass('disabled') && !element.prop('disabled')) {
          dropdown.css('display', 'block');

          var offset = $position.offset(element);
          var parentOffset = $position.offset(angular.element(dropdown[0].offsetParent));

          var dropdownWidth = dropdown.prop('offsetWidth');

          var css = {
              top: offset.top - parentOffset.top + offset.height + 'px'
          };

          if (controller.small()) {
            css.left = Math.max((parentOffset.width - dropdownWidth) / 2, 8) + 'px';
            css.position = 'absolute';
            css.width = '95%';
            css['max-width'] = 'none';
          }
          else {
            var left = Math.round(offset.left - parentOffset.left);
            var rightThreshold = $window.innerWidth - dropdownWidth - 8;
            if (left > rightThreshold) {
                left = rightThreshold;
                dropdown.removeClass('left').addClass('right');
            }
            css.left = left + 'px';
            css.position = null;
            css['max-width'] = null;
          }

          dropdown.css(css);

          openElement = element;
          closeMenu = function (event) {
            $document.unbind('click', closeMenu);
            dropdown.css('display', 'none');
            closeMenu = angular.noop;
            openElement = null;
          };
          $document.bind('click', closeMenu);
        }
      });

      if (dropdown) {
        dropdown.css('display', 'none');
      }
    }
  };
}]);
<commit_msg>refactor(dropdownToggle): Refactor event binding. Unbind on destroy.<commit_after>/*
 * dropdownToggle - Provides dropdown menu functionality
 * @restrict class or attribute
 * @example:

   My Dropdown Menu

       {{choice.text}}

 */
angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.foundation.mediaQueries' ])

.controller('DropdownToggleController', ['$scope', '$attrs', 'mediaQueries', function($scope, $attrs, mediaQueries) {
  this.small = function() {
    return mediaQueries.small() && !mediaQueries.medium();
  };
}])

.directive('dropdownToggle', ['$document', '$window', '$location', '$position', function ($document, $window, $location, $position) {
  var openElement = null,
      closeMenu   = angular.noop;
  return {
    restrict: 'CA',
    scope: {
      dropdownToggle: '@'
    },
    controller: 'DropdownToggleController',
    link: function(scope, element, attrs, controller) {
      var dropdown = angular.element($document[0].querySelector(scope.dropdownToggle));

      var onClick = function (event) {
        dropdown = angular.element($document[0].querySelector(scope.dropdownToggle));
        var elementWasOpen = (element === openElement);

        event.preventDefault();
        event.stopPropagation();

        if (!!openElement) {
          closeMenu();
        }

        if (!elementWasOpen && !element.hasClass('disabled') && !element.prop('disabled')) {
          dropdown.css('display', 'block');

          var offset = $position.offset(element);
          var parentOffset = $position.offset(angular.element(dropdown[0].offsetParent));

          var dropdownWidth = dropdown.prop('offsetWidth');

          var css = {
              top: offset.top - parentOffset.top + offset.height + 'px'
          };

          if (controller.small()) {
            css.left = Math.max((parentOffset.width - dropdownWidth) / 2, 8) + 'px';
            css.position = 'absolute';
            css.width = '95%';
            css['max-width'] = 'none';
          }
          else {
            var left = Math.round(offset.left - parentOffset.left);
            var rightThreshold = $window.innerWidth - dropdownWidth - 8;
            if (left > rightThreshold) {
                left = rightThreshold;
                dropdown.removeClass('left').addClass('right');
            }
            css.left = left + 'px';
            css.position = null;
            css['max-width'] = null;
          }

          dropdown.css(css);

          openElement = element;
          closeMenu = function (event) {
            $document.off('click', closeMenu);
            dropdown.css('display', 'none');
            closeMenu = angular.noop;
            openElement = null;
          };
          $document.on('click', closeMenu);
        }
      }

      if (dropdown) {
        dropdown.css('display', 'none');
      }

      scope.$watch('$location.path', function() { closeMenu(); });

      element.on('click', onClick);
      element.on('$destroy', function() {
        element.off('click', onClick);
      });
    }
  };
}]);
<|endoftext|>


<commit_before>/*
 * This contains common functions we need for processing the respinse
 */

/*
 * function to create list elements `<li>` and append to element with id `id`
 */
var displayListElements = function (id, elements, selected) {
    'use strict';
    var target = document.getElementById(id),
        fragment = document.createDocumentFragment(),
        len = elements.length;

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    elements.forEach(function (element) {
        var li = document.createElement('li'),
            content = document.createTextNode(element);
        li.setAttribute('id', element.toLowerCase());
        if (selected && selected === element.toLowerCase()) {
            li.setAttribute('class', 'active');
        }
        li.appendChild(content);
        fragment.appendChild(li);
    });
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to create `option` and append to select box with id `id`
 */
var displayOptions = function (id, elements, selected) {
    'use strict';
    var target= document.getElementById(id),
        fragment =  document.createDocumentFragment();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key]);
            option.setAttribute('value', key);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to display underlyings
 *
 * we need different function for this because we need to add submarket
 * name as classname to underlyings option
 */
var displayUnderlyings = function (selected) {
    'use strict';
    var target= document.getElementById('underlying'),
        fragment =  document.createDocumentFragment(),
        elements = Offerings.underlyings();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key].display);
            option.setAttribute('value', key);
            option.setAttribute('class', elements[key].classname);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * This maps the form name and barrierCategory we display on
 * trading form to the actual we send it to backend
 * for e.g risefall is mapped to callput with barrierCategory euro_atm
 */
var getFormNameBarrierCategory = function (displayFormName) {
    'use strict';
    var obj = {};
    if (displayFormName) {
        if(displayFormName === 'risefall') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_atm';
        } else if (displayFormName === 'higherlower') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_non_atm';
        } else if (displayFormName === 'callput'){
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = 'euro_atm';
        } else {
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = '';
        }
    } else {
        obj['formName'] = 'callput';
        obj['barrierCategory'] = 'euro_atm';
    }
    return obj;
};

/*
 * This maps the contract type to where we display on trading form
 * and as there is no mapping on server side so need to create it
 * on front end
 *
 * for example we display CALL on top and PUT to bottom
 */
var contractTypeDisplayMapping = function (type) {
    'use strict';
    var obj = {
        CALL: "top",
        PUT: "bottom",
        ASIANU: "top",
        ASIAND: "bottom",
        DIGITMATCH: "top",
        DIGITDIFF: "bottom",
        EXPIRYRANGE: "top",
        EXPIRYMISS: "bottom",
        RANGE: "top",
        UPORDOWN: "bottom",
        ONETOUCH: "top",
        NOTOUCH: "bottom",
    };

    return type ? obj[type] : 'top';
};

/*
 * function to check if element is visible or not
 *
 * alternative to jquery $('#id').is(':visible')
 */
var isVisible = function (elem) {
    if (elem.offsetWidth === 0 && elem.offsetHeight === 0) {
        return false;
    } else {
        return true;
    }
};

/*
 * function to hide and display the loading icon for price container
 */
var hidePriceLoadingIcon = function () {
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

var showPriceLoadingIcon = function () {
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'block';
    }
};

/*
 * function to hide contract confirmation overlay container
 */
var hideOverlayContainer = function () {
    var elm = document.getElementById('contract_confirmation_container');
    if (elm) {
        elm.style.display = 'none';
    }
}
<commit_msg>add use strict in all functions<commit_after>/*
 * This contains common functions we need for processing the respinse
 */

/*
 * function to create list elements `<li>` and append to element with id `id`
 */
var displayListElements = function (id, elements, selected) {
    'use strict';
    var target = document.getElementById(id),
        fragment = document.createDocumentFragment(),
        len = elements.length;

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    elements.forEach(function (element) {
        var li = document.createElement('li'),
            content = document.createTextNode(element);
        li.setAttribute('id', element.toLowerCase());
        if (selected && selected === element.toLowerCase()) {
            li.setAttribute('class', 'active');
        }
        li.appendChild(content);
        fragment.appendChild(li);
    });
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to create `option` and append to select box with id `id`
 */
var displayOptions = function (id, elements, selected) {
    'use strict';
    var target= document.getElementById(id),
        fragment =  document.createDocumentFragment();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key]);
            option.setAttribute('value', key);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to display underlyings
 *
 * we need different function for this because we need to add submarket
 * name as classname to underlyings option
 */
var displayUnderlyings = function (selected) {
    'use strict';
    var target= document.getElementById('underlying'),
        fragment =  document.createDocumentFragment(),
        elements = Offerings.underlyings();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key].display);
            option.setAttribute('value', key);
            option.setAttribute('class', elements[key].classname);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * This maps the form name and barrierCategory we display on
 * trading form to the actual we send it to backend
 * for e.g risefall is mapped to callput with barrierCategory euro_atm
 */
var getFormNameBarrierCategory = function (displayFormName) {
    'use strict';
    var obj = {};
    if (displayFormName) {
        if(displayFormName === 'risefall') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_atm';
        } else if (displayFormName === 'higherlower') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_non_atm';
        } else if (displayFormName === 'callput'){
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = 'euro_atm';
        } else {
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = '';
        }
    } else {
        obj['formName'] = 'callput';
        obj['barrierCategory'] = 'euro_atm';
    }
    return obj;
};

/*
 * This maps the contract type to where we display on trading form
 * and as there is no mapping on server side so need to create it
 * on front end
 *
 * for example we display CALL on top and PUT to bottom
 */
var contractTypeDisplayMapping = function (type) {
    'use strict';
    var obj = {
        CALL: "top",
        PUT: "bottom",
        ASIANU: "top",
        ASIAND: "bottom",
        DIGITMATCH: "top",
        DIGITDIFF: "bottom",
        EXPIRYRANGE: "top",
        EXPIRYMISS: "bottom",
        RANGE: "top",
        UPORDOWN: "bottom",
        ONETOUCH: "top",
        NOTOUCH: "bottom",
    };

    return type ? obj[type] : 'top';
};

/*
 * function to check if element is visible or not
 *
 * alternative to jquery $('#id').is(':visible')
 */
var isVisible = function (elem) {
    'use strict';
    if (elem.offsetWidth === 0 && elem.offsetHeight === 0) {
        return false;
    } else {
        return true;
    }
};

/*
 * function to hide and display the loading icon for price container
 */
var hidePriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

var showPriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'block';
    }
};

/*
 * function to hide contract confirmation overlay container
 */
var hideOverlayContainer = function () {
    'use strict';
    var elm = document.getElementById('contract_confirmation_container');
    if (elm) {
        elm.style.display = 'none';
    }
}
<|endoftext|>


<commit_before>/**
 * Image.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*jshint smarttabs:true, undef:true, unused:true, latedef:true, curly:true, bitwise:false, scripturl:true, browser:true, laxcomma:true */
/*global define:true */

/**
@class moxie/runtime/html5/image/Image
@private
*/
define("moxie/runtime/html5/image/Image", [
	"moxie/runtime/html5/Runtime",
	"moxie/core/utils/Basic",
	"moxie/core/Exceptions",
	"moxie/core/utils/Encode",
	"moxie/file/Blob",
	"moxie/runtime/html5/image/ImageInfo",
	"moxie/runtime/html5/image/MegaPixel",
	"moxie/core/utils/Mime",
	"moxie/core/utils/Env"
], function(extensions, Basic, x, Encode, Blob, ImageInfo, MegaPixel, Mime, Env) {

	function HTML5Image() {
		var me = this
		, _img, _imgInfo, _canvas, _binStr, _srcBlob
		, _modified = false // is set true whenever image is modified
		, _preserveHeaders = true
		;

		Basic.extend(me, {
			loadFromBlob: function(blob, asBinary) {
				var comp = this, I = comp.getRuntime();

				if (Basic.typeOf(asBinary) === 'undefined') {
					asBinary = true;
				}

				if (!I.can('access_binary')) {
					throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR);
				}

				if (blob.isDetached()) {
					_srcBlob = {
						name: blob.name,
						size: blob.size,
						type: blob.type
					};
					_loadFromBinaryString.call(this, blob.getSource());
					return;
				} else {
					_srcBlob = blob.getSource();

					if (asBinary) { // this will let us to hack the file internals
						_readAsBinaryString(_srcBlob, function(data) {
							_loadFromBinaryString.call(comp, data);
						});
					} else { // ... but this is faster
						_readAsDataUrl(_srcBlob, function(data) {
							_loadFromDataUrl.call(comp, data);
						});
					}
				}
			},

			loadFromImage: function(img, exact) {
				this.meta = img.meta;

				_srcBlob = {
					name: img.name,
					size: img.size,
					type: img.type
				};

				if (exact) {
					_loadFromBinaryString.call(this, img.getAsBinaryString());
				} else {
					_img = img.getAsImage();
					this.trigger('load', me.getInfo.call(this));
				}
			},

			getInfo: function() {
				var I = this.getRuntime()
				, info = {
					width: _img && _img.width || 0,
					height: _img && _img.height || 0,
					type: (_srcBlob.type || _srcBlob.name && Mime.mimes[_srcBlob.name.replace(/^.+\.([^\.]+)$/, "$1").toLowerCase()]) || '',
					size: _binStr && _binStr.length || _srcBlob.size || 0,
					name: _srcBlob.name || '',
					meta: this.meta || {}
				};

				if (I.can('access_image_binary') && _binStr) {
					if (_imgInfo) {
						_imgInfo.purge();
					}
					_imgInfo = new ImageInfo(_binStr);
					Basic.extend(info, _imgInfo);
				}
				return info;
			},

			resize: function() {
				if (!_img) {
					throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
				}
				_resize.apply(this, arguments);
			},

			getAsImage: function() {
				if (!_img) {
					throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
				}
				_img.id = this.uid + '_img';
				return _img;
			},

			getAsCanvas: function() {
				if (_canvas) {
					_canvas.id = this.uid + '_canvas';
				}
				return _canvas;
			},

			getAsBlob: function(type, quality) {
				var blob, I = this.getRuntime();

				if (type !== this.type) {
					// if different mime type requested prepare image for conversion
					_resize.call(this, this.width, this.height, false);
				}

				if (!_modified && !!~Basic.inArray(Basic.typeOf(_srcBlob), ['blob', 'file'])) {
					blob = new Blob(I.uid, _srcBlob);
				} else {
					var data = me.getAsBinaryString.call(this, type, quality);
					blob = new Blob(null, { // standalone blob
						type: type,
						size: data.length
					});
					blob.detach(data);
				}
				return blob;
			},

			getAsDataURL: function(type, quality) {
				// if image has not been modified, return the source right away
				if (!_modified) {
					return _img.src;
				}

				if ('image/jpeg' !== type) {
					return _canvas.toDataURL('image/png');
				} else {
					try {
						// older Geckos used to result in an exception on quality argument
						return _canvas.toDataURL('image/jpeg', quality/100);
					} catch (ex) {
						return _canvas.toDataURL('image/jpeg');
					}
				}
			},

			getAsBinaryString: function(type, quality) {
				// if image has not been modified, return the source right away
				if (!_modified) {
					// if image was not loaded from binary string
					if (!_binStr) {
						_binStr = _convertToBinary(me.getAsDataURL(type, quality));
					}
					return _binStr;
				}

				if ('image/jpeg' !== type) {
					_binStr = _convertToBinary(me.getAsDataURL(type, quality));
				} else {
					var dataUrl;

					// if jpeg
					if (!quality) {
						quality = 90;
					}

					try {
						// older Geckos used to result in an exception on quality argument
						dataUrl = _canvas.toDataURL('image/jpeg', quality/100);
					} catch (ex) {
						dataUrl = _canvas.toDataURL('image/jpeg');
					}

					_binStr = _convertToBinary(dataUrl);

					if (_imgInfo && _preserveHeaders) {
						// update dimensions info in exif
						if (_imgInfo.meta && _imgInfo.meta.exif) {
							_imgInfo.setExif({
								PixelXDimension: this.width,
								PixelYDimension: this.height
							});
						}

						_binStr = _imgInfo.writeHeaders(_binStr);
					}
				}

				_modified = false;

				return _binStr;
			},

			destroy: function() {
				me = null;
				_purge.call(this);
				this.getRuntime().getShim().removeInstance(this.uid);
			}
		});

		function _convertToBinary(dataUrl) {
			return Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7));
		}

		function _loadFromBinaryString(binStr) {
			var comp = this;

			_purge.call(this);

			_img = new Image();
			_img.onerror = function() {
				_purge.call(this);
				throw new x.ImageError(x.ImageError.WRONG_FORMAT);
			};
			_img.onload = function() {
				_binStr = binStr;
				comp.trigger('load', me.getInfo.call(comp));
			};

			_img.src = 'data:' + (_srcBlob.type || '') + ';base64,' + Encode.btoa(binStr);
		}

		function _loadFromDataUrl(dataUrl) {
			var comp = this;

			_img = new Image();
			_img.onerror = function() {
				_purge.call(this);
				throw new x.ImageError(x.ImageError.WRONG_FORMAT);
			};
			_img.onload = function() {
				comp.trigger('load', me.getInfo.call(comp));
			};
			_img.src = dataUrl;
		}

		function _readAsBinaryString(file, callback) {
			var fr;

			// use FileReader if it's available
			if (window.FileReader) {
				fr = new FileReader();
				fr.onload = function() {
					callback(this.result);
				};
				fr.readAsBinaryString(file);
			} else {
				return callback(file.getAsBinary());
			}
		}

		function _readAsDataUrl(file, callback) {
			var fr;

			// use FileReader if it's available
			if (window.FileReader) {
				fr = new FileReader();
				fr.onload = function() {
					callback(this.result);
				};
				fr.readAsDataURL(file);
			} else {
				return callback(file.getAsDataURL());
			}
		}

		function _resize(width, height, crop, preserveHeaders) {
			var ctx, scale, mathFn, x, y, imgWidth, imgHeight, orientation;

			_preserveHeaders = preserveHeaders; // we will need to check this on export

			// take into account orientation tag
			orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1;

			if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation
				// swap dimensions
				var mem = width;
				width = height;
				height = mem;
			}

			// unify dimensions
			mathFn = !crop ? Math.min : Math.max;
			scale = mathFn(width/_img.width, height/_img.height);

			// we only downsize here
			if (scale > 1 && (!crop || preserveHeaders)) { // when cropping one of dimensions may still exceed max, so process it anyway
				this.trigger('Resize');
				return;
			}

			imgWidth = Math.round(_img.width * scale);
			imgHeight = Math.round(_img.height * scale);

			// prepare canvas if necessary
			if (!_canvas) {
				_canvas = document.createElement("canvas");
			}

			ctx = _canvas.getContext('2d');

			// scale image and canvas
			if (crop) {
				_canvas.width = width;
				_canvas.height = height;
			} else {
				_canvas.width = imgWidth;
				_canvas.height = imgHeight;
			}

			// if dimensions of the resulting image still larger than canvas, center it
			x = imgWidth > _canvas.width ? Math.round((imgWidth - _canvas.width) / 2)  : 0;
			y = imgHeight > _canvas.height ? Math.round((imgHeight - _canvas.height) / 2) : 0;

			if (!_preserveHeaders) {
				_rotateToOrientaion(_canvas.width, _canvas.height, orientation);
			} else {
				this.width = _canvas.width;
				this.height = _canvas.height;
			}

			_drawToCanvas.call(this, _img, _canvas, -x, -y, imgWidth, imgHeight);

			_modified = true;
			this.trigger('Resize');
		}

		function _drawToCanvas(img, canvas, x, y, w, h) {
			if (Env.os === 'iOS' || Env.os === 'Android') {
				// avoid squish bug in iOS6
				MegaPixel.renderTo(img, canvas, { width: w, height: h, x: x, y: y });
			} else {
				var ctx = canvas.getContext('2d');
				ctx.drawImage(img, x, y, w, h);
			}
		}

		/**
		* Transform canvas coordination according to specified frame size and orientation
		* Orientation value is from EXIF tag
		* @author Shinichi Tomita <shinichi.tomita@gmail.com>
		*/
		function _rotateToOrientaion(width, height, orientation) {
			switch (orientation) {
				case 5:
				case 6:
				case 7:
				case 8:
					_canvas.width = height;
					_canvas.height = width;
					break;
				default:
					_canvas.width = width;
					_canvas.height = height;
			}

			/**
			1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
			2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
			3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
			4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
			5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
			6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
			7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
			8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
			*/

			var ctx = _canvas.getContext('2d');
			switch (orientation) {
				case 2:
					// horizontal flip
					ctx.translate(width, 0);
					ctx.scale(-1, 1);
					break;
				case 3:
					// 180 rotate left
					ctx.translate(width, height);
					ctx.rotate(Math.PI);
					break;
				case 4:
					// vertical flip
					ctx.translate(0, height);
					ctx.scale(1, -1);
					break;
				case 5:
					// vertical flip + 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.scale(1, -1);
					break;
				case 6:
					// 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.translate(0, -height);
					break;
				case 7:
					// horizontal flip + 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.translate(width, -height);
					ctx.scale(-1, 1);
					break;
				case 8:
					// 90 rotate left
					ctx.rotate(-0.5 * Math.PI);
					ctx.translate(-width, 0);
					break;
			}
		}

		function _purge() {
			if (_imgInfo) {
				_imgInfo.purge();
				_imgInfo = null;
			}
			_binStr = _img = _canvas = null;
			_modified = false;
		}
	}

	return (extensions.Image = HTML5Image);
});<commit_msg>Update Image.js<commit_after>/**
 * Image.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*jshint smarttabs:true, undef:true, unused:true, latedef:true, curly:true, bitwise:false, scripturl:true, browser:true, laxcomma:true */
/*global define:true */

/**
@class moxie/runtime/html5/image/Image
@private
*/
define("moxie/runtime/html5/image/Image", [
	"moxie/runtime/html5/Runtime",
	"moxie/core/utils/Basic",
	"moxie/core/Exceptions",
	"moxie/core/utils/Encode",
	"moxie/file/Blob",
	"moxie/runtime/html5/image/ImageInfo",
	"moxie/runtime/html5/image/MegaPixel",
	"moxie/core/utils/Mime",
	"moxie/core/utils/Env"
], function(extensions, Basic, x, Encode, Blob, ImageInfo, MegaPixel, Mime, Env) {

	function HTML5Image() {
		var me = this
		, _img, _imgInfo, _canvas, _binStr, _srcBlob
		, _modified = false // is set true whenever image is modified
		, _preserveHeaders = true
		;

		Basic.extend(me, {
			loadFromBlob: function(blob, asBinary) {
				var comp = this, I = comp.getRuntime();

				if (Basic.typeOf(asBinary) === 'undefined') {
					asBinary = true;
				}

				if (!I.can('access_binary')) {
					throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR);
				}

				if (blob.isDetached()) {
					_srcBlob = {
						name: blob.name,
						size: blob.size,
						type: blob.type
					};
					_loadFromBinaryString.call(this, blob.getSource());
					return;
				} else {
					_srcBlob = blob.getSource();

					if (asBinary) { // this will let us to hack the file internals
						_readAsBinaryString(_srcBlob, function(data) {
							_loadFromBinaryString.call(comp, data);
						});
					} else { // ... but this is faster
						_readAsDataUrl(_srcBlob, function(data) {
							_loadFromDataUrl.call(comp, data);
						});
					}
				}
			},

			loadFromImage: function(img, exact) {
				this.meta = img.meta;

				_srcBlob = {
					name: img.name,
					size: img.size,
					type: img.type
				};

				if (exact) {
					_loadFromBinaryString.call(this, img.getAsBinaryString());
				} else {
					_img = img.getAsImage();
					this.trigger('load', me.getInfo.call(this));
				}
			},

			getInfo: function() {
				var I = this.getRuntime()
				, info = {
					width: _img && _img.width || 0,
					height: _img && _img.height || 0,
					type: (_srcBlob.type || _srcBlob.name && Mime.mimes[_srcBlob.name.replace(/^.+\.([^\.]+)$/, "$1").toLowerCase()]) || '',
					size: _binStr && _binStr.length || _srcBlob.size || 0,
					name: _srcBlob.name || '',
					meta: this.meta || {}
				};

				if (I.can('access_image_binary') && _binStr) {
					if (_imgInfo) {
						_imgInfo.purge();
					}
					_imgInfo = new ImageInfo(_binStr);
					Basic.extend(info, _imgInfo);
				}
				return info;
			},

			resize: function() {
				if (!_img) {
					throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
				}
				_resize.apply(this, arguments);
			},

			getAsImage: function() {
				if (!_img) {
					throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
				}
				_img.id = this.uid + '_img';
				return _img;
			},

			getAsCanvas: function() {
				if (_canvas) {
					_canvas.id = this.uid + '_canvas';
				}
				return _canvas;
			},

			getAsBlob: function(type, quality) {
				var blob, I = this.getRuntime();

				if (type !== this.type) {
					// if different mime type requested prepare image for conversion
					_resize.call(this, this.width, this.height, false);
				}

				if (!_modified && !!~Basic.inArray(Basic.typeOf(_srcBlob), ['blob', 'file'])) {
					blob = new Blob(I.uid, _srcBlob);
				} else {
					var data = me.getAsBinaryString.call(this, type, quality);
					blob = new Blob(null, { // standalone blob
						type: type,
						size: data.length
					});
					blob.detach(data);
				}
				return blob;
			},

			getAsDataURL: function(type, quality) {
				// if image has not been modified, return the source right away
				if (!_modified) {
					return _img.src;
				}

				if ('image/jpeg' !== type) {
					return _canvas.toDataURL('image/png');
				} else {
					try {
						// older Geckos used to result in an exception on quality argument
						return _canvas.toDataURL('image/jpeg', quality/100);
					} catch (ex) {
						return _canvas.toDataURL('image/jpeg');
					}
				}
			},

			getAsBinaryString: function(type, quality) {
				// if image has not been modified, return the source right away
				if (!_modified) {
					// if image was not loaded from binary string
					if (!_binStr) {
						_binStr = _convertToBinary(me.getAsDataURL(type, quality));
					}
					return _binStr;
				}

				if ('image/jpeg' !== type) {
					_binStr = _convertToBinary(me.getAsDataURL(type, quality));
				} else {
					var dataUrl;

					// if jpeg
					if (!quality) {
						quality = 90;
					}

					try {
						// older Geckos used to result in an exception on quality argument
						dataUrl = _canvas.toDataURL('image/jpeg', quality/100);
					} catch (ex) {
						dataUrl = _canvas.toDataURL('image/jpeg');
					}

					_binStr = _convertToBinary(dataUrl);

					if (_imgInfo && _preserveHeaders) {
						// update dimensions info in exif
						if (_imgInfo.meta && _imgInfo.meta.exif) {
							_imgInfo.setExif({
								PixelXDimension: this.width,
								PixelYDimension: this.height
							});
						}

						_binStr = _imgInfo.writeHeaders(_binStr);
					}
				}

				_modified = false;

				return _binStr;
			},

			destroy: function() {
				me = null;
				_purge.call(this);
				this.getRuntime().getShim().removeInstance(this.uid);
			}
		});

		function _convertToBinary(dataUrl) {
			return Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7));
		}

		function _loadFromBinaryString(binStr) {
			var comp = this;

			_purge.call(this);

			_img = new Image();
			_img.onerror = function() {
				_purge.call(this);
				throw new x.ImageError(x.ImageError.WRONG_FORMAT);
			};
			_img.onload = function() {
				_binStr = binStr;
				comp.trigger('load', me.getInfo.call(comp));
			};

			_img.src = 'data:' + (_srcBlob.type || '') + ';base64,' + Encode.btoa(binStr);
		}

		function _loadFromDataUrl(dataUrl) {
			var comp = this;

			_img = new Image();
			_img.onerror = function() {
				_purge.call(this);
				throw new x.ImageError(x.ImageError.WRONG_FORMAT);
			};
			_img.onload = function() {
				comp.trigger('load', me.getInfo.call(comp));
			};
			_img.src = dataUrl;
		}

		function _readAsBinaryString(file, callback) {
			var fr;

			// use FileReader if it's available
			if (window.FileReader) {
				fr = new FileReader();
				fr.onload = function() {
					callback(this.result);
				};
				fr.readAsBinaryString(file);
			} else {
				return callback(file.getAsBinary());
			}
		}

		function _readAsDataUrl(file, callback) {
			var fr;

			// use FileReader if it's available
			if (window.FileReader) {
				fr = new FileReader();
				fr.onload = function() {
					callback(this.result);
				};
				fr.readAsDataURL(file);
			} else {
				return callback(file.getAsDataURL());
			}
		}

		function _resize(width, height, crop, preserveHeaders) {
			var ctx, scale, mathFn, x, y, imgWidth, imgHeight, orientation;

			_preserveHeaders = preserveHeaders; // we will need to check this on export

			// take into account orientation tag
			orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1;

			if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation
				// swap dimensions
				var mem = width;
				width = height;
				height = mem;
			}

			// unify dimensions
			mathFn = !crop ? Math.min : Math.max;
			scale = mathFn(width/_img.width, height/_img.height);

			// we only downsize here
			if (scale > 1 && (!crop || preserveHeaders)) { // when cropping one of dimensions may still exceed max, so process it anyway
				this.trigger('Resize');
				return;
			}

			imgWidth = Math.round(_img.width * scale);
			imgHeight = Math.round(_img.height * scale);

			// prepare canvas if necessary
			if (!_canvas) {
				_canvas = document.createElement("canvas");
			}

			ctx = _canvas.getContext('2d');

			// scale image and canvas
			if (crop) {
				_canvas.width = width;
				_canvas.height = height;
			} else {
				_canvas.width = imgWidth;
				_canvas.height = imgHeight;
			}

			// if dimensions of the resulting image still larger than canvas, center it
			x = imgWidth > _canvas.width ? Math.round((imgWidth - _canvas.width) / 2)  : 0;
			y = imgHeight > _canvas.height ? Math.round((imgHeight - _canvas.height) / 2) : 0;

			if (!_preserveHeaders) {
				_rotateToOrientaion(_canvas.width, _canvas.height, orientation);
			} else {
				this.width = _canvas.width;
				this.height = _canvas.height;
			}

			_drawToCanvas.call(this, _img, _canvas, -x, -y, imgWidth, imgHeight);

			_modified = true;
			this.trigger('Resize');
		}

		function _drawToCanvas(img, canvas, x, y, w, h) {
			if (Env.OS === 'iOS' || Env.OS === 'Android') {
				// avoid squish bug in iOS6
				MegaPixel.renderTo(img, canvas, { width: w, height: h, x: x, y: y });
			} else {
				var ctx = canvas.getContext('2d');
				ctx.drawImage(img, x, y, w, h);
			}
		}

		/**
		* Transform canvas coordination according to specified frame size and orientation
		* Orientation value is from EXIF tag
		* @author Shinichi Tomita <shinichi.tomita@gmail.com>
		*/
		function _rotateToOrientaion(width, height, orientation) {
			switch (orientation) {
				case 5:
				case 6:
				case 7:
				case 8:
					_canvas.width = height;
					_canvas.height = width;
					break;
				default:
					_canvas.width = width;
					_canvas.height = height;
			}

			/**
			1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
			2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
			3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
			4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
			5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
			6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
			7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
			8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
			*/

			var ctx = _canvas.getContext('2d');
			switch (orientation) {
				case 2:
					// horizontal flip
					ctx.translate(width, 0);
					ctx.scale(-1, 1);
					break;
				case 3:
					// 180 rotate left
					ctx.translate(width, height);
					ctx.rotate(Math.PI);
					break;
				case 4:
					// vertical flip
					ctx.translate(0, height);
					ctx.scale(1, -1);
					break;
				case 5:
					// vertical flip + 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.scale(1, -1);
					break;
				case 6:
					// 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.translate(0, -height);
					break;
				case 7:
					// horizontal flip + 90 rotate right
					ctx.rotate(0.5 * Math.PI);
					ctx.translate(width, -height);
					ctx.scale(-1, 1);
					break;
				case 8:
					// 90 rotate left
					ctx.rotate(-0.5 * Math.PI);
					ctx.translate(-width, 0);
					break;
			}
		}

		function _purge() {
			if (_imgInfo) {
				_imgInfo.purge();
				_imgInfo = null;
			}
			_binStr = _img = _canvas = null;
			_modified = false;
		}
	}

	return (extensions.Image = HTML5Image);
});
<|endoftext|>


<commit_before>angular.module('efg.findusView', [
	'efg.componentDirective',
	'uiGmapgoogle-maps',
	'geolocation',
	'ng',
	'ngRoute'
])

.config(function($routeProvider) {
	$routeProvider.when('/findus', {
		controller: 'FindusCtrl as findus',
		templateUrl: 'efg.findusView.tpl.html'
	});
})

.controller('FindusCtrl', function(geolocation) {
	// need to create marker position twice (not as one object)
	// or marker won't update when map is moved
	var latitude = 49.49172
	  , longitude = 8.435441
	  , delta = 0.0001;

	this.map = {
		center: {
			latitude: latitude,
			longitude: longitude
		},
		zoom: 15,
		options: {
			backgroundColor: 'rgb(233,229,220)',
			scrollwheel: false
		},
		bounds: {
			northeast: {
				latitude: latitude * (1 + delta),
				longitude: longitude * (1 + delta)
			},
			southwest: {
				latitude: latitude * (1 - delta),
				longitude: longitude * (1 - delta)
			}
		}
	};
	this.we = {
		coords: {
			latitude: latitude,
			longitude: longitude
		},
		id: 0
	};
	this.you = undefined;

	geolocation.getLocation().then(angular.bind(this, function success(data) {
		this.you = {
			coords: data.coords,
			id: 1
		};
		this.map.bounds = {
			northeast: {
				// to north == +lat
				latitude: Math.max(this.we.coords.latitude, this.you.coords.latitude) * (1 + delta),
				// to east == +lng
				longitude: Math.max(this.we.coords.longitude, this.you.coords.longitude) * (1 + delta)
			},
			southwest: {
				latitude: Math.min(this.we.coords.latitude, this.you.coords.latitude) * (1 - delta),
				longitude: Math.min(this.we.coords.longitude, this.you.coords.longitude) * (1 - delta)
			}
		};
	}));
});<commit_msg>added 'use strict' to conform to jshintrc<commit_after>'use strict';

angular.module('efg.findusView', [
	'efg.componentDirective',
	'uiGmapgoogle-maps',
	'geolocation',
	'ng',
	'ngRoute'
])

.config(function($routeProvider, uiGmapGoogleMapApiProvider) {
	$routeProvider.when('/findus', {
		controller: 'FindusCtrl as findus',
		templateUrl: 'efg.findusView.tpl.html'
	});

	uiGmapGoogleMapApiProvider.configure({
		v: '3.17',
		libraries: 'weather,geometry,visualization'
	});
})

.controller('FindusCtrl', function(geolocation) {
	// need to create marker position twice (not as one object)
	// or marker won't update when map is moved
	var latitude = 49.49172
	  , longitude = 8.435441
	  , delta = 0.0001;

	this.map = {
		center: {
			latitude: latitude,
			longitude: longitude
		},
		zoom: 15,
		options: {
			backgroundColor: 'rgb(233,229,220)',
			scrollwheel: false
		},
		bounds: {
			northeast: {
				latitude: latitude * (1 + delta),
				longitude: longitude * (1 + delta)
			},
			southwest: {
				latitude: latitude * (1 - delta),
				longitude: longitude * (1 - delta)
			}
		}
	};
	this.we = {
		coords: {
			latitude: latitude,
			longitude: longitude
		},
		id: 0
	};
	this.you = undefined;

	geolocation.getLocation().then(angular.bind(this, function success(data) {
		this.you = {
			coords: data.coords,
			id: 1
		};
		this.map.bounds = {
			northeast: {
				// to north == +lat
				latitude: Math.max(this.we.coords.latitude, this.you.coords.latitude) * (1 + delta),
				// to east == +lng
				longitude: Math.max(this.we.coords.longitude, this.you.coords.longitude) * (1 + delta)
			},
			southwest: {
				latitude: Math.min(this.we.coords.latitude, this.you.coords.latitude) * (1 - delta),
				longitude: Math.min(this.we.coords.longitude, this.you.coords.longitude) * (1 - delta)
			}
		};
	}));
});<|endoftext|>


<commit_before>/**
* RegistrationComponents.js
* Created by Kyle Fox 12/11/15
**/

var React = require('react');
var NavigationComponents  = require('./NavigationComponents.js');

class RegistrationContent extends React.Component {
    render() {
        return (

Registration

        );
    }
}

class RegistrationPage extends React.Component {
    render() {
        return (

                <NavigationComponents.Navbar />
                <RegistrationContent />

        );
    }
}

module.exports.RegistrationPage = RegistrationPage;
<commit_msg>Email input with basic front end validation for .mil or .gov<commit_after>/**
* RegistrationComponents.js
* Created by Kyle Fox 12/11/15
**/

var React = require('react');
var NavigationComponents  = require('./NavigationComponents.js');

class EmailComponent extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            buttonClass: 'usa-button-disabled'
        };
    }

    handleChange(e) {
        var inputText = e.target.value;
        var emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.(?:gov|mil)$/;
        var newButtonClass;

        // Activate submit button if input is either .mil or .gov email address
        if (inputText.match(emailRegex)) {
            newButtonClass = 'usa-button';
        } else {
            newButtonClass = 'usa-button-disabled';
        }

        this.setState({
            buttonClass: newButtonClass
        });
    }

    render() {
        return (

                Registration Email
                <input id="input-registration-email" name="input-registration-email" placeholder="Please enter your .gov or .mil email address" type="text" onChange={this.handleChange.bind(this)} />
                <button className={this.state.buttonClass}>Verify this email address</button>

        );
    }
}

class RegistrationContent extends React.Component {
    render() {
        return (

Registration

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor.

                <EmailComponent />

        );
    }
}

class RegistrationPage extends React.Component {
    render() {
        return (

                <NavigationComponents.Navbar />
                <RegistrationContent />

        );
    }
}

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