http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/bootstrap/webworkers.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/bootstrap/webworkers.js b/externs/GCL/externs/goog/bootstrap/webworkers.js new file mode 100644 index 0000000..7799a0a --- /dev/null +++ b/externs/GCL/externs/goog/bootstrap/webworkers.js @@ -0,0 +1,37 @@ +// Copyright 2010 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 A bootstrap for dynamically requiring Closure within an HTML5 + * Web Worker context. To use this, first set CLOSURE_BASE_PATH to the directory + * containing base.js (relative to the main script), then use importScripts to + * load this file and base.js (in that order). After this you can use + * goog.require for further imports. + * + * @nocompile + */ + + +/** + * Imports a script using the Web Worker importScript API. + * + * @param {string} src The script source. + * @return {boolean} True if the script was imported, false otherwise. + */ +this.CLOSURE_IMPORT_SCRIPT = (function(global) { + return function(src) { + global['importScripts'](src); + return true; + }; +})(this);
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/color/alpha.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/color/alpha.js b/externs/GCL/externs/goog/color/alpha.js new file mode 100644 index 0000000..4cd4781 --- /dev/null +++ b/externs/GCL/externs/goog/color/alpha.js @@ -0,0 +1,472 @@ +// Copyright 2006 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 Utilities related to alpha/transparent colors and alpha color + * conversion. + */ + +goog.provide('goog.color.alpha'); + +goog.require('goog.color'); + + +/** + * Parses an alpha color out of a string. + * @param {string} str Color in some format. + * @return {{hex: string, type: string}} 'hex' is a string containing + * a hex representation of the color, and 'type' is a string + * containing the type of color format passed in ('hex', 'rgb', 'named'). + */ +goog.color.alpha.parse = function(str) { + var result = {}; + str = String(str); + + var maybeHex = goog.color.prependHashIfNecessaryHelper(str); + if (goog.color.alpha.isValidAlphaHexColor_(maybeHex)) { + result.hex = goog.color.alpha.normalizeAlphaHex_(maybeHex); + result.type = 'hex'; + return result; + } else { + var rgba = goog.color.alpha.isValidRgbaColor_(str); + if (rgba.length) { + result.hex = goog.color.alpha.rgbaArrayToHex(rgba); + result.type = 'rgba'; + return result; + } else { + var hsla = goog.color.alpha.isValidHslaColor_(str); + if (hsla.length) { + result.hex = goog.color.alpha.hslaArrayToHex(hsla); + result.type = 'hsla'; + return result; + } + } + } + throw Error(str + ' is not a valid color string'); +}; + + +/** + * Converts a hex representation of a color to RGBA. + * @param {string} hexColor Color to convert. + * @return {string} string of the form 'rgba(R,G,B,A)' which can be used in + * styles. + */ +goog.color.alpha.hexToRgbaStyle = function(hexColor) { + return goog.color.alpha.rgbaStyle_(goog.color.alpha.hexToRgba(hexColor)); +}; + + +/** + * Gets the hex color part of an alpha hex color. For example, from '#abcdef55' + * return '#abcdef'. + * @param {string} colorWithAlpha The alpha hex color to get the hex color from. + * @return {string} The hex color where the alpha part has been stripped off. + */ +goog.color.alpha.extractHexColor = function(colorWithAlpha) { + if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) { + var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha); + var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor); + return normalizedColor.substring(0, 7); + } else { + throw Error(colorWithAlpha + ' is not a valid 8-hex color string'); + } +}; + + +/** + * Gets the alpha color part of an alpha hex color. For example, from + * '#abcdef55' return '55'. The result is guaranteed to be two characters long. + * @param {string} colorWithAlpha The alpha hex color to get the hex color from. + * @return {string} The hex color where the alpha part has been stripped off. + */ +goog.color.alpha.extractAlpha = function(colorWithAlpha) { + if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) { + var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha); + var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor); + return normalizedColor.substring(7, 9); + } else { + throw Error(colorWithAlpha + ' is not a valid 8-hex color string'); + } +}; + + +/** + * Regular expression for extracting the digits in a hex color quadruplet. + * @type {RegExp} + * @private + */ +goog.color.alpha.hexQuadrupletRe_ = /#(.)(.)(.)(.)/; + + +/** + * Normalize a hex representation of an alpha color. + * @param {string} hexColor an alpha hex color string. + * @return {string} hex color in the format '#rrggbbaa' with all lowercase + * literals. + * @private + */ +goog.color.alpha.normalizeAlphaHex_ = function(hexColor) { + if (!goog.color.alpha.isValidAlphaHexColor_(hexColor)) { + throw Error("'" + hexColor + "' is not a valid alpha hex color"); + } + if (hexColor.length == 5) { // of the form #RGBA + hexColor = hexColor.replace(goog.color.alpha.hexQuadrupletRe_, + '#$1$1$2$2$3$3$4$4'); + } + return hexColor.toLowerCase(); +}; + + +/** + * Converts an 8-hex representation of a color to RGBA. + * @param {string} hexColor Color to convert. + * @return {!Array<number>} array containing [r, g, b, a]. + * r, g, b are ints between 0 + * and 255, and a is a value between 0 and 1. + */ +goog.color.alpha.hexToRgba = function(hexColor) { + // TODO(user): Enhance code sharing with goog.color, for example by + // adding a goog.color.genericHexToRgb method. + hexColor = goog.color.alpha.normalizeAlphaHex_(hexColor); + var r = parseInt(hexColor.substr(1, 2), 16); + var g = parseInt(hexColor.substr(3, 2), 16); + var b = parseInt(hexColor.substr(5, 2), 16); + var a = parseInt(hexColor.substr(7, 2), 16); + + return [r, g, b, a / 255]; +}; + + +/** + * Converts a color from RGBA to hex representation. + * @param {number} r Amount of red, int between 0 and 255. + * @param {number} g Amount of green, int between 0 and 255. + * @param {number} b Amount of blue, int between 0 and 255. + * @param {number} a Amount of alpha, float between 0 and 1. + * @return {string} hex representation of the color. + */ +goog.color.alpha.rgbaToHex = function(r, g, b, a) { + var intAlpha = Math.floor(a * 255); + if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) { + // TODO(user): The CSS spec says the value should be clamped. + throw Error('"(' + r + ',' + g + ',' + b + ',' + a + + '") is not a valid RGBA color'); + } + var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16)); + return goog.color.rgbToHex(r, g, b) + hexA; +}; + + +/** + * Converts a color from HSLA to hex representation. + * @param {number} h Amount of hue, int between 0 and 360. + * @param {number} s Amount of saturation, int between 0 and 100. + * @param {number} l Amount of lightness, int between 0 and 100. + * @param {number} a Amount of alpha, float between 0 and 1. + * @return {string} hex representation of the color. + */ +goog.color.alpha.hslaToHex = function(h, s, l, a) { + var intAlpha = Math.floor(a * 255); + if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) { + // TODO(user): The CSS spec says the value should be clamped. + throw Error('"(' + h + ',' + s + ',' + l + ',' + a + + '") is not a valid HSLA color'); + } + var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16)); + return goog.color.hslToHex(h, s / 100, l / 100) + hexA; +}; + + +/** + * Converts a color from RGBA to hex representation. + * @param {Array<number>} rgba Array of [r, g, b, a], with r, g, b in [0, 255] + * and a in [0, 1]. + * @return {string} hex representation of the color. + */ +goog.color.alpha.rgbaArrayToHex = function(rgba) { + return goog.color.alpha.rgbaToHex(rgba[0], rgba[1], rgba[2], rgba[3]); +}; + + +/** + * Converts a color from RGBA to an RGBA style string. + * @param {number} r Value of red, in [0, 255]. + * @param {number} g Value of green, in [0, 255]. + * @param {number} b Value of blue, in [0, 255]. + * @param {number} a Value of alpha, in [0, 1]. + * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule. + */ +goog.color.alpha.rgbaToRgbaStyle = function(r, g, b, a) { + if (isNaN(r) || r < 0 || r > 255 || + isNaN(g) || g < 0 || g > 255 || + isNaN(b) || b < 0 || b > 255 || + isNaN(a) || a < 0 || a > 1) { + throw Error('"(' + r + ',' + g + ',' + b + ',' + a + + ')" is not a valid RGBA color'); + } + return goog.color.alpha.rgbaStyle_([r, g, b, a]); +}; + + +/** + * Converts a color from RGBA to an RGBA style string. + * @param {(Array<number>|Float32Array)} rgba Array of [r, g, b, a], + * with r, g, b in [0, 255] and a in [0, 1]. + * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule. + */ +goog.color.alpha.rgbaArrayToRgbaStyle = function(rgba) { + return goog.color.alpha.rgbaToRgbaStyle(rgba[0], rgba[1], rgba[2], rgba[3]); +}; + + +/** + * Converts a color from HSLA to hex representation. + * @param {Array<number>} hsla Array of [h, s, l, a], where h is an integer in + * [0, 360], s and l are integers in [0, 100], and a is in [0, 1]. + * @return {string} hex representation of the color, such as '#af457eff'. + */ +goog.color.alpha.hslaArrayToHex = function(hsla) { + return goog.color.alpha.hslaToHex(hsla[0], hsla[1], hsla[2], hsla[3]); +}; + + +/** + * Converts a color from HSLA to an RGBA style string. + * @param {Array<number>} hsla Array of [h, s, l, a], where h is and integer in + * [0, 360], s and l are integers in [0, 100], and a is in [0, 1]. + * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule. + */ +goog.color.alpha.hslaArrayToRgbaStyle = function(hsla) { + return goog.color.alpha.hslaToRgbaStyle(hsla[0], hsla[1], hsla[2], hsla[3]); +}; + + +/** + * Converts a color from HSLA to an RGBA style string. + * @param {number} h Amount of hue, int between 0 and 360. + * @param {number} s Amount of saturation, int between 0 and 100. + * @param {number} l Amount of lightness, int between 0 and 100. + * @param {number} a Amount of alpha, float between 0 and 1. + * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule. + * styles. + */ +goog.color.alpha.hslaToRgbaStyle = function(h, s, l, a) { + return goog.color.alpha.rgbaStyle_(goog.color.alpha.hslaToRgba(h, s, l, a)); +}; + + +/** + * Converts a color from HSLA color space to RGBA color space. + * @param {number} h Amount of hue, int between 0 and 360. + * @param {number} s Amount of saturation, int between 0 and 100. + * @param {number} l Amount of lightness, int between 0 and 100. + * @param {number} a Amount of alpha, float between 0 and 1. + * @return {!Array<number>} [r, g, b, a] values for the color, where r, g, b + * are integers in [0, 255] and a is a float in [0, 1]. + */ +goog.color.alpha.hslaToRgba = function(h, s, l, a) { + return goog.color.hslToRgb(h, s / 100, l / 100).concat(a); +}; + + +/** + * Converts a color from RGBA color space to HSLA color space. + * Modified from {@link http://en.wikipedia.org/wiki/HLS_color_space}. + * @param {number} r Value of red, in [0, 255]. + * @param {number} g Value of green, in [0, 255]. + * @param {number} b Value of blue, in [0, 255]. + * @param {number} a Value of alpha, in [0, 255]. + * @return {!Array<number>} [h, s, l, a] values for the color, with h an int in + * [0, 360] and s, l and a in [0, 1]. + */ +goog.color.alpha.rgbaToHsla = function(r, g, b, a) { + return goog.color.rgbToHsl(r, g, b).concat(a); +}; + + +/** + * Converts a color from RGBA color space to HSLA color space. + * @param {Array<number>} rgba [r, g, b, a] values for the color, each in + * [0, 255]. + * @return {!Array<number>} [h, s, l, a] values for the color, with h in + * [0, 360] and s, l and a in [0, 1]. + */ +goog.color.alpha.rgbaArrayToHsla = function(rgba) { + return goog.color.alpha.rgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]); +}; + + +/** + * Helper for isValidAlphaHexColor_. + * @type {RegExp} + * @private + */ +goog.color.alpha.validAlphaHexColorRe_ = /^#(?:[0-9a-f]{4}){1,2}$/i; + + +/** + * Checks if a string is a valid alpha hex color. We expect strings of the + * format #RRGGBBAA (ex: #1b3d5f5b) or #RGBA (ex: #3CAF == #33CCAAFF). + * @param {string} str String to check. + * @return {boolean} Whether the string is a valid alpha hex color. + * @private + */ +// TODO(user): Support percentages when goog.color also supports them. +goog.color.alpha.isValidAlphaHexColor_ = function(str) { + return goog.color.alpha.validAlphaHexColorRe_.test(str); +}; + + +/** + * Helper for isNormalizedAlphaHexColor_. + * @type {RegExp} + * @private + */ +goog.color.alpha.normalizedAlphaHexColorRe_ = /^#[0-9a-f]{8}$/; + + +/** + * Checks if a string is a normalized alpha hex color. + * We expect strings of the format #RRGGBBAA (ex: #1b3d5f5b) + * using only lowercase letters. + * @param {string} str String to check. + * @return {boolean} Whether the string is a normalized hex color. + * @private + */ +goog.color.alpha.isNormalizedAlphaHexColor_ = function(str) { + return goog.color.alpha.normalizedAlphaHexColorRe_.test(str); +}; + + +/** + * Regular expression for matching and capturing RGBA style strings. Helper for + * isValidRgbaColor_. + * @type {RegExp} + * @private + */ +goog.color.alpha.rgbaColorRe_ = + /^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,10})\)$/i; + + +/** + * Regular expression for matching and capturing HSLA style strings. Helper for + * isValidHslaColor_. + * @type {RegExp} + * @private + */ +goog.color.alpha.hslaColorRe_ = + /^(?:hsla)\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\%,\s?(0|[1-9]\d{0,2})\%,\s?(0|1|0\.\d{0,10})\)$/i; + + +/** + * Checks if a string is a valid rgba color. We expect strings of the format + * '(r, g, b, a)', or 'rgba(r, g, b, a)', where r, g, b are ints in [0, 255] + * and a is a float in [0, 1]. + * @param {string} str String to check. + * @return {!Array<number>} the integers [r, g, b, a] for valid colors or the + * empty array for invalid colors. + * @private + */ +goog.color.alpha.isValidRgbaColor_ = function(str) { + // Each component is separate (rather than using a repeater) so we can + // capture the match. Also, we explicitly set each component to be either 0, + // or start with a non-zero, to prevent octal numbers from slipping through. + var regExpResultArray = str.match(goog.color.alpha.rgbaColorRe_); + if (regExpResultArray) { + var r = Number(regExpResultArray[1]); + var g = Number(regExpResultArray[2]); + var b = Number(regExpResultArray[3]); + var a = Number(regExpResultArray[4]); + if (r >= 0 && r <= 255 && + g >= 0 && g <= 255 && + b >= 0 && b <= 255 && + a >= 0 && a <= 1) { + return [r, g, b, a]; + } + } + return []; +}; + + +/** + * Checks if a string is a valid hsla color. We expect strings of the format + * 'hsla(h, s, l, a)', where s in an int in [0, 360], s and l are percentages + * between 0 and 100 such as '50%' or '70%', and a is a float in [0, 1]. + * @param {string} str String to check. + * @return {!Array<number>} the integers [h, s, l, a] for valid colors or the + * empty array for invalid colors. + * @private + */ +goog.color.alpha.isValidHslaColor_ = function(str) { + // Each component is separate (rather than using a repeater) so we can + // capture the match. Also, we explicitly set each component to be either 0, + // or start with a non-zero, to prevent octal numbers from slipping through. + var regExpResultArray = str.match(goog.color.alpha.hslaColorRe_); + if (regExpResultArray) { + var h = Number(regExpResultArray[1]); + var s = Number(regExpResultArray[2]); + var l = Number(regExpResultArray[3]); + var a = Number(regExpResultArray[4]); + if (h >= 0 && h <= 360 && + s >= 0 && s <= 100 && + l >= 0 && l <= 100 && + a >= 0 && a <= 1) { + return [h, s, l, a]; + } + } + return []; +}; + + +/** + * Takes an array of [r, g, b, a] and converts it into a string appropriate for + * CSS styles. The alpha channel value is rounded to 3 decimal places to make + * sure the produced string is not too long. + * @param {Array<number>} rgba [r, g, b, a] with r, g, b in [0, 255] and a + * in [0, 1]. + * @return {string} string of the form 'rgba(r,g,b,a)'. + * @private + */ +goog.color.alpha.rgbaStyle_ = function(rgba) { + var roundedRgba = rgba.slice(0); + roundedRgba[3] = Math.round(rgba[3] * 1000) / 1000; + return 'rgba(' + roundedRgba.join(',') + ')'; +}; + + +/** + * Converts from h,s,v,a values to a hex string + * @param {number} h Hue, in [0, 1]. + * @param {number} s Saturation, in [0, 1]. + * @param {number} v Value, in [0, 255]. + * @param {number} a Alpha, in [0, 1]. + * @return {string} hex representation of the color. + */ +goog.color.alpha.hsvaToHex = function(h, s, v, a) { + var alpha = Math.floor(a * 255); + return goog.color.hsvArrayToHex([h, s, v]) + + goog.color.prependZeroIfNecessaryHelper(alpha.toString(16)); +}; + + +/** + * Converts from an HSVA array to a hex string + * @param {Array<number>} hsva Array of [h, s, v, a] in + * [[0, 1], [0, 1], [0, 255], [0, 1]]. + * @return {string} hex representation of the color. + */ +goog.color.alpha.hsvaArrayToHex = function(hsva) { + return goog.color.alpha.hsvaToHex(hsva[0], hsva[1], hsva[2], hsva[3]); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/color/color.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/color/color.js b/externs/GCL/externs/goog/color/color.js new file mode 100644 index 0000000..8220532 --- /dev/null +++ b/externs/GCL/externs/goog/color/color.js @@ -0,0 +1,776 @@ +// Copyright 2006 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 Utilities related to color and color conversion. + */ + +goog.provide('goog.color'); +goog.provide('goog.color.Hsl'); +goog.provide('goog.color.Hsv'); +goog.provide('goog.color.Rgb'); + +goog.require('goog.color.names'); +goog.require('goog.math'); + + +/** + * RGB color representation. An array containing three elements [r, g, b], + * each an integer in [0, 255], representing the red, green, and blue components + * of the color respectively. + * @typedef {Array<number>} + */ +goog.color.Rgb; + + +/** + * HSV color representation. An array containing three elements [h, s, v]: + * h (hue) must be an integer in [0, 360], cyclic. + * s (saturation) must be a number in [0, 1]. + * v (value/brightness) must be an integer in [0, 255]. + * @typedef {Array<number>} + */ +goog.color.Hsv; + + +/** + * HSL color representation. An array containing three elements [h, s, l]: + * h (hue) must be an integer in [0, 360], cyclic. + * s (saturation) must be a number in [0, 1]. + * l (lightness) must be a number in [0, 1]. + * @typedef {Array<number>} + */ +goog.color.Hsl; + + +/** + * Parses a color out of a string. + * @param {string} str Color in some format. + * @return {{hex: string, type: string}} 'hex' is a string containing a hex + * representation of the color, 'type' is a string containing the type + * of color format passed in ('hex', 'rgb', 'named'). + */ +goog.color.parse = function(str) { + var result = {}; + str = String(str); + + var maybeHex = goog.color.prependHashIfNecessaryHelper(str); + if (goog.color.isValidHexColor_(maybeHex)) { + result.hex = goog.color.normalizeHex(maybeHex); + result.type = 'hex'; + return result; + } else { + var rgb = goog.color.isValidRgbColor_(str); + if (rgb.length) { + result.hex = goog.color.rgbArrayToHex(rgb); + result.type = 'rgb'; + return result; + } else if (goog.color.names) { + var hex = goog.color.names[str.toLowerCase()]; + if (hex) { + result.hex = hex; + result.type = 'named'; + return result; + } + } + } + throw Error(str + ' is not a valid color string'); +}; + + +/** + * Determines if the given string can be parsed as a color. + * {@see goog.color.parse}. + * @param {string} str Potential color string. + * @return {boolean} True if str is in a format that can be parsed to a color. + */ +goog.color.isValidColor = function(str) { + var maybeHex = goog.color.prependHashIfNecessaryHelper(str); + return !!(goog.color.isValidHexColor_(maybeHex) || + goog.color.isValidRgbColor_(str).length || + goog.color.names && goog.color.names[str.toLowerCase()]); +}; + + +/** + * Parses red, green, blue components out of a valid rgb color string. + * Throws Error if the color string is invalid. + * @param {string} str RGB representation of a color. + * {@see goog.color.isValidRgbColor_}. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.parseRgb = function(str) { + var rgb = goog.color.isValidRgbColor_(str); + if (!rgb.length) { + throw Error(str + ' is not a valid RGB color'); + } + return rgb; +}; + + +/** + * Converts a hex representation of a color to RGB. + * @param {string} hexColor Color to convert. + * @return {string} string of the form 'rgb(R,G,B)' which can be used in + * styles. + */ +goog.color.hexToRgbStyle = function(hexColor) { + return goog.color.rgbStyle_(goog.color.hexToRgb(hexColor)); +}; + + +/** + * Regular expression for extracting the digits in a hex color triplet. + * @type {RegExp} + * @private + */ +goog.color.hexTripletRe_ = /#(.)(.)(.)/; + + +/** + * Normalize an hex representation of a color + * @param {string} hexColor an hex color string. + * @return {string} hex color in the format '#rrggbb' with all lowercase + * literals. + */ +goog.color.normalizeHex = function(hexColor) { + if (!goog.color.isValidHexColor_(hexColor)) { + throw Error("'" + hexColor + "' is not a valid hex color"); + } + if (hexColor.length == 4) { // of the form #RGB + hexColor = hexColor.replace(goog.color.hexTripletRe_, '#$1$1$2$2$3$3'); + } + return hexColor.toLowerCase(); +}; + + +/** + * Converts a hex representation of a color to RGB. + * @param {string} hexColor Color to convert. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.hexToRgb = function(hexColor) { + hexColor = goog.color.normalizeHex(hexColor); + var r = parseInt(hexColor.substr(1, 2), 16); + var g = parseInt(hexColor.substr(3, 2), 16); + var b = parseInt(hexColor.substr(5, 2), 16); + + return [r, g, b]; +}; + + +/** + * Converts a color from RGB to hex representation. + * @param {number} r Amount of red, int between 0 and 255. + * @param {number} g Amount of green, int between 0 and 255. + * @param {number} b Amount of blue, int between 0 and 255. + * @return {string} hex representation of the color. + */ +goog.color.rgbToHex = function(r, g, b) { + r = Number(r); + g = Number(g); + b = Number(b); + if (isNaN(r) || r < 0 || r > 255 || + isNaN(g) || g < 0 || g > 255 || + isNaN(b) || b < 0 || b > 255) { + throw Error('"(' + r + ',' + g + ',' + b + '") is not a valid RGB color'); + } + var hexR = goog.color.prependZeroIfNecessaryHelper(r.toString(16)); + var hexG = goog.color.prependZeroIfNecessaryHelper(g.toString(16)); + var hexB = goog.color.prependZeroIfNecessaryHelper(b.toString(16)); + return '#' + hexR + hexG + hexB; +}; + + +/** + * Converts a color from RGB to hex representation. + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @return {string} hex representation of the color. + */ +goog.color.rgbArrayToHex = function(rgb) { + return goog.color.rgbToHex(rgb[0], rgb[1], rgb[2]); +}; + + +/** + * Converts a color from RGB color space to HSL color space. + * Modified from {@link http://en.wikipedia.org/wiki/HLS_color_space}. + * @param {number} r Value of red, in [0, 255]. + * @param {number} g Value of green, in [0, 255]. + * @param {number} b Value of blue, in [0, 255]. + * @return {!goog.color.Hsl} hsl representation of the color. + */ +goog.color.rgbToHsl = function(r, g, b) { + // First must normalize r, g, b to be between 0 and 1. + var normR = r / 255; + var normG = g / 255; + var normB = b / 255; + var max = Math.max(normR, normG, normB); + var min = Math.min(normR, normG, normB); + var h = 0; + var s = 0; + + // Luminosity is the average of the max and min rgb color intensities. + var l = 0.5 * (max + min); + + // The hue and saturation are dependent on which color intensity is the max. + // If max and min are equal, the color is gray and h and s should be 0. + if (max != min) { + if (max == normR) { + h = 60 * (normG - normB) / (max - min); + } else if (max == normG) { + h = 60 * (normB - normR) / (max - min) + 120; + } else if (max == normB) { + h = 60 * (normR - normG) / (max - min) + 240; + } + + if (0 < l && l <= 0.5) { + s = (max - min) / (2 * l); + } else { + s = (max - min) / (2 - 2 * l); + } + } + + // Make sure the hue falls between 0 and 360. + return [Math.round(h + 360) % 360, s, l]; +}; + + +/** + * Converts a color from RGB color space to HSL color space. + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @return {!goog.color.Hsl} hsl representation of the color. + */ +goog.color.rgbArrayToHsl = function(rgb) { + return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]); +}; + + +/** + * Helper for hslToRgb. + * @param {number} v1 Helper variable 1. + * @param {number} v2 Helper variable 2. + * @param {number} vH Helper variable 3. + * @return {number} Appropriate RGB value, given the above. + * @private + */ +goog.color.hueToRgb_ = function(v1, v2, vH) { + if (vH < 0) { + vH += 1; + } else if (vH > 1) { + vH -= 1; + } + if ((6 * vH) < 1) { + return (v1 + (v2 - v1) * 6 * vH); + } else if (2 * vH < 1) { + return v2; + } else if (3 * vH < 2) { + return (v1 + (v2 - v1) * ((2 / 3) - vH) * 6); + } + return v1; +}; + + +/** + * Converts a color from HSL color space to RGB color space. + * Modified from {@link http://www.easyrgb.com/math.html} + * @param {number} h Hue, in [0, 360]. + * @param {number} s Saturation, in [0, 1]. + * @param {number} l Luminosity, in [0, 1]. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.hslToRgb = function(h, s, l) { + var r = 0; + var g = 0; + var b = 0; + var normH = h / 360; // normalize h to fall in [0, 1] + + if (s == 0) { + r = g = b = l * 255; + } else { + var temp1 = 0; + var temp2 = 0; + if (l < 0.5) { + temp2 = l * (1 + s); + } else { + temp2 = l + s - (s * l); + } + temp1 = 2 * l - temp2; + r = 255 * goog.color.hueToRgb_(temp1, temp2, normH + (1 / 3)); + g = 255 * goog.color.hueToRgb_(temp1, temp2, normH); + b = 255 * goog.color.hueToRgb_(temp1, temp2, normH - (1 / 3)); + } + + return [Math.round(r), Math.round(g), Math.round(b)]; +}; + + +/** + * Converts a color from HSL color space to RGB color space. + * @param {goog.color.Hsl} hsl hsl representation of the color. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.hslArrayToRgb = function(hsl) { + return goog.color.hslToRgb(hsl[0], hsl[1], hsl[2]); +}; + + +/** + * Helper for isValidHexColor_. + * @type {RegExp} + * @private + */ +goog.color.validHexColorRe_ = /^#(?:[0-9a-f]{3}){1,2}$/i; + + +/** + * Checks if a string is a valid hex color. We expect strings of the format + * #RRGGBB (ex: #1b3d5f) or #RGB (ex: #3CA == #33CCAA). + * @param {string} str String to check. + * @return {boolean} Whether the string is a valid hex color. + * @private + */ +goog.color.isValidHexColor_ = function(str) { + return goog.color.validHexColorRe_.test(str); +}; + + +/** + * Helper for isNormalizedHexColor_. + * @type {RegExp} + * @private + */ +goog.color.normalizedHexColorRe_ = /^#[0-9a-f]{6}$/; + + +/** + * Checks if a string is a normalized hex color. + * We expect strings of the format #RRGGBB (ex: #1b3d5f) + * using only lowercase letters. + * @param {string} str String to check. + * @return {boolean} Whether the string is a normalized hex color. + * @private + */ +goog.color.isNormalizedHexColor_ = function(str) { + return goog.color.normalizedHexColorRe_.test(str); +}; + + +/** + * Regular expression for matching and capturing RGB style strings. Helper for + * isValidRgbColor_. + * @type {RegExp} + * @private + */ +goog.color.rgbColorRe_ = + /^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i; + + +/** + * Checks if a string is a valid rgb color. We expect strings of the format + * '(r, g, b)', or 'rgb(r, g, b)', where each color component is an int in + * [0, 255]. + * @param {string} str String to check. + * @return {!goog.color.Rgb} the rgb representation of the color if it is + * a valid color, or the empty array otherwise. + * @private + */ +goog.color.isValidRgbColor_ = function(str) { + // Each component is separate (rather than using a repeater) so we can + // capture the match. Also, we explicitly set each component to be either 0, + // or start with a non-zero, to prevent octal numbers from slipping through. + var regExpResultArray = str.match(goog.color.rgbColorRe_); + if (regExpResultArray) { + var r = Number(regExpResultArray[1]); + var g = Number(regExpResultArray[2]); + var b = Number(regExpResultArray[3]); + if (r >= 0 && r <= 255 && + g >= 0 && g <= 255 && + b >= 0 && b <= 255) { + return [r, g, b]; + } + } + return []; +}; + + +/** + * Takes a hex value and prepends a zero if it's a single digit. + * Small helper method for use by goog.color and friends. + * @param {string} hex Hex value to prepend if single digit. + * @return {string} hex value prepended with zero if it was single digit, + * otherwise the same value that was passed in. + */ +goog.color.prependZeroIfNecessaryHelper = function(hex) { + return hex.length == 1 ? '0' + hex : hex; +}; + + +/** + * Takes a string a prepends a '#' sign if one doesn't exist. + * Small helper method for use by goog.color and friends. + * @param {string} str String to check. + * @return {string} The value passed in, prepended with a '#' if it didn't + * already have one. + */ +goog.color.prependHashIfNecessaryHelper = function(str) { + return str.charAt(0) == '#' ? str : '#' + str; +}; + + +/** + * Takes an array of [r, g, b] and converts it into a string appropriate for + * CSS styles. + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @return {string} string of the form 'rgb(r,g,b)'. + * @private + */ +goog.color.rgbStyle_ = function(rgb) { + return 'rgb(' + rgb.join(',') + ')'; +}; + + +/** + * Converts an HSV triplet to an RGB array. V is brightness because b is + * reserved for blue in RGB. + * @param {number} h Hue value in [0, 360]. + * @param {number} s Saturation value in [0, 1]. + * @param {number} brightness brightness in [0, 255]. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.hsvToRgb = function(h, s, brightness) { + var red = 0; + var green = 0; + var blue = 0; + if (s == 0) { + red = brightness; + green = brightness; + blue = brightness; + } else { + var sextant = Math.floor(h / 60); + var remainder = (h / 60) - sextant; + var val1 = brightness * (1 - s); + var val2 = brightness * (1 - (s * remainder)); + var val3 = brightness * (1 - (s * (1 - remainder))); + switch (sextant) { + case 1: + red = val2; + green = brightness; + blue = val1; + break; + case 2: + red = val1; + green = brightness; + blue = val3; + break; + case 3: + red = val1; + green = val2; + blue = brightness; + break; + case 4: + red = val3; + green = val1; + blue = brightness; + break; + case 5: + red = brightness; + green = val1; + blue = val2; + break; + case 6: + case 0: + red = brightness; + green = val3; + blue = val1; + break; + } + } + + return [Math.floor(red), Math.floor(green), Math.floor(blue)]; +}; + + +/** + * Converts from RGB values to an array of HSV values. + * @param {number} red Red value in [0, 255]. + * @param {number} green Green value in [0, 255]. + * @param {number} blue Blue value in [0, 255]. + * @return {!goog.color.Hsv} hsv representation of the color. + */ +goog.color.rgbToHsv = function(red, green, blue) { + + var max = Math.max(Math.max(red, green), blue); + var min = Math.min(Math.min(red, green), blue); + var hue; + var saturation; + var value = max; + if (min == max) { + hue = 0; + saturation = 0; + } else { + var delta = (max - min); + saturation = delta / max; + + if (red == max) { + hue = (green - blue) / delta; + } else if (green == max) { + hue = 2 + ((blue - red) / delta); + } else { + hue = 4 + ((red - green) / delta); + } + hue *= 60; + if (hue < 0) { + hue += 360; + } + if (hue > 360) { + hue -= 360; + } + } + + return [hue, saturation, value]; +}; + + +/** + * Converts from an array of RGB values to an array of HSV values. + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @return {!goog.color.Hsv} hsv representation of the color. + */ +goog.color.rgbArrayToHsv = function(rgb) { + return goog.color.rgbToHsv(rgb[0], rgb[1], rgb[2]); +}; + + +/** + * Converts an HSV triplet to an RGB array. + * @param {goog.color.Hsv} hsv hsv representation of the color. + * @return {!goog.color.Rgb} rgb representation of the color. + */ +goog.color.hsvArrayToRgb = function(hsv) { + return goog.color.hsvToRgb(hsv[0], hsv[1], hsv[2]); +}; + + +/** + * Converts a hex representation of a color to HSL. + * @param {string} hex Color to convert. + * @return {!goog.color.Hsv} hsv representation of the color. + */ +goog.color.hexToHsl = function(hex) { + var rgb = goog.color.hexToRgb(hex); + return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]); +}; + + +/** + * Converts from h,s,l values to a hex string + * @param {number} h Hue, in [0, 360]. + * @param {number} s Saturation, in [0, 1]. + * @param {number} l Luminosity, in [0, 1]. + * @return {string} hex representation of the color. + */ +goog.color.hslToHex = function(h, s, l) { + return goog.color.rgbArrayToHex(goog.color.hslToRgb(h, s, l)); +}; + + +/** + * Converts from an hsl array to a hex string + * @param {goog.color.Hsl} hsl hsl representation of the color. + * @return {string} hex representation of the color. + */ +goog.color.hslArrayToHex = function(hsl) { + return goog.color.rgbArrayToHex(goog.color.hslToRgb(hsl[0], hsl[1], hsl[2])); +}; + + +/** + * Converts a hex representation of a color to HSV + * @param {string} hex Color to convert. + * @return {!goog.color.Hsv} hsv representation of the color. + */ +goog.color.hexToHsv = function(hex) { + return goog.color.rgbArrayToHsv(goog.color.hexToRgb(hex)); +}; + + +/** + * Converts from h,s,v values to a hex string + * @param {number} h Hue, in [0, 360]. + * @param {number} s Saturation, in [0, 1]. + * @param {number} v Value, in [0, 255]. + * @return {string} hex representation of the color. + */ +goog.color.hsvToHex = function(h, s, v) { + return goog.color.rgbArrayToHex(goog.color.hsvToRgb(h, s, v)); +}; + + +/** + * Converts from an HSV array to a hex string + * @param {goog.color.Hsv} hsv hsv representation of the color. + * @return {string} hex representation of the color. + */ +goog.color.hsvArrayToHex = function(hsv) { + return goog.color.hsvToHex(hsv[0], hsv[1], hsv[2]); +}; + + +/** + * Calculates the Euclidean distance between two color vectors on an HSL sphere. + * A demo of the sphere can be found at: + * http://en.wikipedia.org/wiki/HSL_color_space + * In short, a vector for color (H, S, L) in this system can be expressed as + * (S*L'*cos(2*PI*H), S*L'*sin(2*PI*H), L), where L' = abs(L - 0.5), and we + * simply calculate the 1-2 distance using these coordinates + * @param {goog.color.Hsl} hsl1 First color in hsl representation. + * @param {goog.color.Hsl} hsl2 Second color in hsl representation. + * @return {number} Distance between the two colors, in the range [0, 1]. + */ +goog.color.hslDistance = function(hsl1, hsl2) { + var sl1, sl2; + if (hsl1[2] <= 0.5) { + sl1 = hsl1[1] * hsl1[2]; + } else { + sl1 = hsl1[1] * (1.0 - hsl1[2]); + } + + if (hsl2[2] <= 0.5) { + sl2 = hsl2[1] * hsl2[2]; + } else { + sl2 = hsl2[1] * (1.0 - hsl2[2]); + } + + var h1 = hsl1[0] / 360.0; + var h2 = hsl2[0] / 360.0; + var dh = (h1 - h2) * 2.0 * Math.PI; + return (hsl1[2] - hsl2[2]) * (hsl1[2] - hsl2[2]) + + sl1 * sl1 + sl2 * sl2 - 2 * sl1 * sl2 * Math.cos(dh); +}; + + +/** + * Blend two colors together, using the specified factor to indicate the weight + * given to the first color + * @param {goog.color.Rgb} rgb1 First color represented in rgb. + * @param {goog.color.Rgb} rgb2 Second color represented in rgb. + * @param {number} factor The weight to be given to rgb1 over rgb2. Values + * should be in the range [0, 1]. If less than 0, factor will be set to 0. + * If greater than 1, factor will be set to 1. + * @return {!goog.color.Rgb} Combined color represented in rgb. + */ +goog.color.blend = function(rgb1, rgb2, factor) { + factor = goog.math.clamp(factor, 0, 1); + + return [ + Math.round(factor * rgb1[0] + (1.0 - factor) * rgb2[0]), + Math.round(factor * rgb1[1] + (1.0 - factor) * rgb2[1]), + Math.round(factor * rgb1[2] + (1.0 - factor) * rgb2[2]) + ]; +}; + + +/** + * Adds black to the specified color, darkening it + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @param {number} factor Number in the range [0, 1]. 0 will do nothing, while + * 1 will return black. If less than 0, factor will be set to 0. If greater + * than 1, factor will be set to 1. + * @return {!goog.color.Rgb} Combined rgb color. + */ +goog.color.darken = function(rgb, factor) { + var black = [0, 0, 0]; + return goog.color.blend(black, rgb, factor); +}; + + +/** + * Adds white to the specified color, lightening it + * @param {goog.color.Rgb} rgb rgb representation of the color. + * @param {number} factor Number in the range [0, 1]. 0 will do nothing, while + * 1 will return white. If less than 0, factor will be set to 0. If greater + * than 1, factor will be set to 1. + * @return {!goog.color.Rgb} Combined rgb color. + */ +goog.color.lighten = function(rgb, factor) { + var white = [255, 255, 255]; + return goog.color.blend(white, rgb, factor); +}; + + +/** + * Find the "best" (highest-contrast) of the suggested colors for the prime + * color. Uses W3C formula for judging readability and visual accessibility: + * http://www.w3.org/TR/AERT#color-contrast + * @param {goog.color.Rgb} prime Color represented as a rgb array. + * @param {Array<goog.color.Rgb>} suggestions Array of colors, + * each representing a rgb array. + * @return {!goog.color.Rgb} Highest-contrast color represented by an array.. + */ +goog.color.highContrast = function(prime, suggestions) { + var suggestionsWithDiff = []; + for (var i = 0; i < suggestions.length; i++) { + suggestionsWithDiff.push({ + color: suggestions[i], + diff: goog.color.yiqBrightnessDiff_(suggestions[i], prime) + + goog.color.colorDiff_(suggestions[i], prime) + }); + } + suggestionsWithDiff.sort(function(a, b) { + return b.diff - a.diff; + }); + return suggestionsWithDiff[0].color; +}; + + +/** + * Calculate brightness of a color according to YIQ formula (brightness is Y). + * More info on YIQ here: http://en.wikipedia.org/wiki/YIQ. Helper method for + * goog.color.highContrast() + * @param {goog.color.Rgb} rgb Color represented by a rgb array. + * @return {number} brightness (Y). + * @private + */ +goog.color.yiqBrightness_ = function(rgb) { + return Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000); +}; + + +/** + * Calculate difference in brightness of two colors. Helper method for + * goog.color.highContrast() + * @param {goog.color.Rgb} rgb1 Color represented by a rgb array. + * @param {goog.color.Rgb} rgb2 Color represented by a rgb array. + * @return {number} Brightness difference. + * @private + */ +goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) { + return Math.abs(goog.color.yiqBrightness_(rgb1) - + goog.color.yiqBrightness_(rgb2)); +}; + + +/** + * Calculate color difference between two colors. Helper method for + * goog.color.highContrast() + * @param {goog.color.Rgb} rgb1 Color represented by a rgb array. + * @param {goog.color.Rgb} rgb2 Color represented by a rgb array. + * @return {number} Color difference. + * @private + */ +goog.color.colorDiff_ = function(rgb1, rgb2) { + return Math.abs(rgb1[0] - rgb2[0]) + Math.abs(rgb1[1] - rgb2[1]) + + Math.abs(rgb1[2] - rgb2[2]); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/color/names.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/color/names.js b/externs/GCL/externs/goog/color/names.js new file mode 100644 index 0000000..c4b3ac8 --- /dev/null +++ b/externs/GCL/externs/goog/color/names.js @@ -0,0 +1,176 @@ +// Copyright 2006 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 Names of standard colors with their associated hex values. + */ + +goog.provide('goog.color.names'); + + +/** + * A map that contains a lot of colors that are recognised by various browsers. + * This list is way larger than the minimal one dictated by W3C. + * The keys of this map are the lowercase "readable" names of the colors, while + * the values are the "hex" values. + */ +goog.color.names = { + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgreen': '#006400', + 'darkgrey': '#a9a9a9', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'grey': '#808080', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightgrey': '#d3d3d3', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370db', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#db7093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32' +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/aes.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/crypt/aes.js b/externs/GCL/externs/goog/crypt/aes.js new file mode 100644 index 0000000..d5a1674 --- /dev/null +++ b/externs/GCL/externs/goog/crypt/aes.js @@ -0,0 +1,1029 @@ +// 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 AES in JavaScript. + * @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard + * + * @author [email protected] (Nathan Naze) - port to Closure + */ + +goog.provide('goog.crypt.Aes'); + +goog.require('goog.asserts'); +goog.require('goog.crypt.BlockCipher'); + + + +/** + * Implementation of AES in JavaScript. + * See http://en.wikipedia.org/wiki/Advanced_Encryption_Standard + * + * WARNING: This is ECB mode only. If you are encrypting something + * longer than 16 bytes, or encrypting more than one value with the same key + * (so basically, always) you need to use this with a block cipher mode of + * operation. See goog.crypt.Cbc. + * + * See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation for more + * information. + * + * @constructor + * @implements {goog.crypt.BlockCipher} + * @param {!Array<number>} key The key as an array of integers in {0, 255}. + * The key must have lengths of 16, 24, or 32 integers for 128-, + * 192-, or 256-bit encryption, respectively. + * @final + * @struct + */ +goog.crypt.Aes = function(key) { + goog.crypt.Aes.assertKeyArray_(key); + + /** + * The AES key. + * @type {!Array<number>} + * @private + */ + this.key_ = key; + + /** + * Key length, in words. + * @type {number} + * @private + */ + this.keyLength_ = this.key_.length / 4; + + /** + * Number of rounds. Based on key length per AES spec. + * @type {number} + * @private + */ + this.numberOfRounds_ = this.keyLength_ + 6; + + /** + * 4x4 byte array containing the current state. + * @type {!Array<!Array<number>>} + * @private + */ + this.state_ = [[], [], [], []]; + + /** + * Scratch temporary array for calculation. + * @type {!Array<!Array<number>>} + * @private + */ + this.temp_ = [[], [], [], []]; + + /** + * The key schedule. + * @type {!Array<!Array<number>>} + * @private + */ + this.keySchedule_; + + this.keyExpansion_(); +}; + + +/** + * @define {boolean} Whether to call test method stubs. This can be enabled + * for unit testing. + */ +goog.define('goog.crypt.Aes.ENABLE_TEST_MODE', false); + + +/** + * @override + */ +goog.crypt.Aes.prototype.encrypt = function(input) { + + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testKeySchedule_(0, this.keySchedule_, 0); + } + + this.copyInput_(input); + this.addRoundKey_(0); + + for (var round = 1; round < this.numberOfRounds_; ++round) { + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testKeySchedule_(round, this.keySchedule_, round); + this.testStartRound_(round, this.state_); + } + + this.subBytes_(goog.crypt.Aes.SBOX_); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterSubBytes_(round, this.state_); + } + + this.shiftRows_(); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterShiftRows_(round, this.state_); + } + + this.mixColumns_(); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterMixColumns_(round, this.state_); + } + + this.addRoundKey_(round); + } + + this.subBytes_(goog.crypt.Aes.SBOX_); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterSubBytes_(round, this.state_); + } + + this.shiftRows_(); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterShiftRows_(round, this.state_); + } + + this.addRoundKey_(this.numberOfRounds_); + + return this.generateOutput_(); +}; + + +/** + * @override + */ +goog.crypt.Aes.prototype.decrypt = function(input) { + + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testKeySchedule_(0, this.keySchedule_, this.numberOfRounds_); + } + + this.copyInput_(input); + this.addRoundKey_(this.numberOfRounds_); + + for (var round = 1; round < this.numberOfRounds_; ++round) { + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testKeySchedule_(round, this.keySchedule_, + this.numberOfRounds_ - round); + this.testStartRound_(round, this.state_); + } + + this.invShiftRows_(); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterShiftRows_(round, this.state_); + } + + this.subBytes_(goog.crypt.Aes.INV_SBOX_); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterSubBytes_(round, this.state_); + } + + this.addRoundKey_(this.numberOfRounds_ - round); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterAddRoundKey_(round, this.state_); + } + + this.invMixColumns_(); + } + + this.invShiftRows_(); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterShiftRows_(round, this.state_); + } + + this.subBytes_(goog.crypt.Aes.INV_SBOX_); + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testAfterSubBytes_(this.numberOfRounds_, this.state_); + } + + if (goog.crypt.Aes.ENABLE_TEST_MODE) { + this.testKeySchedule_(this.numberOfRounds_, this.keySchedule_, 0); + } + + this.addRoundKey_(0); + + return this.generateOutput_(); +}; + + +/** + * Block size, in words. Fixed at 4 per AES spec. + * @type {number} + * @private + */ +goog.crypt.Aes.BLOCK_SIZE_ = 4; + + +/** + * Asserts that the key's array of integers is in the correct format. + * @param {!Array<number>} arr AES key as array of integers. + * @private + */ +goog.crypt.Aes.assertKeyArray_ = function(arr) { + if (goog.asserts.ENABLE_ASSERTS) { + goog.asserts.assert(arr.length == 16 || arr.length == 24 || + arr.length == 32, + 'Key must have length 16, 24, or 32.'); + for (var i = 0; i < arr.length; i++) { + goog.asserts.assertNumber(arr[i]); + goog.asserts.assert(arr[i] >= 0 && arr[i] <= 255); + } + } +}; + + +/** + * Tests can populate this with a callback, and that callback will get called + * at the start of each round *in both functions encrypt() and decrypt()*. + * @param {number} roundNum Round number. + * @param {!Array<Array<number>>} Current state. + * @private + */ +goog.crypt.Aes.prototype.testStartRound_ = goog.nullFunction; + + +/** + * Tests can populate this with a callback, and that callback will get called + * each round right after the SubBytes step gets executed *in both functions + * encrypt() and decrypt()*. + * @param {number} roundNum Round number. + * @param {!Array<Array<number>>} Current state. + * @private + */ +goog.crypt.Aes.prototype.testAfterSubBytes_ = goog.nullFunction; + + +/** + * Tests can populate this with a callback, and that callback will get called + * each round right after the ShiftRows step gets executed *in both functions + * encrypt() and decrypt()*. + * @param {number} roundNum Round number. + * @param {!Array<Array<number>>} Current state. + * @private + */ +goog.crypt.Aes.prototype.testAfterShiftRows_ = goog.nullFunction; + + +/** + * Tests can populate this with a callback, and that callback will get called + * each round right after the MixColumns step gets executed *but only in the + * decrypt() function*. + * @param {number} roundNum Round number. + * @param {!Array<Array<number>>} Current state. + * @private + */ +goog.crypt.Aes.prototype.testAfterMixColumns_ = goog.nullFunction; + + +/** + * Tests can populate this with a callback, and that callback will get called + * each round right after the AddRoundKey step gets executed encrypt(). + * @param {number} roundNum Round number. + * @param {!Array<Array<number>>} Current state. + * @private + */ +goog.crypt.Aes.prototype.testAfterAddRoundKey_ = goog.nullFunction; + + +/** + * Tests can populate this with a callback, and that callback will get called + * before each round on the round key. *Gets called in both the encrypt() and + * decrypt() functions.* + * @param {number} roundNum Round number. + * @param {Array<!Array<number>>} Computed key schedule. + * @param {number} index The index into the key schedule to test. This is not + * necessarily roundNum because the key schedule is used in reverse + * in the case of decryption. + * @private + */ +goog.crypt.Aes.prototype.testKeySchedule_ = goog.nullFunction; + + +/** + * Helper to copy input into the AES state matrix. + * @param {!Array<number>} input Byte array to copy into the state matrix. + * @private + */ +goog.crypt.Aes.prototype.copyInput_ = function(input) { + var v, p; + + goog.asserts.assert(input.length == goog.crypt.Aes.BLOCK_SIZE_ * 4, + 'Expecting input of 4 times block size.'); + + for (var r = 0; r < goog.crypt.Aes.BLOCK_SIZE_; r++) { + for (var c = 0; c < 4; c++) { + p = c * 4 + r; + v = input[p]; + + goog.asserts.assert( + v <= 255 && v >= 0, + 'Invalid input. Value %s at position %s is not a byte.', v, p); + + this.state_[r][c] = v; + } + } +}; + + +/** + * Helper to copy the state matrix into an output array. + * @return {!Array<number>} Output byte array. + * @private + */ +goog.crypt.Aes.prototype.generateOutput_ = function() { + var output = []; + for (var r = 0; r < goog.crypt.Aes.BLOCK_SIZE_; r++) { + for (var c = 0; c < 4; c++) { + output[c * 4 + r] = this.state_[r][c]; + } + } + return output; +}; + + +/** + * AES's AddRoundKey procedure. Add the current round key to the state. + * @param {number} round The current round. + * @private + */ +goog.crypt.Aes.prototype.addRoundKey_ = function(round) { + for (var r = 0; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.state_[r][c] ^= this.keySchedule_[round * 4 + c][r]; + } + } +}; + + +/** + * AES's SubBytes procedure. Substitute bytes from the precomputed SBox lookup + * into the state. + * @param {!Array<number>} box The SBox or invSBox. + * @private + */ +goog.crypt.Aes.prototype.subBytes_ = function(box) { + for (var r = 0; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.state_[r][c] = box[this.state_[r][c]]; + } + } +}; + + +/** + * AES's ShiftRows procedure. Shift the values in each row to the right. Each + * row is shifted one more slot than the one above it. + * @private + */ +goog.crypt.Aes.prototype.shiftRows_ = function() { + for (var r = 1; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.temp_[r][c] = this.state_[r][c]; + } + } + + for (var r = 1; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.state_[r][c] = this.temp_[r][(c + r) % + goog.crypt.Aes.BLOCK_SIZE_]; + } + } +}; + + +/** + * AES's InvShiftRows procedure. Shift the values in each row to the right. + * @private + */ +goog.crypt.Aes.prototype.invShiftRows_ = function() { + for (var r = 1; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_] = + this.state_[r][c]; + } + } + + for (var r = 1; r < 4; r++) { + for (var c = 0; c < 4; c++) { + this.state_[r][c] = this.temp_[r][c]; + } + } +}; + + +/** + * AES's MixColumns procedure. Mix the columns of the state using magic. + * @private + */ +goog.crypt.Aes.prototype.mixColumns_ = function() { + var s = this.state_; + var t = this.temp_[0]; + + for (var c = 0; c < 4; c++) { + t[0] = s[0][c]; + t[1] = s[1][c]; + t[2] = s[2][c]; + t[3] = s[3][c]; + + s[0][c] = (goog.crypt.Aes.MULT_2_[t[0]] ^ + goog.crypt.Aes.MULT_3_[t[1]] ^ t[2] ^ t[3]); + s[1][c] = (t[0] ^ goog.crypt.Aes.MULT_2_[t[1]] ^ + goog.crypt.Aes.MULT_3_[t[2]] ^ t[3]); + s[2][c] = (t[0] ^ t[1] ^ goog.crypt.Aes.MULT_2_[t[2]] ^ + goog.crypt.Aes.MULT_3_[t[3]]); + s[3][c] = (goog.crypt.Aes.MULT_3_[t[0]] ^ t[1] ^ t[2] ^ + goog.crypt.Aes.MULT_2_[t[3]]); + } +}; + + +/** + * AES's InvMixColumns procedure. + * @private + */ +goog.crypt.Aes.prototype.invMixColumns_ = function() { + var s = this.state_; + var t = this.temp_[0]; + + for (var c = 0; c < 4; c++) { + t[0] = s[0][c]; + t[1] = s[1][c]; + t[2] = s[2][c]; + t[3] = s[3][c]; + + s[0][c] = ( + goog.crypt.Aes.MULT_E_[t[0]] ^ goog.crypt.Aes.MULT_B_[t[1]] ^ + goog.crypt.Aes.MULT_D_[t[2]] ^ goog.crypt.Aes.MULT_9_[t[3]]); + + s[1][c] = ( + goog.crypt.Aes.MULT_9_[t[0]] ^ goog.crypt.Aes.MULT_E_[t[1]] ^ + goog.crypt.Aes.MULT_B_[t[2]] ^ goog.crypt.Aes.MULT_D_[t[3]]); + + s[2][c] = ( + goog.crypt.Aes.MULT_D_[t[0]] ^ goog.crypt.Aes.MULT_9_[t[1]] ^ + goog.crypt.Aes.MULT_E_[t[2]] ^ goog.crypt.Aes.MULT_B_[t[3]]); + + s[3][c] = ( + goog.crypt.Aes.MULT_B_[t[0]] ^ goog.crypt.Aes.MULT_D_[t[1]] ^ + goog.crypt.Aes.MULT_9_[t[2]] ^ goog.crypt.Aes.MULT_E_[t[3]]); + } +}; + + +/** + * AES's KeyExpansion procedure. Create the key schedule from the initial key. + * @private + */ +goog.crypt.Aes.prototype.keyExpansion_ = function() { + this.keySchedule_ = new Array(goog.crypt.Aes.BLOCK_SIZE_ * ( + this.numberOfRounds_ + 1)); + + for (var rowNum = 0; rowNum < this.keyLength_; rowNum++) { + this.keySchedule_[rowNum] = [ + this.key_[4 * rowNum], + this.key_[4 * rowNum + 1], + this.key_[4 * rowNum + 2], + this.key_[4 * rowNum + 3] + ]; + } + + var temp = new Array(4); + + for (var rowNum = this.keyLength_; + rowNum < (goog.crypt.Aes.BLOCK_SIZE_ * (this.numberOfRounds_ + 1)); + rowNum++) { + temp[0] = this.keySchedule_[rowNum - 1][0]; + temp[1] = this.keySchedule_[rowNum - 1][1]; + temp[2] = this.keySchedule_[rowNum - 1][2]; + temp[3] = this.keySchedule_[rowNum - 1][3]; + + if (rowNum % this.keyLength_ == 0) { + this.rotWord_(temp); + this.subWord_(temp); + + temp[0] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLength_][0]; + temp[1] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLength_][1]; + temp[2] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLength_][2]; + temp[3] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLength_][3]; + } else if (this.keyLength_ > 6 && rowNum % this.keyLength_ == 4) { + this.subWord_(temp); + } + + this.keySchedule_[rowNum] = new Array(4); + this.keySchedule_[rowNum][0] = + this.keySchedule_[rowNum - this.keyLength_][0] ^ temp[0]; + this.keySchedule_[rowNum][1] = + this.keySchedule_[rowNum - this.keyLength_][1] ^ temp[1]; + this.keySchedule_[rowNum][2] = + this.keySchedule_[rowNum - this.keyLength_][2] ^ temp[2]; + this.keySchedule_[rowNum][3] = + this.keySchedule_[rowNum - this.keyLength_][3] ^ temp[3]; + } +}; + + +/** + * AES's SubWord procedure. + * @param {!Array<number>} w Bytes to find the SBox substitution for. + * @return {!Array<number>} The substituted bytes. + * @private + */ +goog.crypt.Aes.prototype.subWord_ = function(w) { + w[0] = goog.crypt.Aes.SBOX_[w[0]]; + w[1] = goog.crypt.Aes.SBOX_[w[1]]; + w[2] = goog.crypt.Aes.SBOX_[w[2]]; + w[3] = goog.crypt.Aes.SBOX_[w[3]]; + + return w; +}; + + +/** + * AES's RotWord procedure. + * @param {!Array<number>} w Array of bytes to rotate. + * @return {!Array<number>} The rotated bytes. + * @private + */ +goog.crypt.Aes.prototype.rotWord_ = function(w) { + var temp = w[0]; + + w[0] = w[1]; + w[1] = w[2]; + w[2] = w[3]; + w[3] = temp; + + return w; +}; + + +/** + * Precomputed SBox lookup. + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.SBOX_ = [ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, + 0xd7, 0xab, 0x76, + + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, + 0xa4, 0x72, 0xc0, + + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, + 0xd8, 0x31, 0x15, + + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, + 0x27, 0xb2, 0x75, + + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, + 0xe3, 0x2f, 0x84, + + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, + 0x4c, 0x58, 0xcf, + + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, + 0x3c, 0x9f, 0xa8, + + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, + 0xff, 0xf3, 0xd2, + + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, + 0x5d, 0x19, 0x73, + + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, + 0x5e, 0x0b, 0xdb, + + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, + 0x95, 0xe4, 0x79, + + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, + 0x7a, 0xae, 0x08, + + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, + 0xbd, 0x8b, 0x8a, + + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, + 0xc1, 0x1d, 0x9e, + + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, + 0x55, 0x28, 0xdf, + + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, + 0x54, 0xbb, 0x16 +]; + + +/** + * Precomputed InvSBox lookup. + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.INV_SBOX_ = [ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, + 0xf3, 0xd7, 0xfb, + + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, + 0xde, 0xe9, 0xcb, + + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, + 0xfa, 0xc3, 0x4e, + + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, + 0x8b, 0xd1, 0x25, + + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, + 0x65, 0xb6, 0x92, + + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, + 0x8d, 0x9d, 0x84, + + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, + 0xb3, 0x45, 0x06, + + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, + 0x13, 0x8a, 0x6b, + + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, + 0xb4, 0xe6, 0x73, + + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, + 0x75, 0xdf, 0x6e, + + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, + 0x18, 0xbe, 0x1b, + + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, + 0xcd, 0x5a, 0xf4, + + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, + 0x80, 0xec, 0x5f, + + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, + 0xc9, 0x9c, 0xef, + + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, + 0x53, 0x99, 0x61, + + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, + 0x21, 0x0c, 0x7d +]; + + +/** + * Precomputed RCon lookup. + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.RCON_ = [ + [0x00, 0x00, 0x00, 0x00], + [0x01, 0x00, 0x00, 0x00], + [0x02, 0x00, 0x00, 0x00], + [0x04, 0x00, 0x00, 0x00], + [0x08, 0x00, 0x00, 0x00], + [0x10, 0x00, 0x00, 0x00], + [0x20, 0x00, 0x00, 0x00], + [0x40, 0x00, 0x00, 0x00], + [0x80, 0x00, 0x00, 0x00], + [0x1b, 0x00, 0x00, 0x00], + [0x36, 0x00, 0x00, 0x00] +]; + + +/** + * Precomputed lookup of multiplication by 2 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_2_ = [ + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, + 0x18, 0x1A, 0x1C, 0x1E, + + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, + 0x38, 0x3A, 0x3C, 0x3E, + + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, + 0x58, 0x5A, 0x5C, 0x5E, + + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, + 0x78, 0x7A, 0x7C, 0x7E, + + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, + 0x98, 0x9A, 0x9C, 0x9E, + + 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, + 0xB8, 0xBA, 0xBC, 0xBE, + + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, + 0xD8, 0xDA, 0xDC, 0xDE, + + 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, + 0xF8, 0xFA, 0xFC, 0xFE, + + 0x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15, 0x0B, 0x09, 0x0F, 0x0D, + 0x03, 0x01, 0x07, 0x05, + + 0x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35, 0x2B, 0x29, 0x2F, 0x2D, + 0x23, 0x21, 0x27, 0x25, + + 0x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55, 0x4B, 0x49, 0x4F, 0x4D, + 0x43, 0x41, 0x47, 0x45, + + 0x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75, 0x6B, 0x69, 0x6F, 0x6D, + 0x63, 0x61, 0x67, 0x65, + + 0x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95, 0x8B, 0x89, 0x8F, 0x8D, + 0x83, 0x81, 0x87, 0x85, + + 0xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5, 0xAB, 0xA9, 0xAF, 0xAD, + 0xA3, 0xA1, 0xA7, 0xA5, + + 0xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5, 0xCB, 0xC9, 0xCF, 0xCD, + 0xC3, 0xC1, 0xC7, 0xC5, + + 0xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5, 0xEB, 0xE9, 0xEF, 0xED, + 0xE3, 0xE1, 0xE7, 0xE5 +]; + + +/** + * Precomputed lookup of multiplication by 3 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_3_ = [ + 0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D, + 0x14, 0x17, 0x12, 0x11, + + 0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, + 0x24, 0x27, 0x22, 0x21, + + 0x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69, 0x78, 0x7B, 0x7E, 0x7D, + 0x74, 0x77, 0x72, 0x71, + + 0x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59, 0x48, 0x4B, 0x4E, 0x4D, + 0x44, 0x47, 0x42, 0x41, + + 0xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9, 0xD8, 0xDB, 0xDE, 0xDD, + 0xD4, 0xD7, 0xD2, 0xD1, + + 0xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9, 0xE8, 0xEB, 0xEE, 0xED, + 0xE4, 0xE7, 0xE2, 0xE1, + + 0xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9, 0xB8, 0xBB, 0xBE, 0xBD, + 0xB4, 0xB7, 0xB2, 0xB1, + + 0x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99, 0x88, 0x8B, 0x8E, 0x8D, + 0x84, 0x87, 0x82, 0x81, + + 0x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, + 0x8F, 0x8C, 0x89, 0x8A, + + 0xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2, 0xB3, 0xB0, 0xB5, 0xB6, + 0xBF, 0xBC, 0xB9, 0xBA, + + 0xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2, 0xE3, 0xE0, 0xE5, 0xE6, + 0xEF, 0xEC, 0xE9, 0xEA, + + 0xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2, 0xD3, 0xD0, 0xD5, 0xD6, + 0xDF, 0xDC, 0xD9, 0xDA, + + 0x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, + 0x4F, 0x4C, 0x49, 0x4A, + + 0x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, + 0x7F, 0x7C, 0x79, 0x7A, + + 0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, + 0x2F, 0x2C, 0x29, 0x2A, + + 0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, + 0x1F, 0x1C, 0x19, 0x1A +]; + + +/** + * Precomputed lookup of multiplication by 9 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_9_ = [ + 0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, + 0x6C, 0x65, 0x7E, 0x77, + + 0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3, + 0xFC, 0xF5, 0xEE, 0xE7, + + 0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04, 0x73, 0x7A, 0x61, 0x68, + 0x57, 0x5E, 0x45, 0x4C, + + 0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94, 0xE3, 0xEA, 0xF1, 0xF8, + 0xC7, 0xCE, 0xD5, 0xDC, + + 0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49, 0x3E, 0x37, 0x2C, 0x25, + 0x1A, 0x13, 0x08, 0x01, + + 0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9, 0xAE, 0xA7, 0xBC, 0xB5, + 0x8A, 0x83, 0x98, 0x91, + + 0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72, 0x05, 0x0C, 0x17, 0x1E, + 0x21, 0x28, 0x33, 0x3A, + + 0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2, 0x95, 0x9C, 0x87, 0x8E, + 0xB1, 0xB8, 0xA3, 0xAA, + + 0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3, 0xA4, 0xAD, 0xB6, 0xBF, + 0x80, 0x89, 0x92, 0x9B, + + 0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43, 0x34, 0x3D, 0x26, 0x2F, + 0x10, 0x19, 0x02, 0x0B, + + 0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84, + 0xBB, 0xB2, 0xA9, 0xA0, + + 0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14, + 0x2B, 0x22, 0x39, 0x30, + + 0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5, 0xD2, 0xDB, 0xC0, 0xC9, + 0xF6, 0xFF, 0xE4, 0xED, + + 0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35, 0x42, 0x4B, 0x50, 0x59, + 0x66, 0x6F, 0x74, 0x7D, + + 0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E, 0xE9, 0xE0, 0xFB, 0xF2, + 0xCD, 0xC4, 0xDF, 0xD6, + + 0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E, 0x79, 0x70, 0x6B, 0x62, + 0x5D, 0x54, 0x4F, 0x46 +]; + + +/** + * Precomputed lookup of multiplication by 11 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_B_ = [ + 0x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31, 0x58, 0x53, 0x4E, 0x45, + 0x74, 0x7F, 0x62, 0x69, + + 0xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81, 0xE8, 0xE3, 0xFE, 0xF5, + 0xC4, 0xCF, 0xD2, 0xD9, + + 0x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A, 0x23, 0x28, 0x35, 0x3E, + 0x0F, 0x04, 0x19, 0x12, + + 0xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA, 0x93, 0x98, 0x85, 0x8E, + 0xBF, 0xB4, 0xA9, 0xA2, + + 0xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7, 0xAE, 0xA5, 0xB8, 0xB3, + 0x82, 0x89, 0x94, 0x9F, + + 0x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77, 0x1E, 0x15, 0x08, 0x03, + 0x32, 0x39, 0x24, 0x2F, + + 0x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC, 0xD5, 0xDE, 0xC3, 0xC8, + 0xF9, 0xF2, 0xEF, 0xE4, + + 0x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C, 0x65, 0x6E, 0x73, 0x78, + 0x49, 0x42, 0x5F, 0x54, + + 0xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6, 0xAF, 0xA4, 0xB9, 0xB2, + 0x83, 0x88, 0x95, 0x9E, + + 0x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76, 0x1F, 0x14, 0x09, 0x02, + 0x33, 0x38, 0x25, 0x2E, + + 0x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD, 0xD4, 0xDF, 0xC2, 0xC9, + 0xF8, 0xF3, 0xEE, 0xE5, + + 0x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D, 0x64, 0x6F, 0x72, 0x79, + 0x48, 0x43, 0x5E, 0x55, + + 0x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30, 0x59, 0x52, 0x4F, 0x44, + 0x75, 0x7E, 0x63, 0x68, + + 0xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80, 0xE9, 0xE2, 0xFF, 0xF4, + 0xC5, 0xCE, 0xD3, 0xD8, + + 0x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B, 0x22, 0x29, 0x34, 0x3F, + 0x0E, 0x05, 0x18, 0x13, + + 0xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB, 0x92, 0x99, 0x84, 0x8F, + 0xBE, 0xB5, 0xA8, 0xA3 +]; + + +/** + * Precomputed lookup of multiplication by 13 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_D_ = [ + 0x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23, 0x68, 0x65, 0x72, 0x7F, + 0x5C, 0x51, 0x46, 0x4B, + + 0xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3, 0xB8, 0xB5, 0xA2, 0xAF, + 0x8C, 0x81, 0x96, 0x9B, + + 0xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98, 0xD3, 0xDE, 0xC9, 0xC4, + 0xE7, 0xEA, 0xFD, 0xF0, + + 0x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48, 0x03, 0x0E, 0x19, 0x14, + 0x37, 0x3A, 0x2D, 0x20, + + 0x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E, 0x05, 0x08, 0x1F, 0x12, + 0x31, 0x3C, 0x2B, 0x26, + + 0xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E, 0xD5, 0xD8, 0xCF, 0xC2, + 0xE1, 0xEC, 0xFB, 0xF6, + + 0xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5, 0xBE, 0xB3, 0xA4, 0xA9, + 0x8A, 0x87, 0x90, 0x9D, + + 0x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25, 0x6E, 0x63, 0x74, 0x79, + 0x5A, 0x57, 0x40, 0x4D, + + 0xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9, 0xB2, 0xBF, 0xA8, 0xA5, + 0x86, 0x8B, 0x9C, 0x91, + + 0x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29, 0x62, 0x6F, 0x78, 0x75, + 0x56, 0x5B, 0x4C, 0x41, + + 0x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42, 0x09, 0x04, 0x13, 0x1E, + 0x3D, 0x30, 0x27, 0x2A, + + 0xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92, 0xD9, 0xD4, 0xC3, 0xCE, + 0xED, 0xE0, 0xF7, 0xFA, + + 0xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94, 0xDF, 0xD2, 0xC5, 0xC8, + 0xEB, 0xE6, 0xF1, 0xFC, + + 0x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44, 0x0F, 0x02, 0x15, 0x18, + 0x3B, 0x36, 0x21, 0x2C, + + 0x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F, 0x64, 0x69, 0x7E, 0x73, + 0x50, 0x5D, 0x4A, 0x47, + + 0xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF, 0xB4, 0xB9, 0xAE, 0xA3, + 0x80, 0x8D, 0x9A, 0x97 +]; + + +/** + * Precomputed lookup of multiplication by 14 in GF(2^8) + * @type {!Array<number>} + * @private + */ +goog.crypt.Aes.MULT_E_ = [ + 0x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A, 0x70, 0x7E, 0x6C, 0x62, + 0x48, 0x46, 0x54, 0x5A, + + 0xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA, 0x90, 0x9E, 0x8C, 0x82, + 0xA8, 0xA6, 0xB4, 0xBA, + + 0xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1, 0xAB, 0xA5, 0xB7, 0xB9, + 0x93, 0x9D, 0x8F, 0x81, + + 0x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11, 0x4B, 0x45, 0x57, 0x59, + 0x73, 0x7D, 0x6F, 0x61, + + 0xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87, 0xDD, 0xD3, 0xC1, 0xCF, + 0xE5, 0xEB, 0xF9, 0xF7, + + 0x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67, 0x3D, 0x33, 0x21, 0x2F, + 0x05, 0x0B, 0x19, 0x17, + + 0x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C, 0x06, 0x08, 0x1A, 0x14, + 0x3E, 0x30, 0x22, 0x2C, + + 0x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC, 0xE6, 0xE8, 0xFA, 0xF4, + 0xDE, 0xD0, 0xC2, 0xCC, + + 0x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B, 0x31, 0x3F, 0x2D, 0x23, + 0x09, 0x07, 0x15, 0x1B, + + 0xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B, 0xD1, 0xDF, 0xCD, 0xC3, + 0xE9, 0xE7, 0xF5, 0xFB, + + 0x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0, 0xEA, 0xE4, 0xF6, 0xF8, + 0xD2, 0xDC, 0xCE, 0xC0, + + 0x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50, 0x0A, 0x04, 0x16, 0x18, + 0x32, 0x3C, 0x2E, 0x20, + + 0xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6, 0x9C, 0x92, 0x80, 0x8E, + 0xA4, 0xAA, 0xB8, 0xB6, + + 0x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26, 0x7C, 0x72, 0x60, 0x6E, + 0x44, 0x4A, 0x58, 0x56, + + 0x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D, 0x47, 0x49, 0x5B, 0x55, + 0x7F, 0x71, 0x63, 0x6D, + + 0xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD, 0xA7, 0xA9, 0xBB, 0xB5, + 0x9F, 0x91, 0x83, 0x8D +]; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/crypt/arc4.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/crypt/arc4.js b/externs/GCL/externs/goog/crypt/arc4.js new file mode 100644 index 0000000..73c6758 --- /dev/null +++ b/externs/GCL/externs/goog/crypt/arc4.js @@ -0,0 +1,164 @@ +// 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 ARC4 streamcipher implementation. A description of the + * algorithm can be found at: + * http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt. + * + * Usage: + * <code> + * var arc4 = new goog.crypt.Arc4(); + * arc4.setKey(key); + * arc4.discard(1536); + * arc4.crypt(bytes); + * </code> + * + * Note: For converting between strings and byte arrays, goog.crypt.base64 may + * be useful. + * + */ + +goog.provide('goog.crypt.Arc4'); + +goog.require('goog.asserts'); + + + +/** + * ARC4 streamcipher implementation. + * @constructor + * @final + * @struct + */ +goog.crypt.Arc4 = function() { + /** + * A permutation of all 256 possible bytes. + * @type {Array<number>} + * @private + */ + this.state_ = []; + + /** + * 8 bit index pointer into this.state_. + * @type {number} + * @private + */ + this.index1_ = 0; + + /** + * 8 bit index pointer into this.state_. + * @type {number} + * @private + */ + this.index2_ = 0; +}; + + +/** + * Initialize the cipher for use with new key. + * @param {Array<number>} key A byte array containing the key. + * @param {number=} opt_length Indicates # of bytes to take from the key. + */ +goog.crypt.Arc4.prototype.setKey = function(key, opt_length) { + goog.asserts.assertArray(key, 'Key parameter must be a byte array'); + + if (!opt_length) { + opt_length = key.length; + } + + var state = this.state_; + + for (var i = 0; i < 256; ++i) { + state[i] = i; + } + + var j = 0; + for (var i = 0; i < 256; ++i) { + j = (j + state[i] + key[i % opt_length]) & 255; + + var tmp = state[i]; + state[i] = state[j]; + state[j] = tmp; + } + + this.index1_ = 0; + this.index2_ = 0; +}; + + +/** + * Discards n bytes of the keystream. + * These days 1536 is considered a decent amount to drop to get the key state + * warmed-up enough for secure usage. This is not done in the constructor to + * preserve efficiency for use cases that do not need this. + * NOTE: Discard is identical to crypt without actually xoring any data. It's + * unfortunate to have this code duplicated, but this was done for performance + * reasons. Alternatives which were attempted: + * 1. Create a temp array of the correct length and pass it to crypt. This + * works but needlessly allocates an array. But more importantly this + * requires choosing an array type (Array or Uint8Array) in discard, and + * choosing a different type than will be passed to crypt by the client + * code hurts the javascript engines ability to optimize crypt (7x hit in + * v8). + * 2. Make data option in crypt so discard can pass null, this has a huge + * perf hit for crypt. + * @param {number} length Number of bytes to disregard from the stream. + */ +goog.crypt.Arc4.prototype.discard = function(length) { + var i = this.index1_; + var j = this.index2_; + var state = this.state_; + + for (var n = 0; n < length; ++n) { + i = (i + 1) & 255; + j = (j + state[i]) & 255; + + var tmp = state[i]; + state[i] = state[j]; + state[j] = tmp; + } + + this.index1_ = i; + this.index2_ = j; +}; + + +/** + * En- or decrypt (same operation for streamciphers like ARC4) + * @param {Array<number>|Uint8Array} data The data to be xor-ed in place. + * @param {number=} opt_length The number of bytes to crypt. + */ +goog.crypt.Arc4.prototype.crypt = function(data, opt_length) { + if (!opt_length) { + opt_length = data.length; + } + var i = this.index1_; + var j = this.index2_; + var state = this.state_; + + for (var n = 0; n < opt_length; ++n) { + i = (i + 1) & 255; + j = (j + state[i]) & 255; + + var tmp = state[i]; + state[i] = state[j]; + state[j] = tmp; + + data[n] ^= state[(state[i] + state[j]) & 255]; + } + + this.index1_ = i; + this.index2_ = j; +};
