http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/base64.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/base64.js 
b/externs/GCL/externs/goog/crypt/base64.js
new file mode 100644
index 0000000..9103fa1
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/base64.js
@@ -0,0 +1,286 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Base64 en/decoding. Not much to say here except that we
+ * work with decoded values in arrays of bytes. By "byte" I mean a number
+ * in [0, 255].
+ *
+ * @author [email protected] (Gavin Doughtie)
+ */
+
+goog.provide('goog.crypt.base64');
+goog.require('goog.crypt');
+goog.require('goog.userAgent');
+
+// Static lookup maps, lazily populated by init_()
+
+
+/**
+ * Maps bytes to characters.
+ * @type {Object}
+ * @private
+ */
+goog.crypt.base64.byteToCharMap_ = null;
+
+
+/**
+ * Maps characters to bytes.
+ * @type {Object}
+ * @private
+ */
+goog.crypt.base64.charToByteMap_ = null;
+
+
+/**
+ * Maps bytes to websafe characters.
+ * @type {Object}
+ * @private
+ */
+goog.crypt.base64.byteToCharMapWebSafe_ = null;
+
+
+/**
+ * Maps websafe characters to bytes.
+ * @type {Object}
+ * @private
+ */
+goog.crypt.base64.charToByteMapWebSafe_ = null;
+
+
+/**
+ * Our default alphabet, shared between
+ * ENCODED_VALS and ENCODED_VALS_WEBSAFE
+ * @type {string}
+ */
+goog.crypt.base64.ENCODED_VALS_BASE =
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
+    'abcdefghijklmnopqrstuvwxyz' +
+    '0123456789';
+
+
+/**
+ * Our default alphabet. Value 64 (=) is special; it means "nothing."
+ * @type {string}
+ */
+goog.crypt.base64.ENCODED_VALS =
+    goog.crypt.base64.ENCODED_VALS_BASE + '+/=';
+
+
+/**
+ * Our websafe alphabet.
+ * @type {string}
+ */
+goog.crypt.base64.ENCODED_VALS_WEBSAFE =
+    goog.crypt.base64.ENCODED_VALS_BASE + '-_.';
+
+
+/**
+ * Whether this browser supports the atob and btoa functions. This extension
+ * started at Mozilla but is now implemented by many browsers. We use the
+ * ASSUME_* variables to avoid pulling in the full useragent detection library
+ * but still allowing the standard per-browser compilations.
+ *
+ * @type {boolean}
+ */
+goog.crypt.base64.HAS_NATIVE_SUPPORT = goog.userAgent.GECKO ||
+                                       goog.userAgent.WEBKIT ||
+                                       goog.userAgent.OPERA ||
+                                       typeof(goog.global.atob) == 'function';
+
+
+/**
+ * Base64-encode an array of bytes.
+ *
+ * @param {Array<number>|Uint8Array} input An array of bytes (numbers with
+ *     value in [0, 255]) to encode.
+ * @param {boolean=} opt_webSafe Boolean indicating we should use the
+ *     alternative alphabet.
+ * @return {string} The base64 encoded string.
+ */
+goog.crypt.base64.encodeByteArray = function(input, opt_webSafe) {
+  if (!goog.isArrayLike(input)) {
+    throw Error('encodeByteArray takes an array as a parameter');
+  }
+
+  goog.crypt.base64.init_();
+
+  var byteToCharMap = opt_webSafe ?
+                      goog.crypt.base64.byteToCharMapWebSafe_ :
+                      goog.crypt.base64.byteToCharMap_;
+
+  var output = [];
+
+  for (var i = 0; i < input.length; i += 3) {
+    var byte1 = input[i];
+    var haveByte2 = i + 1 < input.length;
+    var byte2 = haveByte2 ? input[i + 1] : 0;
+    var haveByte3 = i + 2 < input.length;
+    var byte3 = haveByte3 ? input[i + 2] : 0;
+
+    var outByte1 = byte1 >> 2;
+    var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
+    var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
+    var outByte4 = byte3 & 0x3F;
+
+    if (!haveByte3) {
+      outByte4 = 64;
+
+      if (!haveByte2) {
+        outByte3 = 64;
+      }
+    }
+
+    output.push(byteToCharMap[outByte1],
+                byteToCharMap[outByte2],
+                byteToCharMap[outByte3],
+                byteToCharMap[outByte4]);
+  }
+
+  return output.join('');
+};
+
+
+/**
+ * Base64-encode a string.
+ *
+ * @param {string} input A string to encode.
+ * @param {boolean=} opt_webSafe If true, we should use the
+ *     alternative alphabet.
+ * @return {string} The base64 encoded string.
+ */
+goog.crypt.base64.encodeString = function(input, opt_webSafe) {
+  // Shortcut for Mozilla browsers that implement
+  // a native base64 encoder in the form of "btoa/atob"
+  if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
+    return goog.global.btoa(input);
+  }
+  return goog.crypt.base64.encodeByteArray(
+      goog.crypt.stringToByteArray(input), opt_webSafe);
+};
+
+
+/**
+ * Base64-decode a string.
+ *
+ * @param {string} input to decode.
+ * @param {boolean=} opt_webSafe True if we should use the
+ *     alternative alphabet.
+ * @return {string} string representing the decoded value.
+ */
+goog.crypt.base64.decodeString = function(input, opt_webSafe) {
+  // Shortcut for Mozilla browsers that implement
+  // a native base64 encoder in the form of "btoa/atob"
+  if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
+    return goog.global.atob(input);
+  }
+  return goog.crypt.byteArrayToString(
+      goog.crypt.base64.decodeStringToByteArray(input, opt_webSafe));
+};
+
+
+/**
+ * Base64-decode a string.
+ *
+ * In base-64 decoding, groups of four characters are converted into three
+ * bytes.  If the encoder did not apply padding, the input length may not
+ * be a multiple of 4.
+ *
+ * In this case, the last group will have fewer than 4 characters, and
+ * padding will be inferred.  If the group has one or two characters, it 
decodes
+ * to one byte.  If the group has three characters, it decodes to two bytes.
+ *
+ * @param {string} input Input to decode.
+ * @param {boolean=} opt_webSafe True if we should use the web-safe alphabet.
+ * @return {!Array<number>} bytes representing the decoded value.
+ */
+goog.crypt.base64.decodeStringToByteArray = function(input, opt_webSafe) {
+  goog.crypt.base64.init_();
+
+  var charToByteMap = opt_webSafe ?
+                      goog.crypt.base64.charToByteMapWebSafe_ :
+                      goog.crypt.base64.charToByteMap_;
+
+  var output = [];
+
+  for (var i = 0; i < input.length; ) {
+    var byte1 = charToByteMap[input.charAt(i++)];
+
+    var haveByte2 = i < input.length;
+    var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
+    ++i;
+
+    var haveByte3 = i < input.length;
+    var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
+    ++i;
+
+    var haveByte4 = i < input.length;
+    var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
+    ++i;
+
+    if (byte1 == null || byte2 == null ||
+        byte3 == null || byte4 == null) {
+      throw Error();
+    }
+
+    var outByte1 = (byte1 << 2) | (byte2 >> 4);
+    output.push(outByte1);
+
+    if (byte3 != 64) {
+      var outByte2 = ((byte2 << 4) & 0xF0) | (byte3 >> 2);
+      output.push(outByte2);
+
+      if (byte4 != 64) {
+        var outByte3 = ((byte3 << 6) & 0xC0) | byte4;
+        output.push(outByte3);
+      }
+    }
+  }
+
+  return output;
+};
+
+
+/**
+ * Lazy static initialization function. Called before
+ * accessing any of the static map variables.
+ * @private
+ */
+goog.crypt.base64.init_ = function() {
+  if (!goog.crypt.base64.byteToCharMap_) {
+    goog.crypt.base64.byteToCharMap_ = {};
+    goog.crypt.base64.charToByteMap_ = {};
+    goog.crypt.base64.byteToCharMapWebSafe_ = {};
+    goog.crypt.base64.charToByteMapWebSafe_ = {};
+
+    // We want quick mappings back and forth, so we precompute two maps.
+    for (var i = 0; i < goog.crypt.base64.ENCODED_VALS.length; i++) {
+      goog.crypt.base64.byteToCharMap_[i] =
+          goog.crypt.base64.ENCODED_VALS.charAt(i);
+      goog.crypt.base64.charToByteMap_[goog.crypt.base64.byteToCharMap_[i]] = 
i;
+      goog.crypt.base64.byteToCharMapWebSafe_[i] =
+          goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i);
+      goog.crypt.base64.charToByteMapWebSafe_[
+          goog.crypt.base64.byteToCharMapWebSafe_[i]] = i;
+
+      // Be forgiving when decoding and correctly decode both encodings.
+      if (i >= goog.crypt.base64.ENCODED_VALS_BASE.length) {
+        goog.crypt.base64.charToByteMap_[
+            goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
+        goog.crypt.base64.charToByteMapWebSafe_[
+            goog.crypt.base64.ENCODED_VALS.charAt(i)] = i;
+      }
+    }
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/basen.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/basen.js 
b/externs/GCL/externs/goog/crypt/basen.js
new file mode 100644
index 0000000..2bac248
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/basen.js
@@ -0,0 +1,242 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Numeric base conversion library.  Works for arbitrary bases 
and
+ * arbitrary length numbers.
+ *
+ * For base-64 conversion use base64.js because it is optimized for the 
specific
+ * conversion to base-64 while this module is generic.  Base-64 is defined here
+ * mostly for demonstration purpose.
+ *
+ * TODO: Make base64 and baseN classes that have common interface.  
(Perhaps...)
+ *
+ */
+
+goog.provide('goog.crypt.baseN');
+
+
+/**
+ * Base-2, i.e. '01'.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_BINARY = '01';
+
+
+/**
+ * Base-8, i.e. '01234567'.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_OCTAL = '01234567';
+
+
+/**
+ * Base-10, i.e. '0123456789'.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_DECIMAL = '0123456789';
+
+
+/**
+ * Base-16 using lower case, i.e. '0123456789abcdef'.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL = '0123456789abcdef';
+
+
+/**
+ * Base-16 using upper case, i.e. '0123456789ABCDEF'.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_UPPERCASE_HEXADECIMAL = '0123456789ABCDEF';
+
+
+/**
+ * The more-known version of the BASE-64 encoding.  Uses + and / characters.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_64 =
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+
+/**
+ * URL-safe version of the BASE-64 encoding.
+ * @type {string}
+ */
+goog.crypt.baseN.BASE_64_URL_SAFE =
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
+
+
+/**
+ * Converts a number from one numeric base to another.
+ *
+ * The bases are represented as strings, which list allowed digits.  Each digit
+ * should be unique.  The bases can either be user defined, or any of
+ * goog.crypt.baseN.BASE_xxx.
+ *
+ * The number is in human-readable format, most significant digit first, and is
+ * a non-negative integer.  Base designators such as $, 0x, d, b or h (at end)
+ * will be interpreted as digits, so avoid them.  Leading zeros will be 
trimmed.
+ *
+ * Note: for huge bases the result may be inaccurate because of overflowing
+ * 64-bit doubles used by JavaScript for integer calculus.  This may happen
+ * if the product of the number of digits in the input and output bases comes
+ * close to 10^16, which is VERY unlikely (100M digits in each base), but
+ * may be possible in the future unicode world.  (Unicode 3.2 has less than 
100K
+ * characters.  However, it reserves some more, close to 1M.)
+ *
+ * @param {string} number The number to convert.
+ * @param {string} inputBase The numeric base the number is in (all digits).
+ * @param {string} outputBase Requested numeric base.
+ * @return {string} The converted number.
+ */
+goog.crypt.baseN.recodeString = function(number, inputBase, outputBase) {
+  if (outputBase == '') {
+    throw Error('Empty output base');
+  }
+
+  // Check if number is 0 (special case when we don't want to return '').
+  var isZero = true;
+  for (var i = 0, n = number.length; i < n; i++) {
+    if (number.charAt(i) != inputBase.charAt(0)) {
+      isZero = false;
+      break;
+    }
+  }
+  if (isZero) {
+    return outputBase.charAt(0);
+  }
+
+  var numberDigits = goog.crypt.baseN.stringToArray_(number, inputBase);
+
+  var inputBaseSize = inputBase.length;
+  var outputBaseSize = outputBase.length;
+
+  // result = 0.
+  var result = [];
+
+  // For all digits of number, starting with the most significant ...
+  for (var i = numberDigits.length - 1; i >= 0; i--) {
+
+    // result *= number.base.
+    var carry = 0;
+    for (var j = 0, n = result.length; j < n; j++) {
+      var digit = result[j];
+      // This may overflow for huge bases.  See function comment.
+      digit = digit * inputBaseSize + carry;
+      if (digit >= outputBaseSize) {
+        var remainder = digit % outputBaseSize;
+        carry = (digit - remainder) / outputBaseSize;
+        digit = remainder;
+      } else {
+        carry = 0;
+      }
+      result[j] = digit;
+    }
+    while (carry) {
+      var remainder = carry % outputBaseSize;
+      result.push(remainder);
+      carry = (carry - remainder) / outputBaseSize;
+    }
+
+    // result += number[i].
+    carry = numberDigits[i];
+    var j = 0;
+    while (carry) {
+      if (j >= result.length) {
+        // Extend result with a leading zero which will be overwritten below.
+        result.push(0);
+      }
+      var digit = result[j];
+      digit += carry;
+      if (digit >= outputBaseSize) {
+        var remainder = digit % outputBaseSize;
+        carry = (digit - remainder) / outputBaseSize;
+        digit = remainder;
+      } else {
+        carry = 0;
+      }
+      result[j] = digit;
+      j++;
+    }
+  }
+
+  return goog.crypt.baseN.arrayToString_(result, outputBase);
+};
+
+
+/**
+ * Converts a string representation of a number to an array of digit values.
+ *
+ * More precisely, the digit values are indices into the number base, which
+ * is represented as a string, which can either be user defined or one of the
+ * BASE_xxx constants.
+ *
+ * Throws an Error if the number contains a digit not found in the base.
+ *
+ * @param {string} number The string to convert, most significant digit first.
+ * @param {string} base Digits in the base.
+ * @return {!Array<number>} Array of digit values, least significant digit
+ *     first.
+ * @private
+ */
+goog.crypt.baseN.stringToArray_ = function(number, base) {
+  var index = {};
+  for (var i = 0, n = base.length; i < n; i++) {
+    index[base.charAt(i)] = i;
+  }
+  var result = [];
+  for (var i = number.length - 1; i >= 0; i--) {
+    var character = number.charAt(i);
+    var digit = index[character];
+    if (typeof digit == 'undefined') {
+      throw Error('Number ' + number +
+                  ' contains a character not found in base ' +
+                  base + ', which is ' + character);
+    }
+    result.push(digit);
+  }
+  return result;
+};
+
+
+/**
+ * Converts an array representation of a number to a string.
+ *
+ * More precisely, the elements of the input array are indices into the base,
+ * which is represented as a string, which can either be user defined or one of
+ * the BASE_xxx constants.
+ *
+ * Throws an Error if the number contains a digit which is outside the range
+ * 0 ... base.length - 1.
+ *
+ * @param {Array<number>} number Array of digit values, least significant
+ *     first.
+ * @param {string} base Digits in the base.
+ * @return {string} Number as a string, most significant digit first.
+ * @private
+ */
+goog.crypt.baseN.arrayToString_ = function(number, base) {
+  var n = number.length;
+  var chars = [];
+  var baseSize = base.length;
+  for (var i = n - 1; i >= 0; i--) {
+    var digit = number[i];
+    if (digit >= baseSize || digit < 0) {
+      throw Error('Number ' + number + ' contains an invalid digit: ' + digit);
+    }
+    chars.push(base.charAt(digit));
+  }
+  return chars.join('');
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/blobhasher.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/blobhasher.js 
b/externs/GCL/externs/goog/crypt/blobhasher.js
new file mode 100644
index 0000000..cb4af79
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/blobhasher.js
@@ -0,0 +1,285 @@
+// Copyright 2011 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Asynchronous hash computer for the Blob interface.
+ *
+ * The Blob interface, part of the HTML5 File API, is supported on Chrome 7+,
+ * Firefox 4.0 and Opera 11. No Blob interface implementation is expected on
+ * Internet Explorer 10. Chrome 11, Firefox 5.0 and the subsequent release of
+ * Opera are supposed to use vendor prefixes due to evolving API, see
+ * http://dev.w3.org/2006/webapi/FileAPI/ for details.
+ *
+ * This implementation currently uses upcoming Chrome and Firefox prefixes,
+ * plus the original Blob.slice specification, as implemented on Chrome 10
+ * and Firefox 4.0.
+ *
+ */
+
+goog.provide('goog.crypt.BlobHasher');
+goog.provide('goog.crypt.BlobHasher.EventType');
+
+goog.require('goog.asserts');
+goog.require('goog.events.EventTarget');
+goog.require('goog.fs');
+goog.require('goog.log');
+
+
+
+/**
+ * Construct the hash computer.
+ *
+ * @param {!goog.crypt.Hash} hashFn The hash function to use.
+ * @param {number=} opt_blockSize Processing block size.
+ * @constructor
+ * @struct
+ * @suppress {checkStructDictInheritance}
+ * @extends {goog.events.EventTarget}
+ * @final
+ */
+goog.crypt.BlobHasher = function(hashFn, opt_blockSize) {
+  goog.crypt.BlobHasher.base(this, 'constructor');
+
+  /**
+   * The actual hash function.
+   * @type {!goog.crypt.Hash}
+   * @private
+   */
+  this.hashFn_ = hashFn;
+
+  /**
+   * The blob being processed or null if no blob is being processed.
+   * @type {Blob}
+   * @private
+   */
+  this.blob_ = null;
+
+  /**
+   * Computed hash value.
+   * @type {Array<number>}
+   * @private
+   */
+  this.hashVal_ = null;
+
+  /**
+   * Number of bytes already processed.
+   * @type {number}
+   * @private
+   */
+  this.bytesProcessed_ = 0;
+
+  /**
+   * The number of bytes to hash or Infinity for no limit.
+   * @type {number}
+   * @private
+   */
+  this.hashingLimit_ = Infinity;
+
+  /**
+   * Processing block size.
+   * @type {number}
+   * @private
+   */
+  this.blockSize_ = opt_blockSize || 5000000;
+
+  /**
+   * File reader object. Will be null if no chunk is currently being read.
+   * @type {FileReader}
+   * @private
+   */
+  this.fileReader_ = null;
+
+  /**
+   * The logger used by this object.
+   * @type {goog.log.Logger}
+   * @private
+   */
+  this.logger_ = goog.log.getLogger('goog.crypt.BlobHasher');
+};
+goog.inherits(goog.crypt.BlobHasher, goog.events.EventTarget);
+
+
+/**
+ * Event names for hash computation events
+ * @enum {string}
+ */
+goog.crypt.BlobHasher.EventType = {
+  STARTED: 'started',
+  PROGRESS: 'progress',
+  THROTTLED: 'throttled',
+  COMPLETE: 'complete',
+  ABORT: 'abort',
+  ERROR: 'error'
+};
+
+
+/**
+ * Start the hash computation.
+ * @param {!Blob} blob The blob of data to compute the hash for.
+ */
+goog.crypt.BlobHasher.prototype.hash = function(blob) {
+  this.abort();
+  this.hashFn_.reset();
+  this.blob_ = blob;
+  this.hashVal_ = null;
+  this.bytesProcessed_ = 0;
+  this.dispatchEvent(goog.crypt.BlobHasher.EventType.STARTED);
+
+  this.processNextBlock_();
+};
+
+
+/**
+ * Sets the maximum number of bytes to hash or Infinity for no limit. Can be
+ * called before hash() to throttle the hash computation. The hash computation
+ * can then be continued by repeatedly calling setHashingLimit() with greater
+ * byte offsets. This is useful if you don't need the hash until some time in
+ * the future, for example when uploading a file and you don't need the hash
+ * until the transfer is complete.
+ * @param {number} byteOffset The byte offset to compute the hash up to.
+ *     Should be a non-negative integer or Infinity for no limit. Negative
+ *     values are not allowed.
+ */
+goog.crypt.BlobHasher.prototype.setHashingLimit = function(byteOffset) {
+  goog.asserts.assert(byteOffset >= 0, 'Hashing limit must be non-negative.');
+  this.hashingLimit_ = byteOffset;
+
+  // Resume processing if a blob is currently being hashed, but no block read
+  // is currently in progress.
+  if (this.blob_ && !this.fileReader_) {
+    this.processNextBlock_();
+  }
+};
+
+
+/**
+ * Abort hash computation.
+ */
+goog.crypt.BlobHasher.prototype.abort = function() {
+  if (this.fileReader_) {
+    this.fileReader_.abort();
+    this.fileReader_ = null;
+  }
+
+  if (this.blob_) {
+    this.blob_ = null;
+    this.dispatchEvent(goog.crypt.BlobHasher.EventType.ABORT);
+  }
+};
+
+
+/**
+ * @return {number} Number of bytes processed so far.
+ */
+goog.crypt.BlobHasher.prototype.getBytesProcessed = function() {
+  return this.bytesProcessed_;
+};
+
+
+/**
+ * @return {Array<number>} The computed hash value or null if not ready.
+ */
+goog.crypt.BlobHasher.prototype.getHash = function() {
+  return this.hashVal_;
+};
+
+
+/**
+ * Helper function setting up the processing for the next block, or finalizing
+ * the computation if all blocks were processed.
+ * @private
+ */
+goog.crypt.BlobHasher.prototype.processNextBlock_ = function() {
+  goog.asserts.assert(this.blob_, 'A hash computation must be in progress.');
+
+  if (this.bytesProcessed_ < this.blob_.size) {
+
+    if (this.hashingLimit_ <= this.bytesProcessed_) {
+      // Throttle limit reached. Wait until we are allowed to hash more bytes.
+      this.dispatchEvent(goog.crypt.BlobHasher.EventType.THROTTLED);
+      return;
+    }
+
+    // We have to reset the FileReader every time, otherwise it fails on
+    // Chrome, including the latest Chrome 12 beta.
+    // http://code.google.com/p/chromium/issues/detail?id=82346
+    this.fileReader_ = new FileReader();
+    this.fileReader_.onload = goog.bind(this.onLoad_, this);
+    this.fileReader_.onerror = goog.bind(this.onError_, this);
+
+    var endOffset = Math.min(this.hashingLimit_, this.blob_.size);
+    var size = Math.min(endOffset - this.bytesProcessed_, this.blockSize_);
+    var chunk = goog.fs.sliceBlob(this.blob_, this.bytesProcessed_,
+                                  this.bytesProcessed_ + size);
+    if (!chunk || chunk.size != size) {
+      goog.log.error(this.logger_, 'Failed slicing the blob');
+      this.onError_();
+      return;
+    }
+
+    if (this.fileReader_.readAsArrayBuffer) {
+      this.fileReader_.readAsArrayBuffer(chunk);
+    } else if (this.fileReader_.readAsBinaryString) {
+      this.fileReader_.readAsBinaryString(chunk);
+    } else {
+      goog.log.error(this.logger_, 'Failed calling the chunk reader');
+      this.onError_();
+    }
+  } else {
+    this.hashVal_ = this.hashFn_.digest();
+    this.blob_ = null;
+    this.dispatchEvent(goog.crypt.BlobHasher.EventType.COMPLETE);
+  }
+};
+
+
+/**
+ * Handle processing block loaded.
+ * @private
+ */
+goog.crypt.BlobHasher.prototype.onLoad_ = function() {
+  goog.log.info(this.logger_, 'Successfully loaded a chunk');
+
+  var array = null;
+  if (this.fileReader_.result instanceof Array ||
+      goog.isString(this.fileReader_.result)) {
+    array = this.fileReader_.result;
+  } else if (goog.global['ArrayBuffer'] && goog.global['Uint8Array'] &&
+             this.fileReader_.result instanceof ArrayBuffer) {
+    array = new Uint8Array(this.fileReader_.result);
+  }
+  if (!array) {
+    goog.log.error(this.logger_, 'Failed reading the chunk');
+    this.onError_();
+    return;
+  }
+
+  this.hashFn_.update(array);
+  this.bytesProcessed_ += array.length;
+  this.fileReader_ = null;
+  this.dispatchEvent(goog.crypt.BlobHasher.EventType.PROGRESS);
+
+  this.processNextBlock_();
+};
+
+
+/**
+ * Handles error.
+ * @private
+ */
+goog.crypt.BlobHasher.prototype.onError_ = function() {
+  this.fileReader_ = null;
+  this.blob_ = null;
+  this.dispatchEvent(goog.crypt.BlobHasher.EventType.ERROR);
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/blockcipher.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/blockcipher.js 
b/externs/GCL/externs/goog/crypt/blockcipher.js
new file mode 100644
index 0000000..be766f0
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/blockcipher.js
@@ -0,0 +1,52 @@
+// Copyright 2012 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Interface definition of a block cipher. A block cipher is a
+ * pair of algorithms that implement encryption and decryption of input bytes.
+ *
+ * @see http://en.wikipedia.org/wiki/Block_cipher
+ *
+ * @author [email protected] (Nathan Naze)
+ */
+
+goog.provide('goog.crypt.BlockCipher');
+
+
+
+/**
+ * Interface definition for a block cipher.
+ * @interface
+ */
+goog.crypt.BlockCipher = function() {};
+
+
+/**
+ * Encrypt a plaintext block.  The implementation may expect (and assert)
+ * a particular block length.
+ * @param {!Array<number>} input Plaintext array of input bytes.
+ * @return {!Array<number>} Encrypted ciphertext array of bytes.  Should be the
+ *     same length as input.
+ */
+goog.crypt.BlockCipher.prototype.encrypt;
+
+
+/**
+ * Decrypt a plaintext block.  The implementation may expect (and assert)
+ * a particular block length.
+ * @param {!Array<number>} input Ciphertext. Array of input bytes.
+ * @return {!Array<number>} Decrypted plaintext array of bytes.  Should be the
+ *     same length as input.
+ */
+goog.crypt.BlockCipher.prototype.decrypt;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/cbc.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/cbc.js 
b/externs/GCL/externs/goog/crypt/cbc.js
new file mode 100644
index 0000000..68a2656
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/cbc.js
@@ -0,0 +1,153 @@
+// Copyright 2012 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Implementation of CBC mode for block ciphers.  See
+ *     http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
+ *     #Cipher-block_chaining_.28CBC.29. for description.
+ *
+ * @author [email protected] (Nathan Naze)
+ */
+
+goog.provide('goog.crypt.Cbc');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.crypt');
+
+
+
+/**
+ * Implements the CBC mode for block ciphers. See
+ * http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
+ * #Cipher-block_chaining_.28CBC.29
+ *
+ * @param {!goog.crypt.BlockCipher} cipher The block cipher to use.
+ * @param {number=} opt_blockSize The block size of the cipher in bytes.
+ *     Defaults to 16 bytes.
+ * @constructor
+ * @final
+ * @struct
+ */
+goog.crypt.Cbc = function(cipher, opt_blockSize) {
+
+  /**
+   * Block cipher.
+   * @type {!goog.crypt.BlockCipher}
+   * @private
+   */
+  this.cipher_ = cipher;
+
+  /**
+   * Block size in bytes.
+   * @type {number}
+   * @private
+   */
+  this.blockSize_ = opt_blockSize || 16;
+};
+
+
+/**
+ * Encrypt a message.
+ *
+ * @param {!Array<number>} plainText Message to encrypt. An array of bytes.
+ *     The length should be a multiple of the block size.
+ * @param {!Array<number>} initialVector Initial vector for the CBC mode.
+ *     An array of bytes with the same length as the block size.
+ * @return {!Array<number>} Encrypted message.
+ */
+goog.crypt.Cbc.prototype.encrypt = function(plainText, initialVector) {
+
+  goog.asserts.assert(
+      plainText.length % this.blockSize_ == 0,
+      'Data\'s length must be multiple of block size.');
+
+  goog.asserts.assert(
+      initialVector.length == this.blockSize_,
+      'Initial vector must be size of one block.');
+
+  // Implementation of
+  // http://en.wikipedia.org/wiki/File:Cbc_encryption.png
+
+  var cipherText = [];
+  var vector = initialVector;
+
+  // Generate each block of the encrypted cypher text.
+  for (var blockStartIndex = 0;
+       blockStartIndex < plainText.length;
+       blockStartIndex += this.blockSize_) {
+
+    // Takes one block from the input message.
+    var plainTextBlock = goog.array.slice(
+        plainText,
+        blockStartIndex,
+        blockStartIndex + this.blockSize_);
+
+    var input = goog.crypt.xorByteArray(plainTextBlock, vector);
+    var resultBlock = this.cipher_.encrypt(input);
+
+    goog.array.extend(cipherText, resultBlock);
+    vector = resultBlock;
+  }
+
+  return cipherText;
+};
+
+
+/**
+ * Decrypt a message.
+ *
+ * @param {!Array<number>} cipherText Message to decrypt. An array of bytes.
+ *     The length should be a multiple of the block size.
+ * @param {!Array<number>} initialVector Initial vector for the CBC mode.
+ *     An array of bytes with the same length as the block size.
+ * @return {!Array<number>} Decrypted message.
+ */
+goog.crypt.Cbc.prototype.decrypt = function(cipherText, initialVector) {
+
+  goog.asserts.assert(
+      cipherText.length % this.blockSize_ == 0,
+      'Data\'s length must be multiple of block size.');
+
+  goog.asserts.assert(
+      initialVector.length == this.blockSize_,
+      'Initial vector must be size of one block.');
+
+  // Implementation of
+  // http://en.wikipedia.org/wiki/File:Cbc_decryption.png
+
+  var plainText = [];
+  var blockStartIndex = 0;
+  var vector = initialVector;
+
+  // Generate each block of the decrypted plain text.
+  while (blockStartIndex < cipherText.length) {
+
+    // Takes one block.
+    var cipherTextBlock = goog.array.slice(
+        cipherText,
+        blockStartIndex,
+        blockStartIndex + this.blockSize_);
+
+    var resultBlock = this.cipher_.decrypt(cipherTextBlock);
+    var plainTextBlock = goog.crypt.xorByteArray(vector, resultBlock);
+
+    goog.array.extend(plainText, plainTextBlock);
+    vector = cipherTextBlock;
+
+    blockStartIndex += this.blockSize_;
+  }
+
+  return plainText;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/crypt.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/crypt.js 
b/externs/GCL/externs/goog/crypt/crypt.js
new file mode 100644
index 0000000..e8f722a
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/crypt.js
@@ -0,0 +1,173 @@
+// Copyright 2008 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Namespace with crypto related helper functions.
+ */
+
+goog.provide('goog.crypt');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+
+
+/**
+ * Turns a string into an array of bytes; a "byte" being a JS number in the
+ * range 0-255.
+ * @param {string} str String value to arrify.
+ * @return {!Array<number>} Array of numbers corresponding to the
+ *     UCS character codes of each character in str.
+ */
+goog.crypt.stringToByteArray = function(str) {
+  var output = [], p = 0;
+  for (var i = 0; i < str.length; i++) {
+    var c = str.charCodeAt(i);
+    while (c > 0xff) {
+      output[p++] = c & 0xff;
+      c >>= 8;
+    }
+    output[p++] = c;
+  }
+  return output;
+};
+
+
+/**
+ * Turns an array of numbers into the string given by the concatenation of the
+ * characters to which the numbers correspond.
+ * @param {Array<number>} bytes Array of numbers representing characters.
+ * @return {string} Stringification of the array.
+ */
+goog.crypt.byteArrayToString = function(bytes) {
+  var CHUNK_SIZE = 8192;
+
+  // Special-case the simple case for speed's sake.
+  if (bytes.length < CHUNK_SIZE) {
+    return String.fromCharCode.apply(null, bytes);
+  }
+
+  // The remaining logic splits conversion by chunks since
+  // Function#apply() has a maximum parameter count.
+  // See discussion: http://goo.gl/LrWmZ9
+
+  var str = '';
+  for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {
+    var chunk = goog.array.slice(bytes, i, i + CHUNK_SIZE);
+    str += String.fromCharCode.apply(null, chunk);
+  }
+  return str;
+};
+
+
+/**
+ * Turns an array of numbers into the hex string given by the concatenation of
+ * the hex values to which the numbers correspond.
+ * @param {Uint8Array|Array<number>} array Array of numbers representing
+ *     characters.
+ * @return {string} Hex string.
+ */
+goog.crypt.byteArrayToHex = function(array) {
+  return goog.array.map(array, function(numByte) {
+    var hexByte = numByte.toString(16);
+    return hexByte.length > 1 ? hexByte : '0' + hexByte;
+  }).join('');
+};
+
+
+/**
+ * Converts a hex string into an integer array.
+ * @param {string} hexString Hex string of 16-bit integers (two characters
+ *     per integer).
+ * @return {!Array<number>} Array of {0,255} integers for the given string.
+ */
+goog.crypt.hexToByteArray = function(hexString) {
+  goog.asserts.assert(hexString.length % 2 == 0,
+                      'Key string length must be multiple of 2');
+  var arr = [];
+  for (var i = 0; i < hexString.length; i += 2) {
+    arr.push(parseInt(hexString.substring(i, i + 2), 16));
+  }
+  return arr;
+};
+
+
+/**
+ * Converts a JS string to a UTF-8 "byte" array.
+ * @param {string} str 16-bit unicode string.
+ * @return {!Array<number>} UTF-8 byte array.
+ */
+goog.crypt.stringToUtf8ByteArray = function(str) {
+  // TODO(user): Use native implementations if/when available
+  str = str.replace(/\r\n/g, '\n');
+  var out = [], p = 0;
+  for (var i = 0; i < str.length; i++) {
+    var c = str.charCodeAt(i);
+    if (c < 128) {
+      out[p++] = c;
+    } else if (c < 2048) {
+      out[p++] = (c >> 6) | 192;
+      out[p++] = (c & 63) | 128;
+    } else {
+      out[p++] = (c >> 12) | 224;
+      out[p++] = ((c >> 6) & 63) | 128;
+      out[p++] = (c & 63) | 128;
+    }
+  }
+  return out;
+};
+
+
+/**
+ * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
+ * @param {Uint8Array|Array<number>} bytes UTF-8 byte array.
+ * @return {string} 16-bit Unicode string.
+ */
+goog.crypt.utf8ByteArrayToString = function(bytes) {
+  // TODO(user): Use native implementations if/when available
+  var out = [], pos = 0, c = 0;
+  while (pos < bytes.length) {
+    var c1 = bytes[pos++];
+    if (c1 < 128) {
+      out[c++] = String.fromCharCode(c1);
+    } else if (c1 > 191 && c1 < 224) {
+      var c2 = bytes[pos++];
+      out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
+    } else {
+      var c2 = bytes[pos++];
+      var c3 = bytes[pos++];
+      out[c++] = String.fromCharCode(
+          (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
+    }
+  }
+  return out.join('');
+};
+
+
+/**
+ * XOR two byte arrays.
+ * @param {!ArrayBufferView|!Array<number>} bytes1 Byte array 1.
+ * @param {!ArrayBufferView|!Array<number>} bytes2 Byte array 2.
+ * @return {!Array<number>} Resulting XOR of the two byte arrays.
+ */
+goog.crypt.xorByteArray = function(bytes1, bytes2) {
+  goog.asserts.assert(
+      bytes1.length == bytes2.length,
+      'XOR array lengths must match');
+
+  var result = [];
+  for (var i = 0; i < bytes1.length; i++) {
+    result.push(bytes1[i] ^ bytes2[i]);
+  }
+  return result;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/hash.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/hash.js 
b/externs/GCL/externs/goog/crypt/hash.js
new file mode 100644
index 0000000..51209be
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/hash.js
@@ -0,0 +1,69 @@
+// Copyright 2011 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Abstract cryptographic hash interface.
+ *
+ * See goog.crypt.Sha1 and goog.crypt.Md5 for sample implementations.
+ *
+ */
+
+goog.provide('goog.crypt.Hash');
+
+
+
+/**
+ * Create a cryptographic hash instance.
+ *
+ * @constructor
+ * @struct
+ */
+goog.crypt.Hash = function() {
+  /**
+   * The block size for the hasher.
+   * @type {number}
+   */
+  this.blockSize = -1;
+};
+
+
+/**
+ * Resets the internal accumulator.
+ */
+goog.crypt.Hash.prototype.reset = goog.abstractMethod;
+
+
+/**
+ * Adds a byte array (array with values in [0-255] range) or a string (might
+ * only contain 8-bit, i.e., Latin1 characters) to the internal accumulator.
+ *
+ * Many hash functions operate on blocks of data and implement optimizations
+ * when a full chunk of data is readily available. Hence it is often preferable
+ * to provide large chunks of data (a kilobyte or more) than to repeatedly
+ * call the update method with few tens of bytes. If this is not possible, or
+ * not feasible, it might be good to provide data in multiplies of hash block
+ * size (often 64 bytes). Please see the implementation and performance tests
+ * of your favourite hash.
+ *
+ * @param {Array<number>|Uint8Array|string} bytes Data used for the update.
+ * @param {number=} opt_length Number of bytes to use.
+ */
+goog.crypt.Hash.prototype.update = goog.abstractMethod;
+
+
+/**
+ * @return {!Array<number>} The finalized hash computed
+ *     from the internal accumulator.
+ */
+goog.crypt.Hash.prototype.digest = goog.abstractMethod;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/hash32.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/hash32.js 
b/externs/GCL/externs/goog/crypt/hash32.js
new file mode 100644
index 0000000..fa24ccf
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/hash32.js
@@ -0,0 +1,184 @@
+// Copyright 2008 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Implementation of 32-bit hashing functions.
+ *
+ * This is a direct port from the Google Java Hash class
+ *
+ */
+
+goog.provide('goog.crypt.hash32');
+
+goog.require('goog.crypt');
+
+
+/**
+ * Default seed used during hashing, digits of pie.
+ * See SEED32 in http://go/base.hash.java
+ * @type {number}
+ */
+goog.crypt.hash32.SEED32 = 314159265;
+
+
+/**
+ * Arbitrary constant used during hashing.
+ * See CONSTANT32 in http://go/base.hash.java
+ * @type {number}
+ */
+goog.crypt.hash32.CONSTANT32 = -1640531527;
+
+
+/**
+ * Hashes a string to a 32-bit value.
+ * @param {string} str String to hash.
+ * @return {number} 32-bit hash.
+ */
+goog.crypt.hash32.encodeString = function(str) {
+  return goog.crypt.hash32.encodeByteArray(goog.crypt.stringToByteArray(str));
+};
+
+
+/**
+ * Hashes a string to a 32-bit value, converting the string to UTF-8 before
+ * doing the encoding.
+ * @param {string} str String to hash.
+ * @return {number} 32-bit hash.
+ */
+goog.crypt.hash32.encodeStringUtf8 = function(str) {
+  return goog.crypt.hash32.encodeByteArray(
+      goog.crypt.stringToUtf8ByteArray(str));
+};
+
+
+/**
+ * Hashes an integer to a 32-bit value.
+ * @param {number} value Number to hash.
+ * @return {number} 32-bit hash.
+ */
+goog.crypt.hash32.encodeInteger = function(value) {
+  // TODO(user): Does this make sense in JavaScript with doubles?  Should we
+  // force the value to be in the correct range?
+  return goog.crypt.hash32.mix32_({
+    a: value,
+    b: goog.crypt.hash32.CONSTANT32,
+    c: goog.crypt.hash32.SEED32
+  });
+};
+
+
+/**
+ * Hashes a "byte" array to a 32-bit value using the supplied seed.
+ * @param {Array<number>} bytes Array of bytes.
+ * @param {number=} opt_offset The starting position to use for hash
+ * computation.
+ * @param {number=} opt_length Number of bytes that are used for hashing.
+ * @param {number=} opt_seed The seed.
+ * @return {number} 32-bit hash.
+ */
+goog.crypt.hash32.encodeByteArray = function(
+    bytes, opt_offset, opt_length, opt_seed) {
+  var offset = opt_offset || 0;
+  var length = opt_length || bytes.length;
+  var seed = opt_seed || goog.crypt.hash32.SEED32;
+
+  var mix = {
+    a: goog.crypt.hash32.CONSTANT32,
+    b: goog.crypt.hash32.CONSTANT32,
+    c: seed
+  };
+
+  var keylen;
+  for (keylen = length; keylen >= 12; keylen -= 12, offset += 12) {
+    mix.a += goog.crypt.hash32.wordAt_(bytes, offset);
+    mix.b += goog.crypt.hash32.wordAt_(bytes, offset + 4);
+    mix.c += goog.crypt.hash32.wordAt_(bytes, offset + 8);
+    goog.crypt.hash32.mix32_(mix);
+  }
+  // Hash any remaining bytes
+  mix.c += length;
+  switch (keylen) {  // deal with rest.  Some cases fall through
+    case 11: mix.c += (bytes[offset + 10]) << 24;
+    case 10: mix.c += (bytes[offset + 9] & 0xff) << 16;
+    case 9 : mix.c += (bytes[offset + 8] & 0xff) << 8;
+    // the first byte of c is reserved for the length
+    case 8 :
+      mix.b += goog.crypt.hash32.wordAt_(bytes, offset + 4);
+      mix.a += goog.crypt.hash32.wordAt_(bytes, offset);
+      break;
+    case 7 : mix.b += (bytes[offset + 6] & 0xff) << 16;
+    case 6 : mix.b += (bytes[offset + 5] & 0xff) << 8;
+    case 5 : mix.b += (bytes[offset + 4] & 0xff);
+    case 4 :
+      mix.a += goog.crypt.hash32.wordAt_(bytes, offset);
+      break;
+    case 3 : mix.a += (bytes[offset + 2] & 0xff) << 16;
+    case 2 : mix.a += (bytes[offset + 1] & 0xff) << 8;
+    case 1 : mix.a += (bytes[offset + 0] & 0xff);
+    // case 0 : nothing left to add
+  }
+  return goog.crypt.hash32.mix32_(mix);
+};
+
+
+/**
+ * Performs an inplace mix of an object with the integer properties (a, b, c)
+ * and returns the final value of c.
+ * @param {Object} mix Object with properties, a, b, and c.
+ * @return {number} The end c-value for the mixing.
+ * @private
+ */
+goog.crypt.hash32.mix32_ = function(mix) {
+  var a = mix.a, b = mix.b, c = mix.c;
+  a -= b; a -= c; a ^= c >>> 13;
+  b -= c; b -= a; b ^= a << 8;
+  c -= a; c -= b; c ^= b >>> 13;
+  a -= b; a -= c; a ^= c >>> 12;
+  b -= c; b -= a; b ^= a << 16;
+  c -= a; c -= b; c ^= b >>> 5;
+  a -= b; a -= c; a ^= c >>> 3;
+  b -= c; b -= a; b ^= a << 10;
+  c -= a; c -= b; c ^= b >>> 15;
+  mix.a = a; mix.b = b; mix.c = c;
+  return c;
+};
+
+
+/**
+ * Returns the word at a given offset.  Treating an array of bytes a word at a
+ * time is far more efficient than byte-by-byte.
+ * @param {Array<number>} bytes Array of bytes.
+ * @param {number} offset Offset in the byte array.
+ * @return {number} Integer value for the word.
+ * @private
+ */
+goog.crypt.hash32.wordAt_ = function(bytes, offset) {
+  var a = goog.crypt.hash32.toSigned_(bytes[offset + 0]);
+  var b = goog.crypt.hash32.toSigned_(bytes[offset + 1]);
+  var c = goog.crypt.hash32.toSigned_(bytes[offset + 2]);
+  var d = goog.crypt.hash32.toSigned_(bytes[offset + 3]);
+  return a + (b << 8) + (c << 16) + (d << 24);
+};
+
+
+/**
+ * Converts an unsigned "byte" to signed, that is, convert a value in the range
+ * (0, 2^8-1) to (-2^7, 2^7-1) in order to be compatible with Java's byte type.
+ * @param {number} n Unsigned "byte" value.
+ * @return {number} Signed "byte" value.
+ * @private
+ */
+goog.crypt.hash32.toSigned_ = function(n) {
+  return n > 127 ? n - 256 : n;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/hmac.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/hmac.js 
b/externs/GCL/externs/goog/crypt/hmac.js
new file mode 100644
index 0000000..15e0e1d
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/hmac.js
@@ -0,0 +1,160 @@
+// Copyright 2011 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Implementation of HMAC in JavaScript.
+ *
+ * Usage:
+ *   var hmac = new goog.crypt.Hmac(new goog.crypt.sha1(), key, 64);
+ *   var digest = hmac.getHmac(bytes);
+ *
+ * @author [email protected] (Jige Yu) - port to closure
+ */
+
+
+goog.provide('goog.crypt.Hmac');
+
+goog.require('goog.crypt.Hash');
+
+
+
+/**
+ * @constructor
+ * @param {!goog.crypt.Hash} hasher An object to serve as a hash function.
+ * @param {Array<number>} key The secret key to use to calculate the hmac.
+ *     Should be an array of not more than {@code blockSize} integers in
+       {0, 255}.
+ * @param {number=} opt_blockSize Optional. The block size {@code hasher} uses.
+ *     If not specified, uses the block size from the hasher, or 16 if it is
+ *     not specified.
+ * @extends {goog.crypt.Hash}
+ * @final
+ * @struct
+ */
+goog.crypt.Hmac = function(hasher, key, opt_blockSize) {
+  goog.crypt.Hmac.base(this, 'constructor');
+
+  /**
+   * The underlying hasher to calculate hash.
+   *
+   * @type {!goog.crypt.Hash}
+   * @private
+   */
+  this.hasher_ = hasher;
+
+  this.blockSize = opt_blockSize || hasher.blockSize || 16;
+
+  /**
+   * The outer padding array of hmac
+   *
+   * @type {!Array<number>}
+   * @private
+   */
+  this.keyO_ = new Array(this.blockSize);
+
+  /**
+   * The inner padding array of hmac
+   *
+   * @type {!Array<number>}
+   * @private
+   */
+  this.keyI_ = new Array(this.blockSize);
+
+  this.initialize_(key);
+};
+goog.inherits(goog.crypt.Hmac, goog.crypt.Hash);
+
+
+/**
+ * Outer padding byte of HMAC algorith, per http://en.wikipedia.org/wiki/HMAC
+ *
+ * @type {number}
+ * @private
+ */
+goog.crypt.Hmac.OPAD_ = 0x5c;
+
+
+/**
+ * Inner padding byte of HMAC algorith, per http://en.wikipedia.org/wiki/HMAC
+ *
+ * @type {number}
+ * @private
+ */
+goog.crypt.Hmac.IPAD_ = 0x36;
+
+
+/**
+ * Initializes Hmac by precalculating the inner and outer paddings.
+ *
+ * @param {Array<number>} key The secret key to use to calculate the hmac.
+ *     Should be an array of not more than {@code blockSize} integers in
+       {0, 255}.
+ * @private
+ */
+goog.crypt.Hmac.prototype.initialize_ = function(key) {
+  if (key.length > this.blockSize) {
+    this.hasher_.update(key);
+    key = this.hasher_.digest();
+    this.hasher_.reset();
+  }
+  // Precalculate padded and xor'd keys.
+  var keyByte;
+  for (var i = 0; i < this.blockSize; i++) {
+    if (i < key.length) {
+      keyByte = key[i];
+    } else {
+      keyByte = 0;
+    }
+    this.keyO_[i] = keyByte ^ goog.crypt.Hmac.OPAD_;
+    this.keyI_[i] = keyByte ^ goog.crypt.Hmac.IPAD_;
+  }
+  // Be ready for an immediate update.
+  this.hasher_.update(this.keyI_);
+};
+
+
+/** @override */
+goog.crypt.Hmac.prototype.reset = function() {
+  this.hasher_.reset();
+  this.hasher_.update(this.keyI_);
+};
+
+
+/** @override */
+goog.crypt.Hmac.prototype.update = function(bytes, opt_length) {
+  this.hasher_.update(bytes, opt_length);
+};
+
+
+/** @override */
+goog.crypt.Hmac.prototype.digest = function() {
+  var temp = this.hasher_.digest();
+  this.hasher_.reset();
+  this.hasher_.update(this.keyO_);
+  this.hasher_.update(temp);
+  return this.hasher_.digest();
+};
+
+
+/**
+ * Calculates an HMAC for a given message.
+ *
+ * @param {Array<number>|Uint8Array|string} message  Data to Hmac.
+ * @return {!Array<number>} the digest of the given message.
+ */
+goog.crypt.Hmac.prototype.getHmac = function(message) {
+  this.reset();
+  this.update(message);
+  return this.digest();
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/md5.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/md5.js 
b/externs/GCL/externs/goog/crypt/md5.js
new file mode 100644
index 0000000..56335e1
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/md5.js
@@ -0,0 +1,435 @@
+// Copyright 2011 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview MD5 cryptographic hash.
+ * Implementation of http://tools.ietf.org/html/rfc1321 with common
+ * optimizations and tweaks (see http://en.wikipedia.org/wiki/MD5).
+ *
+ * Usage:
+ *   var md5 = new goog.crypt.Md5();
+ *   md5.update(bytes);
+ *   var hash = md5.digest();
+ *
+ * Performance:
+ *   Chrome 23              ~680 Mbit/s
+ *   Chrome 13 (in a VM)    ~250 Mbit/s
+ *   Firefox 6.0 (in a VM)  ~100 Mbit/s
+ *   IE9 (in a VM)           ~27 Mbit/s
+ *   Firefox 3.6             ~15 Mbit/s
+ *   IE8 (in a VM)           ~13 Mbit/s
+ *
+ */
+
+goog.provide('goog.crypt.Md5');
+
+goog.require('goog.crypt.Hash');
+
+
+
+/**
+ * MD5 cryptographic hash constructor.
+ * @constructor
+ * @extends {goog.crypt.Hash}
+ * @final
+ * @struct
+ */
+goog.crypt.Md5 = function() {
+  goog.crypt.Md5.base(this, 'constructor');
+
+  this.blockSize = 512 / 8;
+
+  /**
+   * Holds the current values of accumulated A-D variables (MD buffer).
+   * @type {!Array<number>}
+   * @private
+   */
+  this.chain_ = new Array(4);
+
+  /**
+   * A buffer holding the data until the whole block can be processed.
+   * @type {!Array<number>}
+   * @private
+   */
+  this.block_ = new Array(this.blockSize);
+
+  /**
+   * The length of yet-unprocessed data as collected in the block.
+   * @type {number}
+   * @private
+   */
+  this.blockLength_ = 0;
+
+  /**
+   * The total length of the message so far.
+   * @type {number}
+   * @private
+   */
+  this.totalLength_ = 0;
+
+  this.reset();
+};
+goog.inherits(goog.crypt.Md5, goog.crypt.Hash);
+
+
+/**
+ * Integer rotation constants used by the abbreviated implementation.
+ * They are hardcoded in the unrolled implementation, so it is left
+ * here commented out.
+ * @type {Array<number>}
+ * @private
+ *
+goog.crypt.Md5.S_ = [
+  7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+  5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+  4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+  6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
+];
+ */
+
+/**
+ * Sine function constants used by the abbreviated implementation.
+ * They are hardcoded in the unrolled implementation, so it is left
+ * here commented out.
+ * @type {Array<number>}
+ * @private
+ *
+goog.crypt.Md5.T_ = [
+  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+];
+ */
+
+
+/** @override */
+goog.crypt.Md5.prototype.reset = function() {
+  this.chain_[0] = 0x67452301;
+  this.chain_[1] = 0xefcdab89;
+  this.chain_[2] = 0x98badcfe;
+  this.chain_[3] = 0x10325476;
+
+  this.blockLength_ = 0;
+  this.totalLength_ = 0;
+};
+
+
+/**
+ * Internal compress helper function. It takes a block of data (64 bytes)
+ * and updates the accumulator.
+ * @param {Array<number>|Uint8Array|string} buf The block to compress.
+ * @param {number=} opt_offset Offset of the block in the buffer.
+ * @private
+ */
+goog.crypt.Md5.prototype.compress_ = function(buf, opt_offset) {
+  if (!opt_offset) {
+    opt_offset = 0;
+  }
+
+  // We allocate the array every time, but it's cheap in practice.
+  var X = new Array(16);
+
+  // Get 16 little endian words. It is not worth unrolling this for Chrome 11.
+  if (goog.isString(buf)) {
+    for (var i = 0; i < 16; ++i) {
+      X[i] = (buf.charCodeAt(opt_offset++)) |
+             (buf.charCodeAt(opt_offset++) << 8) |
+             (buf.charCodeAt(opt_offset++) << 16) |
+             (buf.charCodeAt(opt_offset++) << 24);
+    }
+  } else {
+    for (var i = 0; i < 16; ++i) {
+      X[i] = (buf[opt_offset++]) |
+             (buf[opt_offset++] << 8) |
+             (buf[opt_offset++] << 16) |
+             (buf[opt_offset++] << 24);
+    }
+  }
+
+  var A = this.chain_[0];
+  var B = this.chain_[1];
+  var C = this.chain_[2];
+  var D = this.chain_[3];
+  var sum = 0;
+
+  /*
+   * This is an abbreviated implementation, it is left here commented out for
+   * reference purposes. See below for an unrolled version in use.
+   *
+  var f, n, tmp;
+  for (var i = 0; i < 64; ++i) {
+
+    if (i < 16) {
+      f = (D ^ (B & (C ^ D)));
+      n = i;
+    } else if (i < 32) {
+      f = (C ^ (D & (B ^ C)));
+      n = (5 * i + 1) % 16;
+    } else if (i < 48) {
+      f = (B ^ C ^ D);
+      n = (3 * i + 5) % 16;
+    } else {
+      f = (C ^ (B | (~D)));
+      n = (7 * i) % 16;
+    }
+
+    tmp = D;
+    D = C;
+    C = B;
+    sum = (A + f + goog.crypt.Md5.T_[i] + X[n]) & 0xffffffff;
+    B += ((sum << goog.crypt.Md5.S_[i]) & 0xffffffff) |
+         (sum >>> (32 - goog.crypt.Md5.S_[i]));
+    A = tmp;
+  }
+   */
+
+  /*
+   * This is an unrolled MD5 implementation, which gives ~30% speedup compared
+   * to the abbreviated implementation above, as measured on Chrome 11. It is
+   * important to keep 32-bit croppings to minimum and inline the integer
+   * rotation.
+   */
+  sum = (A + (D ^ (B & (C ^ D))) + X[0] + 0xd76aa478) & 0xffffffff;
+  A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
+  sum = (D + (C ^ (A & (B ^ C))) + X[1] + 0xe8c7b756) & 0xffffffff;
+  D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
+  sum = (C + (B ^ (D & (A ^ B))) + X[2] + 0x242070db) & 0xffffffff;
+  C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
+  sum = (B + (A ^ (C & (D ^ A))) + X[3] + 0xc1bdceee) & 0xffffffff;
+  B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
+  sum = (A + (D ^ (B & (C ^ D))) + X[4] + 0xf57c0faf) & 0xffffffff;
+  A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
+  sum = (D + (C ^ (A & (B ^ C))) + X[5] + 0x4787c62a) & 0xffffffff;
+  D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
+  sum = (C + (B ^ (D & (A ^ B))) + X[6] + 0xa8304613) & 0xffffffff;
+  C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
+  sum = (B + (A ^ (C & (D ^ A))) + X[7] + 0xfd469501) & 0xffffffff;
+  B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
+  sum = (A + (D ^ (B & (C ^ D))) + X[8] + 0x698098d8) & 0xffffffff;
+  A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
+  sum = (D + (C ^ (A & (B ^ C))) + X[9] + 0x8b44f7af) & 0xffffffff;
+  D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
+  sum = (C + (B ^ (D & (A ^ B))) + X[10] + 0xffff5bb1) & 0xffffffff;
+  C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
+  sum = (B + (A ^ (C & (D ^ A))) + X[11] + 0x895cd7be) & 0xffffffff;
+  B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
+  sum = (A + (D ^ (B & (C ^ D))) + X[12] + 0x6b901122) & 0xffffffff;
+  A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
+  sum = (D + (C ^ (A & (B ^ C))) + X[13] + 0xfd987193) & 0xffffffff;
+  D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
+  sum = (C + (B ^ (D & (A ^ B))) + X[14] + 0xa679438e) & 0xffffffff;
+  C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
+  sum = (B + (A ^ (C & (D ^ A))) + X[15] + 0x49b40821) & 0xffffffff;
+  B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
+  sum = (A + (C ^ (D & (B ^ C))) + X[1] + 0xf61e2562) & 0xffffffff;
+  A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
+  sum = (D + (B ^ (C & (A ^ B))) + X[6] + 0xc040b340) & 0xffffffff;
+  D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
+  sum = (C + (A ^ (B & (D ^ A))) + X[11] + 0x265e5a51) & 0xffffffff;
+  C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
+  sum = (B + (D ^ (A & (C ^ D))) + X[0] + 0xe9b6c7aa) & 0xffffffff;
+  B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
+  sum = (A + (C ^ (D & (B ^ C))) + X[5] + 0xd62f105d) & 0xffffffff;
+  A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
+  sum = (D + (B ^ (C & (A ^ B))) + X[10] + 0x02441453) & 0xffffffff;
+  D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
+  sum = (C + (A ^ (B & (D ^ A))) + X[15] + 0xd8a1e681) & 0xffffffff;
+  C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
+  sum = (B + (D ^ (A & (C ^ D))) + X[4] + 0xe7d3fbc8) & 0xffffffff;
+  B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
+  sum = (A + (C ^ (D & (B ^ C))) + X[9] + 0x21e1cde6) & 0xffffffff;
+  A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
+  sum = (D + (B ^ (C & (A ^ B))) + X[14] + 0xc33707d6) & 0xffffffff;
+  D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
+  sum = (C + (A ^ (B & (D ^ A))) + X[3] + 0xf4d50d87) & 0xffffffff;
+  C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
+  sum = (B + (D ^ (A & (C ^ D))) + X[8] + 0x455a14ed) & 0xffffffff;
+  B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
+  sum = (A + (C ^ (D & (B ^ C))) + X[13] + 0xa9e3e905) & 0xffffffff;
+  A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
+  sum = (D + (B ^ (C & (A ^ B))) + X[2] + 0xfcefa3f8) & 0xffffffff;
+  D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
+  sum = (C + (A ^ (B & (D ^ A))) + X[7] + 0x676f02d9) & 0xffffffff;
+  C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
+  sum = (B + (D ^ (A & (C ^ D))) + X[12] + 0x8d2a4c8a) & 0xffffffff;
+  B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
+  sum = (A + (B ^ C ^ D) + X[5] + 0xfffa3942) & 0xffffffff;
+  A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
+  sum = (D + (A ^ B ^ C) + X[8] + 0x8771f681) & 0xffffffff;
+  D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
+  sum = (C + (D ^ A ^ B) + X[11] + 0x6d9d6122) & 0xffffffff;
+  C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
+  sum = (B + (C ^ D ^ A) + X[14] + 0xfde5380c) & 0xffffffff;
+  B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
+  sum = (A + (B ^ C ^ D) + X[1] + 0xa4beea44) & 0xffffffff;
+  A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
+  sum = (D + (A ^ B ^ C) + X[4] + 0x4bdecfa9) & 0xffffffff;
+  D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
+  sum = (C + (D ^ A ^ B) + X[7] + 0xf6bb4b60) & 0xffffffff;
+  C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
+  sum = (B + (C ^ D ^ A) + X[10] + 0xbebfbc70) & 0xffffffff;
+  B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
+  sum = (A + (B ^ C ^ D) + X[13] + 0x289b7ec6) & 0xffffffff;
+  A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
+  sum = (D + (A ^ B ^ C) + X[0] + 0xeaa127fa) & 0xffffffff;
+  D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
+  sum = (C + (D ^ A ^ B) + X[3] + 0xd4ef3085) & 0xffffffff;
+  C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
+  sum = (B + (C ^ D ^ A) + X[6] + 0x04881d05) & 0xffffffff;
+  B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
+  sum = (A + (B ^ C ^ D) + X[9] + 0xd9d4d039) & 0xffffffff;
+  A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
+  sum = (D + (A ^ B ^ C) + X[12] + 0xe6db99e5) & 0xffffffff;
+  D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
+  sum = (C + (D ^ A ^ B) + X[15] + 0x1fa27cf8) & 0xffffffff;
+  C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
+  sum = (B + (C ^ D ^ A) + X[2] + 0xc4ac5665) & 0xffffffff;
+  B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
+  sum = (A + (C ^ (B | (~D))) + X[0] + 0xf4292244) & 0xffffffff;
+  A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
+  sum = (D + (B ^ (A | (~C))) + X[7] + 0x432aff97) & 0xffffffff;
+  D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
+  sum = (C + (A ^ (D | (~B))) + X[14] + 0xab9423a7) & 0xffffffff;
+  C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
+  sum = (B + (D ^ (C | (~A))) + X[5] + 0xfc93a039) & 0xffffffff;
+  B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
+  sum = (A + (C ^ (B | (~D))) + X[12] + 0x655b59c3) & 0xffffffff;
+  A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
+  sum = (D + (B ^ (A | (~C))) + X[3] + 0x8f0ccc92) & 0xffffffff;
+  D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
+  sum = (C + (A ^ (D | (~B))) + X[10] + 0xffeff47d) & 0xffffffff;
+  C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
+  sum = (B + (D ^ (C | (~A))) + X[1] + 0x85845dd1) & 0xffffffff;
+  B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
+  sum = (A + (C ^ (B | (~D))) + X[8] + 0x6fa87e4f) & 0xffffffff;
+  A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
+  sum = (D + (B ^ (A | (~C))) + X[15] + 0xfe2ce6e0) & 0xffffffff;
+  D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
+  sum = (C + (A ^ (D | (~B))) + X[6] + 0xa3014314) & 0xffffffff;
+  C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
+  sum = (B + (D ^ (C | (~A))) + X[13] + 0x4e0811a1) & 0xffffffff;
+  B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
+  sum = (A + (C ^ (B | (~D))) + X[4] + 0xf7537e82) & 0xffffffff;
+  A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
+  sum = (D + (B ^ (A | (~C))) + X[11] + 0xbd3af235) & 0xffffffff;
+  D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
+  sum = (C + (A ^ (D | (~B))) + X[2] + 0x2ad7d2bb) & 0xffffffff;
+  C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
+  sum = (B + (D ^ (C | (~A))) + X[9] + 0xeb86d391) & 0xffffffff;
+  B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
+
+  this.chain_[0] = (this.chain_[0] + A) & 0xffffffff;
+  this.chain_[1] = (this.chain_[1] + B) & 0xffffffff;
+  this.chain_[2] = (this.chain_[2] + C) & 0xffffffff;
+  this.chain_[3] = (this.chain_[3] + D) & 0xffffffff;
+};
+
+
+/** @override */
+goog.crypt.Md5.prototype.update = function(bytes, opt_length) {
+  if (!goog.isDef(opt_length)) {
+    opt_length = bytes.length;
+  }
+  var lengthMinusBlock = opt_length - this.blockSize;
+
+  // Copy some object properties to local variables in order to save on access
+  // time from inside the loop (~10% speedup was observed on Chrome 11).
+  var block = this.block_;
+  var blockLength = this.blockLength_;
+  var i = 0;
+
+  // The outer while loop should execute at most twice.
+  while (i < opt_length) {
+    // When we have no data in the block to top up, we can directly process the
+    // input buffer (assuming it contains sufficient data). This gives ~30%
+    // speedup on Chrome 14 and ~70% speedup on Firefox 6.0, but requires that
+    // the data is provided in large chunks (or in multiples of 64 bytes).
+    if (blockLength == 0) {
+      while (i <= lengthMinusBlock) {
+        this.compress_(bytes, i);
+        i += this.blockSize;
+      }
+    }
+
+    if (goog.isString(bytes)) {
+      while (i < opt_length) {
+        block[blockLength++] = bytes.charCodeAt(i++);
+        if (blockLength == this.blockSize) {
+          this.compress_(block);
+          blockLength = 0;
+          // Jump to the outer loop so we use the full-block optimization.
+          break;
+        }
+      }
+    } else {
+      while (i < opt_length) {
+        block[blockLength++] = bytes[i++];
+        if (blockLength == this.blockSize) {
+          this.compress_(block);
+          blockLength = 0;
+          // Jump to the outer loop so we use the full-block optimization.
+          break;
+        }
+      }
+    }
+  }
+
+  this.blockLength_ = blockLength;
+  this.totalLength_ += opt_length;
+};
+
+
+/** @override */
+goog.crypt.Md5.prototype.digest = function() {
+  // This must accommodate at least 1 padding byte (0x80), 8 bytes of
+  // total bitlength, and must end at a 64-byte boundary.
+  var pad = new Array((this.blockLength_ < 56 ?
+                       this.blockSize :
+                       this.blockSize * 2) - this.blockLength_);
+
+  // Add padding: 0x80 0x00*
+  pad[0] = 0x80;
+  for (var i = 1; i < pad.length - 8; ++i) {
+    pad[i] = 0;
+  }
+  // Add the total number of bits, little endian 64-bit integer.
+  var totalBits = this.totalLength_ * 8;
+  for (var i = pad.length - 8; i < pad.length; ++i) {
+    pad[i] = totalBits & 0xff;
+    totalBits /= 0x100; // Don't use bit-shifting here!
+  }
+  this.update(pad);
+
+  var digest = new Array(16);
+  var n = 0;
+  for (var i = 0; i < 4; ++i) {
+    for (var j = 0; j < 32; j += 8) {
+      digest[n++] = (this.chain_[i] >>> j) & 0xff;
+    }
+  }
+  return digest;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/pbkdf2.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/pbkdf2.js 
b/externs/GCL/externs/goog/crypt/pbkdf2.js
new file mode 100644
index 0000000..2fd1807
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/pbkdf2.js
@@ -0,0 +1,128 @@
+// Copyright 2012 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Implementation of PBKDF2 in JavaScript.
+ * @see http://en.wikipedia.org/wiki/PBKDF2
+ *
+ * Currently we only support HMAC-SHA1 as the underlying hash function. To add 
a
+ * new hash function, add a static method similar to 
deriveKeyFromPasswordSha1()
+ * and implement the specific computeBlockCallback() using the hash function.
+ *
+ * Usage:
+ *   var key = pbkdf2.deriveKeySha1(
+ *       stringToByteArray('password'), stringToByteArray('salt'), 1000, 128);
+ *
+ */
+
+goog.provide('goog.crypt.pbkdf2');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.crypt');
+goog.require('goog.crypt.Hmac');
+goog.require('goog.crypt.Sha1');
+
+
+/**
+ * Derives key from password using PBKDF2-SHA1
+ * @param {!Array<number>} password Byte array representation of the password
+ *     from which the key is derived.
+ * @param {!Array<number>} initialSalt Byte array representation of the salt.
+ * @param {number} iterations Number of interations when computing the key.
+ * @param {number} keyLength Length of the output key in bits.
+ *     Must be multiple of 8.
+ * @return {!Array<number>} Byte array representation of the output key.
+ */
+goog.crypt.pbkdf2.deriveKeySha1 = function(
+    password, initialSalt, iterations, keyLength) {
+  // Length of the HMAC-SHA1 output in bits.
+  var HASH_LENGTH = 160;
+
+  /**
+   * Compute each block of the key using HMAC-SHA1.
+   * @param {!Array<number>} index Byte array representation of the index of
+   *     the block to be computed.
+   * @return {!Array<number>} Byte array representation of the output block.
+   */
+  var computeBlock = function(index) {
+    // Initialize the result to be array of 0 such that its xor with the first
+    // block would be the first block.
+    var result = goog.array.repeat(0, HASH_LENGTH / 8);
+    // Initialize the salt of the first iteration to initialSalt || i.
+    var salt = initialSalt.concat(index);
+    var hmac = new goog.crypt.Hmac(new goog.crypt.Sha1(), password, 64);
+    // Compute and XOR each iteration.
+    for (var i = 0; i < iterations; i++) {
+      // The salt of the next iteration is the result of the current iteration.
+      salt = hmac.getHmac(salt);
+      result = goog.crypt.xorByteArray(result, salt);
+    }
+    return result;
+  };
+
+  return goog.crypt.pbkdf2.deriveKeyFromPassword_(
+      computeBlock, HASH_LENGTH, keyLength);
+};
+
+
+/**
+ * Compute each block of the key using PBKDF2.
+ * @param {Function} computeBlock Function to compute each block of the output
+ *     key.
+ * @param {number} hashLength Length of each block in bits. This is determined
+ *     by the specific hash function used. Must be multiple of 8.
+ * @param {number} keyLength Length of the output key in bits.
+ *     Must be multiple of 8.
+ * @return {!Array<number>} Byte array representation of the output key.
+ * @private
+ */
+goog.crypt.pbkdf2.deriveKeyFromPassword_ =
+    function(computeBlock, hashLength, keyLength) {
+  goog.asserts.assert(keyLength % 8 == 0, 'invalid output key length');
+
+  // Compute and concactate each block of the output key.
+  var numBlocks = Math.ceil(keyLength / hashLength);
+  goog.asserts.assert(numBlocks >= 1, 'invalid number of blocks');
+  var result = [];
+  for (var i = 1; i <= numBlocks; i++) {
+    var indexBytes = goog.crypt.pbkdf2.integerToByteArray_(i);
+    result = result.concat(computeBlock(indexBytes));
+  }
+
+  // Trim the last block if needed.
+  var lastBlockSize = keyLength % hashLength;
+  if (lastBlockSize != 0) {
+    var desiredBytes = ((numBlocks - 1) * hashLength + lastBlockSize) / 8;
+    result.splice(desiredBytes, (hashLength - lastBlockSize) / 8);
+  }
+  return result;
+};
+
+
+/**
+ * Converts an integer number to a 32-bit big endian byte array.
+ * @param {number} n Integer number to be converted.
+ * @return {!Array<number>} Byte Array representation of the 32-bit big endian
+ *     encoding of n.
+ * @private
+ */
+goog.crypt.pbkdf2.integerToByteArray_ = function(n) {
+  var result = new Array(4);
+  result[0] = n >> 24 & 0xFF;
+  result[1] = n >> 16 & 0xFF;
+  result[2] = n >> 8 & 0xFF;
+  result[3] = n & 0xFF;
+  return result;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/sha1.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/crypt/sha1.js 
b/externs/GCL/externs/goog/crypt/sha1.js
new file mode 100644
index 0000000..b1a5219
--- /dev/null
+++ b/externs/GCL/externs/goog/crypt/sha1.js
@@ -0,0 +1,294 @@
+// Copyright 2005 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview SHA-1 cryptographic hash.
+ * Variable names follow the notation in FIPS PUB 180-3:
+ * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
+ *
+ * Usage:
+ *   var sha1 = new goog.crypt.sha1();
+ *   sha1.update(bytes);
+ *   var hash = sha1.digest();
+ *
+ * Performance:
+ *   Chrome 23:   ~400 Mbit/s
+ *   Firefox 16:  ~250 Mbit/s
+ *
+ */
+
+goog.provide('goog.crypt.Sha1');
+
+goog.require('goog.crypt.Hash');
+
+
+
+/**
+ * SHA-1 cryptographic hash constructor.
+ *
+ * The properties declared here are discussed in the above algorithm document.
+ * @constructor
+ * @extends {goog.crypt.Hash}
+ * @final
+ * @struct
+ */
+goog.crypt.Sha1 = function() {
+  goog.crypt.Sha1.base(this, 'constructor');
+
+  this.blockSize = 512 / 8;
+
+  /**
+   * Holds the previous values of accumulated variables a-e in the compress_
+   * function.
+   * @type {!Array<number>}
+   * @private
+   */
+  this.chain_ = [];
+
+  /**
+   * A buffer holding the partially computed hash result.
+   * @type {!Array<number>}
+   * @private
+   */
+  this.buf_ = [];
+
+  /**
+   * An array of 80 bytes, each a part of the message to be hashed.  Referred 
to
+   * as the message schedule in the docs.
+   * @type {!Array<number>}
+   * @private
+   */
+  this.W_ = [];
+
+  /**
+   * Contains data needed to pad messages less than 64 bytes.
+   * @type {!Array<number>}
+   * @private
+   */
+  this.pad_ = [];
+
+  this.pad_[0] = 128;
+  for (var i = 1; i < this.blockSize; ++i) {
+    this.pad_[i] = 0;
+  }
+
+  /**
+   * @private {number}
+   */
+  this.inbuf_ = 0;
+
+  /**
+   * @private {number}
+   */
+  this.total_ = 0;
+
+  this.reset();
+};
+goog.inherits(goog.crypt.Sha1, goog.crypt.Hash);
+
+
+/** @override */
+goog.crypt.Sha1.prototype.reset = function() {
+  this.chain_[0] = 0x67452301;
+  this.chain_[1] = 0xefcdab89;
+  this.chain_[2] = 0x98badcfe;
+  this.chain_[3] = 0x10325476;
+  this.chain_[4] = 0xc3d2e1f0;
+
+  this.inbuf_ = 0;
+  this.total_ = 0;
+};
+
+
+/**
+ * Internal compress helper function.
+ * @param {!Array<number>|!Uint8Array|string} buf Block to compress.
+ * @param {number=} opt_offset Offset of the block in the buffer.
+ * @private
+ */
+goog.crypt.Sha1.prototype.compress_ = function(buf, opt_offset) {
+  if (!opt_offset) {
+    opt_offset = 0;
+  }
+
+  var W = this.W_;
+
+  // get 16 big endian words
+  if (goog.isString(buf)) {
+    for (var i = 0; i < 16; i++) {
+      // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS
+      // have a bug that turns the post-increment ++ operator into 
pre-increment
+      // during JIT compilation.  We have code that depends heavily on SHA-1 
for
+      // correctness and which is affected by this bug, so I've removed all 
uses
+      // of post-increment ++ in which the result value is used.  We can revert
+      // this change once the Safari bug
+      // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and
+      // most clients have been updated.
+      W[i] = (buf.charCodeAt(opt_offset) << 24) |
+             (buf.charCodeAt(opt_offset + 1) << 16) |
+             (buf.charCodeAt(opt_offset + 2) << 8) |
+             (buf.charCodeAt(opt_offset + 3));
+      opt_offset += 4;
+    }
+  } else {
+    for (var i = 0; i < 16; i++) {
+      W[i] = (buf[opt_offset] << 24) |
+             (buf[opt_offset + 1] << 16) |
+             (buf[opt_offset + 2] << 8) |
+             (buf[opt_offset + 3]);
+      opt_offset += 4;
+    }
+  }
+
+  // expand to 80 words
+  for (var i = 16; i < 80; i++) {
+    var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
+    W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;
+  }
+
+  var a = this.chain_[0];
+  var b = this.chain_[1];
+  var c = this.chain_[2];
+  var d = this.chain_[3];
+  var e = this.chain_[4];
+  var f, k;
+
+  // TODO(user): Try to unroll this loop to speed up the computation.
+  for (var i = 0; i < 80; i++) {
+    if (i < 40) {
+      if (i < 20) {
+        f = d ^ (b & (c ^ d));
+        k = 0x5a827999;
+      } else {
+        f = b ^ c ^ d;
+        k = 0x6ed9eba1;
+      }
+    } else {
+      if (i < 60) {
+        f = (b & c) | (d & (b | c));
+        k = 0x8f1bbcdc;
+      } else {
+        f = b ^ c ^ d;
+        k = 0xca62c1d6;
+      }
+    }
+
+    var t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;
+    e = d;
+    d = c;
+    c = ((b << 30) | (b >>> 2)) & 0xffffffff;
+    b = a;
+    a = t;
+  }
+
+  this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
+  this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
+  this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
+  this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
+  this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
+};
+
+
+/** @override */
+goog.crypt.Sha1.prototype.update = function(bytes, opt_length) {
+  // TODO(johnlenz): tighten the function signature and remove this check
+  if (bytes == null) {
+    return;
+  }
+
+  if (!goog.isDef(opt_length)) {
+    opt_length = bytes.length;
+  }
+
+  var lengthMinusBlock = opt_length - this.blockSize;
+  var n = 0;
+  // Using local instead of member variables gives ~5% speedup on Firefox 16.
+  var buf = this.buf_;
+  var inbuf = this.inbuf_;
+
+  // The outer while loop should execute at most twice.
+  while (n < opt_length) {
+    // When we have no data in the block to top up, we can directly process the
+    // input buffer (assuming it contains sufficient data). This gives ~25%
+    // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that
+    // the data is provided in large chunks (or in multiples of 64 bytes).
+    if (inbuf == 0) {
+      while (n <= lengthMinusBlock) {
+        this.compress_(bytes, n);
+        n += this.blockSize;
+      }
+    }
+
+    if (goog.isString(bytes)) {
+      while (n < opt_length) {
+        buf[inbuf] = bytes.charCodeAt(n);
+        ++inbuf;
+        ++n;
+        if (inbuf == this.blockSize) {
+          this.compress_(buf);
+          inbuf = 0;
+          // Jump to the outer loop so we use the full-block optimization.
+          break;
+        }
+      }
+    } else {
+      while (n < opt_length) {
+        buf[inbuf] = bytes[n];
+        ++inbuf;
+        ++n;
+        if (inbuf == this.blockSize) {
+          this.compress_(buf);
+          inbuf = 0;
+          // Jump to the outer loop so we use the full-block optimization.
+          break;
+        }
+      }
+    }
+  }
+
+  this.inbuf_ = inbuf;
+  this.total_ += opt_length;
+};
+
+
+/** @override */
+goog.crypt.Sha1.prototype.digest = function() {
+  var digest = [];
+  var totalBits = this.total_ * 8;
+
+  // Add pad 0x80 0x00*.
+  if (this.inbuf_ < 56) {
+    this.update(this.pad_, 56 - this.inbuf_);
+  } else {
+    this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));
+  }
+
+  // Add # bits.
+  for (var i = this.blockSize - 1; i >= 56; i--) {
+    this.buf_[i] = totalBits & 255;
+    totalBits /= 256; // Don't use bit-shifting here!
+  }
+
+  this.compress_(this.buf_);
+
+  var n = 0;
+  for (var i = 0; i < 5; i++) {
+    for (var j = 24; j >= 0; j -= 8) {
+      digest[n] = (this.chain_[i] >> j) & 255;
+      ++n;
+    }
+  }
+
+  return digest;
+};

Reply via email to