Last active
December 3, 2016 04:35
-
-
Save jgillich/617494cb670a70e0c27f6a4c878202e0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<body> | |
<div id="terminal" | |
style="position:relative; width:100%; height:500px"></div> | |
</body> | |
<script src="hterm_all.js"></script> | |
<script> | |
hterm.defaultStorage = new lib.Storage.Local() | |
var t = new hterm.Terminal("foo") | |
t.onTerminalReady = function() { | |
var io = t.io.push(); | |
io.onVTKeystroke = function(str) { | |
console.log(str) | |
}; | |
io.sendString = function(str) { | |
console.log(str) | |
}; | |
}; | |
t.decorate(document.querySelector('#terminal')); | |
t.io.println('Print a string and add CRLF'); | |
</script> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file was generated by libdot/bin/concat.sh. | |
// It has been marked read-only for your safety. Rather | |
// than edit it directly, please modify one of these source | |
// files... | |
// | |
// libdot/js/lib.js | |
// libdot/js/lib_colors.js | |
// libdot/js/lib_f.js | |
// libdot/js/lib_message_manager.js | |
// libdot/js/lib_preference_manager.js | |
// libdot/js/lib_resource.js | |
// libdot/js/lib_storage.js | |
// libdot/js/lib_storage_chrome.js | |
// libdot/js/lib_storage_local.js | |
// libdot/js/lib_storage_memory.js | |
// libdot/js/lib_test_manager.js | |
// libdot/js/lib_utf8.js | |
// libdot/js/lib_wc.js | |
// hterm/js/hterm.js | |
// hterm/js/hterm_frame.js | |
// hterm/js/hterm_keyboard.js | |
// hterm/js/hterm_keyboard_bindings.js | |
// hterm/js/hterm_keyboard_keymap.js | |
// hterm/js/hterm_keyboard_keypattern.js | |
// hterm/js/hterm_options.js | |
// hterm/js/hterm_parser.js | |
// hterm/js/hterm_parser_identifiers.js | |
// hterm/js/hterm_preference_manager.js | |
// hterm/js/hterm_pubsub.js | |
// hterm/js/hterm_screen.js | |
// hterm/js/hterm_scrollport.js | |
// hterm/js/hterm_terminal.js | |
// hterm/js/hterm_terminal_io.js | |
// hterm/js/hterm_text_attributes.js | |
// hterm/js/hterm_vt.js | |
// hterm/js/hterm_vt_character_map.js | |
// | |
// SOURCE FILE: libdot/js/lib.js | |
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
'use strict'; | |
if (typeof lib != 'undefined') | |
throw new Error('Global "lib" object already exists.'); | |
var lib = {}; | |
/** | |
* Map of "dependency" to ["source", ...]. | |
* | |
* Each dependency is a object name, like "lib.fs", "source" is the url that | |
* depdends on the object. | |
*/ | |
lib.runtimeDependencies_ = {}; | |
/** | |
* List of functions that need to be invoked during library initialization. | |
* | |
* Each element in the initCallbacks_ array is itself a two-element array. | |
* Element 0 is a short string describing the owner of the init routine, useful | |
* for debugging. Element 1 is the callback function. | |
*/ | |
lib.initCallbacks_ = []; | |
/** | |
* Records a runtime dependency. | |
* | |
* This can be useful when you want to express a run-time dependency at | |
* compile time. It is not intended to be a full-fledged library system or | |
* dependency tracker. It's just there to make it possible to debug the | |
* deps without running all the code. | |
* | |
* Object names are specified as strings. For example... | |
* | |
* lib.rtdep('lib.colors', 'lib.PreferenceManager'); | |
* | |
* Object names need not be rooted by 'lib'. You may use this to declare a | |
* dependency on any object. | |
* | |
* The client program may call lib.ensureRuntimeDependencies() at startup in | |
* order to ensure that all runtime dependencies have been met. | |
* | |
* @param {string} var_args One or more objects specified as strings. | |
*/ | |
lib.rtdep = function(var_args) { | |
var source; | |
try { | |
throw new Error(); | |
} catch (ex) { | |
var stackArray = ex.stack.split('\n'); | |
// In Safari, the resulting stackArray will only have 2 elements and the | |
// individual strings are formatted differently. | |
if (stackArray.length >= 3) { | |
source = stackArray[2].replace(/^\s*at\s+/, ''); | |
} else { | |
source = stackArray[1].replace(/^\s*global code@/, ''); | |
} | |
} | |
for (var i = 0; i < arguments.length; i++) { | |
var path = arguments[i]; | |
if (path instanceof Array) { | |
lib.rtdep.apply(lib, path); | |
} else { | |
var ary = this.runtimeDependencies_[path]; | |
if (!ary) | |
ary = this.runtimeDependencies_[path] = []; | |
ary.push(source); | |
} | |
} | |
}; | |
/** | |
* Ensures that all runtime dependencies are met, or an exception is thrown. | |
* | |
* Every unmet runtime dependency will be logged to the JS console. If at | |
* least one dependency is unmet this will raise an exception. | |
*/ | |
lib.ensureRuntimeDependencies_ = function() { | |
var passed = true; | |
for (var path in lib.runtimeDependencies_) { | |
var sourceList = lib.runtimeDependencies_[path]; | |
var names = path.split('.'); | |
// In a document context 'window' is the global object. In a worker it's | |
// called 'self'. | |
var obj = (window || self); | |
for (var i = 0; i < names.length; i++) { | |
if (!(names[i] in obj)) { | |
console.warn('Missing "' + path + '" is needed by', sourceList); | |
passed = false; | |
break; | |
} | |
obj = obj[names[i]]; | |
} | |
} | |
if (!passed) | |
throw new Error('Failed runtime dependency check'); | |
}; | |
/** | |
* Register an initialization function. | |
* | |
* The initialization functions are invoked in registration order when | |
* lib.init() is invoked. Each function will receive a single parameter, which | |
* is a function to be invoked when it completes its part of the initialization. | |
* | |
* @param {string} name A short descriptive name of the init routine useful for | |
* debugging. | |
* @param {function(function)} callback The initialization function to register. | |
* @return {function} The callback parameter. | |
*/ | |
lib.registerInit = function(name, callback) { | |
lib.initCallbacks_.push([name, callback]); | |
return callback; | |
}; | |
/** | |
* Initialize the library. | |
* | |
* This will ensure that all registered runtime dependencies are met, and | |
* invoke any registered initialization functions. | |
* | |
* Initialization is asynchronous. The library is not ready for use until | |
* the onInit function is invoked. | |
* | |
* @param {function()} onInit The function to invoke when initialization is | |
* complete. | |
* @param {function(*)} opt_logFunction An optional function to send | |
* initialization related log messages to. | |
*/ | |
lib.init = function(onInit, opt_logFunction) { | |
var ary = lib.initCallbacks_; | |
var initNext = function() { | |
if (ary.length) { | |
var rec = ary.shift(); | |
if (opt_logFunction) | |
opt_logFunction('init: ' + rec[0]); | |
rec[1](lib.f.alarm(initNext)); | |
} else { | |
onInit(); | |
} | |
}; | |
if (typeof onInit != 'function') | |
throw new Error('Missing or invalid argument: onInit'); | |
lib.ensureRuntimeDependencies_(); | |
setTimeout(initNext, 0); | |
}; | |
// SOURCE FILE: libdot/js/lib_colors.js | |
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
'use strict'; | |
/** | |
* Namespace for color utilities. | |
*/ | |
lib.colors = {}; | |
/** | |
* First, some canned regular expressions we're going to use in this file. | |
* | |
* | |
* BRACE YOURSELF | |
* | |
* ,~~~~. | |
* |>_< ~~ | |
* 3`---'-/. | |
* 3:::::\v\ | |
* =o=:::::\,\ | |
* | :::::\,,\ | |
* | |
* THE REGULAR EXPRESSIONS | |
* ARE COMING. | |
* | |
* There's no way to break long RE literals in JavaScript. Fix that why don't | |
* you? Oh, and also there's no way to write a string that doesn't interpret | |
* escapes. | |
* | |
* Instead, we stoop to this .replace() trick. | |
*/ | |
lib.colors.re_ = { | |
// CSS hex color, #RGB. | |
hex16: /#([a-f0-9])([a-f0-9])([a-f0-9])/i, | |
// CSS hex color, #RRGGBB. | |
hex24: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i, | |
// CSS rgb color, rgb(rrr,ggg,bbb). | |
rgb: new RegExp( | |
('^/s*rgb/s*/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,' + | |
'/s*(/d{1,3})/s*/)/s*$' | |
).replace(/\//g, '\\'), 'i'), | |
// CSS rgb color, rgb(rrr,ggg,bbb,aaa). | |
rgba: new RegExp( | |
('^/s*rgba/s*' + | |
'/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' + | |
'(?:,/s*(/d+(?:/./d+)?)/s*)/)/s*$' | |
).replace(/\//g, '\\'), 'i'), | |
// Either RGB or RGBA. | |
rgbx: new RegExp( | |
('^/s*rgba?/s*' + | |
'/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' + | |
'(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$' | |
).replace(/\//g, '\\'), 'i'), | |
// An X11 "rgb:ddd/ddd/ddd" value. | |
x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i, | |
// English color name. | |
name: /[a-z][a-z0-9\s]+/, | |
}; | |
/** | |
* Convert a CSS rgb(ddd,ddd,ddd) color value into an X11 color value. | |
* | |
* Other CSS color values are ignored to ensure sanitary data handling. | |
* | |
* Each 'ddd' component is a one byte value specified in decimal. | |
* | |
* @param {string} value The CSS color value to convert. | |
* @return {string} The X11 color value or null if the value could not be | |
* converted. | |
*/ | |
lib.colors.rgbToX11 = function(value) { | |
function scale(v) { | |
v = (Math.min(v, 255) * 257).toString(16); | |
while (v.length < 4) | |
v = '0' + v; | |
return v; | |
} | |
var ary = value.match(lib.colors.re_.rgbx); | |
if (!ary) | |
return null; | |
return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]); | |
}; | |
/** | |
* Convert an X11 color value into an CSS rgb(...) color value. | |
* | |
* The X11 value may be an X11 color name, or an RGB value of the form | |
* rgb:hhhh/hhhh/hhhh. If a component value is less than 4 digits it is | |
* padded out to 4, then scaled down to fit in a single byte. | |
* | |
* @param {string} value The X11 color value to convert. | |
* @return {string} The CSS color value or null if the value could not be | |
* converted. | |
*/ | |
lib.colors.x11ToCSS = function(v) { | |
function scale(v) { | |
// Pad out values with less than four digits. This padding (probably) | |
// matches xterm. It's difficult to say for sure since xterm seems to | |
// arrive at a padded value and then perform some combination of | |
// gamma correction, color space tranformation, and quantization. | |
if (v.length == 1) { | |
// Single digits pad out to four by repeating the character. "f" becomes | |
// "ffff". Scaling down a hex value of this pattern by 257 is the same | |
// as cutting off one byte. We skip the middle step and just double | |
// the character. | |
return parseInt(v + v, 16); | |
} | |
if (v.length == 2) { | |
// Similar deal here. X11 pads two digit values by repeating the | |
// byte (or scale up by 257). Since we're going to scale it back | |
// down anyway, we can just return the original value. | |
return parseInt(v, 16); | |
} | |
if (v.length == 3) { | |
// Three digit values seem to be padded by repeating the final digit. | |
// e.g. 10f becomes 10ff. | |
v = v + v.substr(2); | |
} | |
// Scale down the 2 byte value. | |
return Math.round(parseInt(v, 16) / 257); | |
} | |
var ary = v.match(lib.colors.re_.x11rgb); | |
if (!ary) | |
return lib.colors.nameToRGB(v); | |
ary.splice(0, 1); | |
return lib.colors.arrayToRGBA(ary.map(scale)); | |
}; | |
/** | |
* Converts one or more CSS '#RRGGBB' color values into their rgb(...) | |
* form. | |
* | |
* Arrays are converted in place. If a value cannot be converted, it is | |
* replaced with null. | |
* | |
* @param {string|Array.<string>} A single RGB value or array of RGB values to | |
* convert. | |
* @return {string|Array.<string>} The converted value or values. | |
*/ | |
lib.colors.hexToRGB = function(arg) { | |
var hex16 = lib.colors.re_.hex16; | |
var hex24 = lib.colors.re_.hex24; | |
function convert(hex) { | |
if (hex.length == 4) { | |
hex = hex.replace(hex16, function(h, r, g, b) { | |
return "#" + r + r + g + g + b + b; | |
}); | |
} | |
var ary = hex.match(hex24); | |
if (!ary) | |
return null; | |
return 'rgb(' + parseInt(ary[1], 16) + ', ' + | |
parseInt(ary[2], 16) + ', ' + | |
parseInt(ary[3], 16) + ')'; | |
} | |
if (arg instanceof Array) { | |
for (var i = 0; i < arg.length; i++) { | |
arg[i] = convert(arg[i]); | |
} | |
} else { | |
arg = convert(arg); | |
} | |
return arg; | |
}; | |
/** | |
* Converts one or more CSS rgb(...) forms into their '#RRGGBB' color values. | |
* | |
* If given an rgba(...) form, the alpha field is thrown away. | |
* | |
* Arrays are converted in place. If a value cannot be converted, it is | |
* replaced with null. | |
* | |
* @param {string|Array.<string>} A single rgb(...) value or array of rgb(...) | |
* values to convert. | |
* @return {string|Array.<string>} The converted value or values. | |
*/ | |
lib.colors.rgbToHex = function(arg) { | |
function convert(rgb) { | |
var ary = lib.colors.crackRGB(rgb); | |
return '#' + lib.f.zpad(((parseInt(ary[0]) << 16) | | |
(parseInt(ary[1]) << 8) | | |
(parseInt(ary[2]) << 0)).toString(16), 6); | |
} | |
if (arg instanceof Array) { | |
for (var i = 0; i < arg.length; i++) { | |
arg[i] = convert(arg[i]); | |
} | |
} else { | |
arg = convert(arg); | |
} | |
return arg; | |
}; | |
/** | |
* Take any valid css color definition and turn it into an rgb or rgba value. | |
* | |
* Returns null if the value could not be normalized. | |
*/ | |
lib.colors.normalizeCSS = function(def) { | |
if (def.substr(0, 1) == '#') | |
return lib.colors.hexToRGB(def); | |
if (lib.colors.re_.rgbx.test(def)) | |
return def; | |
return lib.colors.nameToRGB(def); | |
}; | |
/** | |
* Convert a 3 or 4 element array into an rgba(...) string. | |
*/ | |
lib.colors.arrayToRGBA = function(ary) { | |
var alpha = (ary.length > 3) ? ary[3] : 1; | |
return 'rgba(' + ary[0] + ', ' + ary[1] + ', ' + ary[2] + ', ' + alpha + ')'; | |
}; | |
/** | |
* Overwrite the alpha channel of an rgb/rgba color. | |
*/ | |
lib.colors.setAlpha = function(rgb, alpha) { | |
var ary = lib.colors.crackRGB(rgb); | |
ary[3] = alpha; | |
return lib.colors.arrayToRGBA(ary); | |
}; | |
/** | |
* Mix a percentage of a tint color into a base color. | |
*/ | |
lib.colors.mix = function(base, tint, percent) { | |
var ary1 = lib.colors.crackRGB(base); | |
var ary2 = lib.colors.crackRGB(tint); | |
for (var i = 0; i < 4; ++i) { | |
var diff = ary2[i] - ary1[i]; | |
ary1[i] = Math.round(parseInt(ary1[i]) + diff * percent); | |
} | |
return lib.colors.arrayToRGBA(ary1); | |
}; | |
/** | |
* Split an rgb/rgba color into an array of its components. | |
* | |
* On success, a 4 element array will be returned. For rgb values, the alpha | |
* will be set to 1. | |
*/ | |
lib.colors.crackRGB = function(color) { | |
if (color.substr(0, 4) == 'rgba') { | |
var ary = color.match(lib.colors.re_.rgba); | |
if (ary) { | |
ary.shift(); | |
return ary; | |
} | |
} else { | |
var ary = color.match(lib.colors.re_.rgb); | |
if (ary) { | |
ary.shift(); | |
ary.push(1); | |
return ary; | |
} | |
} | |
console.error('Couldn\'t crack: ' + color); | |
return null; | |
}; | |
/** | |
* Convert an X11 color name into a CSS rgb(...) value. | |
* | |
* Names are stripped of spaces and converted to lowercase. If the name is | |
* unknown, null is returned. | |
* | |
* This list of color name to RGB mapping is derived from the stock X11 | |
* rgb.txt file. | |
* | |
* @param {string} name The color name to convert. | |
* @return {string} The corresponding CSS rgb(...) value. | |
*/ | |
lib.colors.nameToRGB = function(name) { | |
if (name in lib.colors.colorNames) | |
return lib.colors.colorNames[name]; | |
name = name.toLowerCase(); | |
if (name in lib.colors.colorNames) | |
return lib.colors.colorNames[name]; | |
name = name.replace(/\s+/g, ''); | |
if (name in lib.colors.colorNames) | |
return lib.colors.colorNames[name]; | |
return null; | |
}; | |
/** | |
* The stock color palette. | |
*/ | |
lib.colors.stockColorPalette = lib.colors.hexToRGB | |
([// The "ANSI 16"... | |
'#000000', '#CC0000', '#4E9A06', '#C4A000', | |
'#3465A4', '#75507B', '#06989A', '#D3D7CF', | |
'#555753', '#EF2929', '#00BA13', '#FCE94F', | |
'#729FCF', '#F200CB', '#00B5BD', '#EEEEEC', | |
// The 6x6 color cubes... | |
'#000000', '#00005F', '#000087', '#0000AF', '#0000D7', '#0000FF', | |
'#005F00', '#005F5F', '#005F87', '#005FAF', '#005FD7', '#005FFF', | |
'#008700', '#00875F', '#008787', '#0087AF', '#0087D7', '#0087FF', | |
'#00AF00', '#00AF5F', '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', | |
'#00D700', '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF', | |
'#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', | |
'#5F0000', '#5F005F', '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', | |
'#5F5F00', '#5F5F5F', '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', | |
'#5F8700', '#5F875F', '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', | |
'#5FAF00', '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', | |
'#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', | |
'#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', | |
'#870000', '#87005F', '#870087', '#8700AF', '#8700D7', '#8700FF', | |
'#875F00', '#875F5F', '#875F87', '#875FAF', '#875FD7', '#875FFF', | |
'#878700', '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF', | |
'#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', | |
'#87D700', '#87D75F', '#87D787', '#87D7AF', '#87D7D7', '#87D7FF', | |
'#87FF00', '#87FF5F', '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', | |
'#AF0000', '#AF005F', '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', | |
'#AF5F00', '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', | |
'#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', | |
'#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', | |
'#AFD700', '#AFD75F', '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', | |
'#AFFF00', '#AFFF5F', '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', | |
'#D70000', '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF', | |
'#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', | |
'#D78700', '#D7875F', '#D78787', '#D787AF', '#D787D7', '#D787FF', | |
'#D7AF00', '#D7AF5F', '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', | |
'#D7D700', '#D7D75F', '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', | |
'#D7FF00', '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', | |
'#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', | |
'#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', | |
'#FF8700', '#FF875F', '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', | |
'#FFAF00', '#FFAF5F', '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', | |
'#FFD700', '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', | |
'#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', | |
// The greyscale ramp... | |
'#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A', | |
'#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676', | |
'#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', | |
'#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE' | |
]); | |
/** | |
* The current color palette, possibly with user changes. | |
*/ | |
lib.colors.colorPalette = lib.colors.stockColorPalette; | |
/** | |
* Named colors according to the stock X11 rgb.txt file. | |
*/ | |
lib.colors.colorNames = { | |
"aliceblue": "rgb(240, 248, 255)", | |
"antiquewhite": "rgb(250, 235, 215)", | |
"antiquewhite1": "rgb(255, 239, 219)", | |
"antiquewhite2": "rgb(238, 223, 204)", | |
"antiquewhite3": "rgb(205, 192, 176)", | |
"antiquewhite4": "rgb(139, 131, 120)", | |
"aquamarine": "rgb(127, 255, 212)", | |
"aquamarine1": "rgb(127, 255, 212)", | |
"aquamarine2": "rgb(118, 238, 198)", | |
"aquamarine3": "rgb(102, 205, 170)", | |
"aquamarine4": "rgb(69, 139, 116)", | |
"azure": "rgb(240, 255, 255)", | |
"azure1": "rgb(240, 255, 255)", | |
"azure2": "rgb(224, 238, 238)", | |
"azure3": "rgb(193, 205, 205)", | |
"azure4": "rgb(131, 139, 139)", | |
"beige": "rgb(245, 245, 220)", | |
"bisque": "rgb(255, 228, 196)", | |
"bisque1": "rgb(255, 228, 196)", | |
"bisque2": "rgb(238, 213, 183)", | |
"bisque3": "rgb(205, 183, 158)", | |
"bisque4": "rgb(139, 125, 107)", | |
"black": "rgb(0, 0, 0)", | |
"blanchedalmond": "rgb(255, 235, 205)", | |
"blue": "rgb(0, 0, 255)", | |
"blue1": "rgb(0, 0, 255)", | |
"blue2": "rgb(0, 0, 238)", | |
"blue3": "rgb(0, 0, 205)", | |
"blue4": "rgb(0, 0, 139)", | |
"blueviolet": "rgb(138, 43, 226)", | |
"brown": "rgb(165, 42, 42)", | |
"brown1": "rgb(255, 64, 64)", | |
"brown2": "rgb(238, 59, 59)", | |
"brown3": "rgb(205, 51, 51)", | |
"brown4": "rgb(139, 35, 35)", | |
"burlywood": "rgb(222, 184, 135)", | |
"burlywood1": "rgb(255, 211, 155)", | |
"burlywood2": "rgb(238, 197, 145)", | |
"burlywood3": "rgb(205, 170, 125)", | |
"burlywood4": "rgb(139, 115, 85)", | |
"cadetblue": "rgb(95, 158, 160)", | |
"cadetblue1": "rgb(152, 245, 255)", | |
"cadetblue2": "rgb(142, 229, 238)", | |
"cadetblue3": "rgb(122, 197, 205)", | |
"cadetblue4": "rgb(83, 134, 139)", | |
"chartreuse": "rgb(127, 255, 0)", | |
"chartreuse1": "rgb(127, 255, 0)", | |
"chartreuse2": "rgb(118, 238, 0)", | |
"chartreuse3": "rgb(102, 205, 0)", | |
"chartreuse4": "rgb(69, 139, 0)", | |
"chocolate": "rgb(210, 105, 30)", | |
"chocolate1": "rgb(255, 127, 36)", | |
"chocolate2": "rgb(238, 118, 33)", | |
"chocolate3": "rgb(205, 102, 29)", | |
"chocolate4": "rgb(139, 69, 19)", | |
"coral": "rgb(255, 127, 80)", | |
"coral1": "rgb(255, 114, 86)", | |
"coral2": "rgb(238, 106, 80)", | |
"coral3": "rgb(205, 91, 69)", | |
"coral4": "rgb(139, 62, 47)", | |
"cornflowerblue": "rgb(100, 149, 237)", | |
"cornsilk": "rgb(255, 248, 220)", | |
"cornsilk1": "rgb(255, 248, 220)", | |
"cornsilk2": "rgb(238, 232, 205)", | |
"cornsilk3": "rgb(205, 200, 177)", | |
"cornsilk4": "rgb(139, 136, 120)", | |
"cyan": "rgb(0, 255, 255)", | |
"cyan1": "rgb(0, 255, 255)", | |
"cyan2": "rgb(0, 238, 238)", | |
"cyan3": "rgb(0, 205, 205)", | |
"cyan4": "rgb(0, 139, 139)", | |
"darkblue": "rgb(0, 0, 139)", | |
"darkcyan": "rgb(0, 139, 139)", | |
"darkgoldenrod": "rgb(184, 134, 11)", | |
"darkgoldenrod1": "rgb(255, 185, 15)", | |
"darkgoldenrod2": "rgb(238, 173, 14)", | |
"darkgoldenrod3": "rgb(205, 149, 12)", | |
"darkgoldenrod4": "rgb(139, 101, 8)", | |
"darkgray": "rgb(169, 169, 169)", | |
"darkgreen": "rgb(0, 100, 0)", | |
"darkgrey": "rgb(169, 169, 169)", | |
"darkkhaki": "rgb(189, 183, 107)", | |
"darkmagenta": "rgb(139, 0, 139)", | |
"darkolivegreen": "rgb(85, 107, 47)", | |
"darkolivegreen1": "rgb(202, 255, 112)", | |
"darkolivegreen2": "rgb(188, 238, 104)", | |
"darkolivegreen3": "rgb(162, 205, 90)", | |
"darkolivegreen4": "rgb(110, 139, 61)", | |
"darkorange": "rgb(255, 140, 0)", | |
"darkorange1": "rgb(255, 127, 0)", | |
"darkorange2": "rgb(238, 118, 0)", | |
"darkorange3": "rgb(205, 102, 0)", | |
"darkorange4": "rgb(139, 69, 0)", | |
"darkorchid": "rgb(153, 50, 204)", | |
"darkorchid1": "rgb(191, 62, 255)", | |
"darkorchid2": "rgb(178, 58, 238)", | |
"darkorchid3": "rgb(154, 50, 205)", | |
"darkorchid4": "rgb(104, 34, 139)", | |
"darkred": "rgb(139, 0, 0)", | |
"darksalmon": "rgb(233, 150, 122)", | |
"darkseagreen": "rgb(143, 188, 143)", | |
"darkseagreen1": "rgb(193, 255, 193)", | |
"darkseagreen2": "rgb(180, 238, 180)", | |
"darkseagreen3": "rgb(155, 205, 155)", | |
"darkseagreen4": "rgb(105, 139, 105)", | |
"darkslateblue": "rgb(72, 61, 139)", | |
"darkslategray": "rgb(47, 79, 79)", | |
"darkslategray1": "rgb(151, 255, 255)", | |
"darkslategray2": "rgb(141, 238, 238)", | |
"darkslategray3": "rgb(121, 205, 205)", | |
"darkslategray4": "rgb(82, 139, 139)", | |
"darkslategrey": "rgb(47, 79, 79)", | |
"darkturquoise": "rgb(0, 206, 209)", | |
"darkviolet": "rgb(148, 0, 211)", | |
"debianred": "rgb(215, 7, 81)", | |
"deeppink": "rgb(255, 20, 147)", | |
"deeppink1": "rgb(255, 20, 147)", | |
"deeppink2": "rgb(238, 18, 137)", | |
"deeppink3": "rgb(205, 16, 118)", | |
"deeppink4": "rgb(139, 10, 80)", | |
"deepskyblue": "rgb(0, 191, 255)", | |
"deepskyblue1": "rgb(0, 191, 255)", | |
"deepskyblue2": "rgb(0, 178, 238)", | |
"deepskyblue3": "rgb(0, 154, 205)", | |
"deepskyblue4": "rgb(0, 104, 139)", | |
"dimgray": "rgb(105, 105, 105)", | |
"dimgrey": "rgb(105, 105, 105)", | |
"dodgerblue": "rgb(30, 144, 255)", | |
"dodgerblue1": "rgb(30, 144, 255)", | |
"dodgerblue2": "rgb(28, 134, 238)", | |
"dodgerblue3": "rgb(24, 116, 205)", | |
"dodgerblue4": "rgb(16, 78, 139)", | |
"firebrick": "rgb(178, 34, 34)", | |
"firebrick1": "rgb(255, 48, 48)", | |
"firebrick2": "rgb(238, 44, 44)", | |
"firebrick3": "rgb(205, 38, 38)", | |
"firebrick4": "rgb(139, 26, 26)", | |
"floralwhite": "rgb(255, 250, 240)", | |
"forestgreen": "rgb(34, 139, 34)", | |
"gainsboro": "rgb(220, 220, 220)", | |
"ghostwhite": "rgb(248, 248, 255)", | |
"gold": "rgb(255, 215, 0)", | |
"gold1": "rgb(255, 215, 0)", | |
"gold2": "rgb(238, 201, 0)", | |
"gold3": "rgb(205, 173, 0)", | |
"gold4": "rgb(139, 117, 0)", | |
"goldenrod": "rgb(218, 165, 32)", | |
"goldenrod1": "rgb(255, 193, 37)", | |
"goldenrod2": "rgb(238, 180, 34)", | |
"goldenrod3": "rgb(205, 155, 29)", | |
"goldenrod4": "rgb(139, 105, 20)", | |
"gray": "rgb(190, 190, 190)", | |
"gray0": "rgb(0, 0, 0)", | |
"gray1": "rgb(3, 3, 3)", | |
"gray10": "rgb(26, 26, 26)", | |
"gray100": "rgb(255, 255, 255)", | |
"gray11": "rgb(28, 28, 28)", | |
"gray12": "rgb(31, 31, 31)", | |
"gray13": "rgb(33, 33, 33)", | |
"gray14": "rgb(36, 36, 36)", | |
"gray15": "rgb(38, 38, 38)", | |
"gray16": "rgb(41, 41, 41)", | |
"gray17": "rgb(43, 43, 43)", | |
"gray18": "rgb(46, 46, 46)", | |
"gray19": "rgb(48, 48, 48)", | |
"gray2": "rgb(5, 5, 5)", | |
"gray20": "rgb(51, 51, 51)", | |
"gray21": "rgb(54, 54, 54)", | |
"gray22": "rgb(56, 56, 56)", | |
"gray23": "rgb(59, 59, 59)", | |
"gray24": "rgb(61, 61, 61)", | |
"gray25": "rgb(64, 64, 64)", | |
"gray26": "rgb(66, 66, 66)", | |
"gray27": "rgb(69, 69, 69)", | |
"gray28": "rgb(71, 71, 71)", | |
"gray29": "rgb(74, 74, 74)", | |
"gray3": "rgb(8, 8, 8)", | |
"gray30": "rgb(77, 77, 77)", | |
"gray31": "rgb(79, 79, 79)", | |
"gray32": "rgb(82, 82, 82)", | |
"gray33": "rgb(84, 84, 84)", | |
"gray34": "rgb(87, 87, 87)", | |
"gray35": "rgb(89, 89, 89)", | |
"gray36": "rgb(92, 92, 92)", | |
"gray37": "rgb(94, 94, 94)", | |
"gray38": "rgb(97, 97, 97)", | |
"gray39": "rgb(99, 99, 99)", | |
"gray4": "rgb(10, 10, 10)", | |
"gray40": "rgb(102, 102, 102)", | |
"gray41": "rgb(105, 105, 105)", | |
"gray42": "rgb(107, 107, 107)", | |
"gray43": "rgb(110, 110, 110)", | |
"gray44": "rgb(112, 112, 112)", | |
"gray45": "rgb(115, 115, 115)", | |
"gray46": "rgb(117, 117, 117)", | |
"gray47": "rgb(120, 120, 120)", | |
"gray48": "rgb(122, 122, 122)", | |
"gray49": "rgb(125, 125, 125)", | |
"gray5": "rgb(13, 13, 13)", | |
"gray50": "rgb(127, 127, 127)", | |
"gray51": "rgb(130, 130, 130)", | |
"gray52": "rgb(133, 133, 133)", | |
"gray53": "rgb(135, 135, 135)", | |
"gray54": "rgb(138, 138, 138)", | |
"gray55": "rgb(140, 140, 140)", | |
"gray56": "rgb(143, 143, 143)", | |
"gray57": "rgb(145, 145, 145)", | |
"gray58": "rgb(148, 148, 148)", | |
"gray59": "rgb(150, 150, 150)", | |
"gray6": "rgb(15, 15, 15)", | |
"gray60": "rgb(153, 153, 153)", | |
"gray61": "rgb(156, 156, 156)", | |
"gray62": "rgb(158, 158, 158)", | |
"gray63": "rgb(161, 161, 161)", | |
"gray64": "rgb(163, 163, 163)", | |
"gray65": "rgb(166, 166, 166)", | |
"gray66": "rgb(168, 168, 168)", | |
"gray67": "rgb(171, 171, 171)", | |
"gray68": "rgb(173, 173, 173)", | |
"gray69": "rgb(176, 176, 176)", | |
"gray7": "rgb(18, 18, 18)", | |
"gray70": "rgb(179, 179, 179)", | |
"gray71": "rgb(181, 181, 181)", | |
"gray72": "rgb(184, 184, 184)", | |
"gray73": "rgb(186, 186, 186)", | |
"gray74": "rgb(189, 189, 189)", | |
"gray75": "rgb(191, 191, 191)", | |
"gray76": "rgb(194, 194, 194)", | |
"gray77": "rgb(196, 196, 196)", | |
"gray78": "rgb(199, 199, 199)", | |
"gray79": "rgb(201, 201, 201)", | |
"gray8": "rgb(20, 20, 20)", | |
"gray80": "rgb(204, 204, 204)", | |
"gray81": "rgb(207, 207, 207)", | |
"gray82": "rgb(209, 209, 209)", | |
"gray83": "rgb(212, 212, 212)", | |
"gray84": "rgb(214, 214, 214)", | |
"gray85": "rgb(217, 217, 217)", | |
"gray86": "rgb(219, 219, 219)", | |
"gray87": "rgb(222, 222, 222)", | |
"gray88": "rgb(224, 224, 224)", | |
"gray89": "rgb(227, 227, 227)", | |
"gray9": "rgb(23, 23, 23)", | |
"gray90": "rgb(229, 229, 229)", | |
"gray91": "rgb(232, 232, 232)", | |
"gray92": "rgb(235, 235, 235)", | |
"gray93": "rgb(237, 237, 237)", | |
"gray94": "rgb(240, 240, 240)", | |
"gray95": "rgb(242, 242, 242)", | |
"gray96": "rgb(245, 245, 245)", | |
"gray97": "rgb(247, 247, 247)", | |
"gray98": "rgb(250, 250, 250)", | |
"gray99": "rgb(252, 252, 252)", | |
"green": "rgb(0, 255, 0)", | |
"green1": "rgb(0, 255, 0)", | |
"green2": "rgb(0, 238, 0)", | |
"green3": "rgb(0, 205, 0)", | |
"green4": "rgb(0, 139, 0)", | |
"greenyellow": "rgb(173, 255, 47)", | |
"grey": "rgb(190, 190, 190)", | |
"grey0": "rgb(0, 0, 0)", | |
"grey1": "rgb(3, 3, 3)", | |
"grey10": "rgb(26, 26, 26)", | |
"grey100": "rgb(255, 255, 255)", | |
"grey11": "rgb(28, 28, 28)", | |
"grey12": "rgb(31, 31, 31)", | |
"grey13": "rgb(33, 33, 33)", | |
"grey14": "rgb(36, 36, 36)", | |
"grey15": "rgb(38, 38, 38)", | |
"grey16": "rgb(41, 41, 41)", | |
"grey17": "rgb(43, 43, 43)", | |
"grey18": "rgb(46, 46, 46)", | |
"grey19": "rgb(48, 48, 48)", | |
"grey2": "rgb(5, 5, 5)", | |
"grey20": "rgb(51, 51, 51)", | |
"grey21": "rgb(54, 54, 54)", | |
"grey22": "rgb(56, 56, 56)", | |
"grey23": "rgb(59, 59, 59)", | |
"grey24": "rgb(61, 61, 61)", | |
"grey25": "rgb(64, 64, 64)", | |
"grey26": "rgb(66, 66, 66)", | |
"grey27": "rgb(69, 69, 69)", | |
"grey28": "rgb(71, 71, 71)", | |
"grey29": "rgb(74, 74, 74)", | |
"grey3": "rgb(8, 8, 8)", | |
"grey30": "rgb(77, 77, 77)", | |
"grey31": "rgb(79, 79, 79)", | |
"grey32": "rgb(82, 82, 82)", | |
"grey33": "rgb(84, 84, 84)", | |
"grey34": "rgb(87, 87, 87)", | |
"grey35": "rgb(89, 89, 89)", | |
"grey36": "rgb(92, 92, 92)", | |
"grey37": "rgb(94, 94, 94)", | |
"grey38": "rgb(97, 97, 97)", | |
"grey39": "rgb(99, 99, 99)", | |
"grey4": "rgb(10, 10, 10)", | |
"grey40": "rgb(102, 102, 102)", | |
"grey41": "rgb(105, 105, 105)", | |
"grey42": "rgb(107, 107, 107)", | |
"grey43": "rgb(110, 110, 110)", | |
"grey44": "rgb(112, 112, 112)", | |
"grey45": "rgb(115, 115, 115)", | |
"grey46": "rgb(117, 117, 117)", | |
"grey47": "rgb(120, 120, 120)", | |
"grey48": "rgb(122, 122, 122)", | |
"grey49": "rgb(125, 125, 125)", | |
"grey5": "rgb(13, 13, 13)", | |
"grey50": "rgb(127, 127, 127)", | |
"grey51": "rgb(130, 130, 130)", | |
"grey52": "rgb(133, 133, 133)", | |
"grey53": "rgb(135, 135, 135)", | |
"grey54": "rgb(138, 138, 138)", | |
"grey55": "rgb(140, 140, 140)", | |
"grey56": "rgb(143, 143, 143)", | |
"grey57": "rgb(145, 145, 145)", | |
"grey58": "rgb(148, 148, 148)", | |
"grey59": "rgb(150, 150, 150)", | |
"grey6": "rgb(15, 15, 15)", | |
"grey60": "rgb(153, 153, 153)", | |
"grey61": "rgb(156, 156, 156)", | |
"grey62": "rgb(158, 158, 158)", | |
"grey63": "rgb(161, 161, 161)", | |
"grey64": "rgb(163, 163, 163)", | |
"grey65": "rgb(166, 166, 166)", | |
"grey66": "rgb(168, 168, 168)", | |
"grey67": "rgb(171, 171, 171)", | |
"grey68": "rgb(173, 173, 173)", | |
"grey69": "rgb(176, 176, 176)", | |
"grey7": "rgb(18, 18, 18)", | |
"grey70": "rgb(179, 179, 179)", | |
"grey71": "rgb(181, 181, 181)", | |
"grey72": "rgb(184, 184, 184)", | |
"grey73": "rgb(186, 186, 186)", | |
"grey74": "rgb(189, 189, 189)", | |
"grey75": "rgb(191, 191, 191)", | |
"grey76": "rgb(194, 194, 194)", | |
"grey77": "rgb(196, 196, 196)", | |
"grey78": "rgb(199, 199, 199)", | |
"grey79": "rgb(201, 201, 201)", | |
"grey8": "rgb(20, 20, 20)", | |
"grey80": "rgb(204, 204, 204)", | |
"grey81": "rgb(207, 207, 207)", | |
"grey82": "rgb(209, 209, 209)", | |
"grey83": "rgb(212, 212, 212)", | |
"grey84": "rgb(214, 214, 214)", | |
"grey85": "rgb(217, 217, 217)", | |
"grey86": "rgb(219, 219, 219)", | |
"grey87": "rgb(222, 222, 222)", | |
"grey88": "rgb(224, 224, 224)", | |
"grey89": "rgb(227, 227, 227)", | |
"grey9": "rgb(23, 23, 23)", | |
"grey90": "rgb(229, 229, 229)", | |
"grey91": "rgb(232, 232, 232)", | |
"grey92": "rgb(235, 235, 235)", | |
"grey93": "rgb(237, 237, 237)", | |
"grey94": "rgb(240, 240, 240)", | |
"grey95": "rgb(242, 242, 242)", | |
"grey96": "rgb(245, 245, 245)", | |
"grey97": "rgb(247, 247, 247)", | |
"grey98": "rgb(250, 250, 250)", | |
"grey99": "rgb(252, 252, 252)", | |
"honeydew": "rgb(240, 255, 240)", | |
"honeydew1": "rgb(240, 255, 240)", | |
"honeydew2": "rgb(224, 238, 224)", | |
"honeydew3": "rgb(193, 205, 193)", | |
"honeydew4": "rgb(131, 139, 131)", | |
"hotpink": "rgb(255, 105, 180)", | |
"hotpink1": "rgb(255, 110, 180)", | |
"hotpink2": "rgb(238, 106, 167)", | |
"hotpink3": "rgb(205, 96, 144)", | |
"hotpink4": "rgb(139, 58, 98)", | |
"indianred": "rgb(205, 92, 92)", | |
"indianred1": "rgb(255, 106, 106)", | |
"indianred2": "rgb(238, 99, 99)", | |
"indianred3": "rgb(205, 85, 85)", | |
"indianred4": "rgb(139, 58, 58)", | |
"ivory": "rgb(255, 255, 240)", | |
"ivory1": "rgb(255, 255, 240)", | |
"ivory2": "rgb(238, 238, 224)", | |
"ivory3": "rgb(205, 205, 193)", | |
"ivory4": "rgb(139, 139, 131)", | |
"khaki": "rgb(240, 230, 140)", | |
"khaki1": "rgb(255, 246, 143)", | |
"khaki2": "rgb(238, 230, 133)", | |
"khaki3": "rgb(205, 198, 115)", | |
"khaki4": "rgb(139, 134, 78)", | |
"lavender": "rgb(230, 230, 250)", | |
"lavenderblush": "rgb(255, 240, 245)", | |
"lavenderblush1": "rgb(255, 240, 245)", | |
"lavenderblush2": "rgb(238, 224, 229)", | |
"lavenderblush3": "rgb(205, 193, 197)", | |
"lavenderblush4": "rgb(139, 131, 134)", | |
"lawngreen": "rgb(124, 252, 0)", | |
"lemonchiffon": "rgb(255, 250, 205)", | |
"lemonchiffon1": "rgb(255, 250, 205)", | |
"lemonchiffon2": "rgb(238, 233, 191)", | |
"lemonchiffon3": "rgb(205, 201, 165)", | |
"lemonchiffon4": "rgb(139, 137, 112)", | |
"lightblue": "rgb(173, 216, 230)", | |
"lightblue1": "rgb(191, 239, 255)", | |
"lightblue2": "rgb(178, 223, 238)", | |
"lightblue3": "rgb(154, 192, 205)", | |
"lightblue4": "rgb(104, 131, 139)", | |
"lightcoral": "rgb(240, 128, 128)", | |
"lightcyan": "rgb(224, 255, 255)", | |
"lightcyan1": "rgb(224, 255, 255)", | |
"lightcyan2": "rgb(209, 238, 238)", | |
"lightcyan3": "rgb(180, 205, 205)", | |
"lightcyan4": "rgb(122, 139, 139)", | |
"lightgoldenrod": "rgb(238, 221, 130)", | |
"lightgoldenrod1": "rgb(255, 236, 139)", | |
"lightgoldenrod2": "rgb(238, 220, 130)", | |
"lightgoldenrod3": "rgb(205, 190, 112)", | |
"lightgoldenrod4": "rgb(139, 129, 76)", | |
"lightgoldenrodyellow": "rgb(250, 250, 210)", | |
"lightgray": "rgb(211, 211, 211)", | |
"lightgreen": "rgb(144, 238, 144)", | |
"lightgrey": "rgb(211, 211, 211)", | |
"lightpink": "rgb(255, 182, 193)", | |
"lightpink1": "rgb(255, 174, 185)", | |
"lightpink2": "rgb(238, 162, 173)", | |
"lightpink3": "rgb(205, 140, 149)", | |
"lightpink4": "rgb(139, 95, 101)", | |
"lightsalmon": "rgb(255, 160, 122)", | |
"lightsalmon1": "rgb(255, 160, 122)", | |
"lightsalmon2": "rgb(238, 149, 114)", | |
"lightsalmon3": "rgb(205, 129, 98)", | |
"lightsalmon4": "rgb(139, 87, 66)", | |
"lightseagreen": "rgb(32, 178, 170)", | |
"lightskyblue": "rgb(135, 206, 250)", | |
"lightskyblue1": "rgb(176, 226, 255)", | |
"lightskyblue2": "rgb(164, 211, 238)", | |
"lightskyblue3": "rgb(141, 182, 205)", | |
"lightskyblue4": "rgb(96, 123, 139)", | |
"lightslateblue": "rgb(132, 112, 255)", | |
"lightslategray": "rgb(119, 136, 153)", | |
"lightslategrey": "rgb(119, 136, 153)", | |
"lightsteelblue": "rgb(176, 196, 222)", | |
"lightsteelblue1": "rgb(202, 225, 255)", | |
"lightsteelblue2": "rgb(188, 210, 238)", | |
"lightsteelblue3": "rgb(162, 181, 205)", | |
"lightsteelblue4": "rgb(110, 123, 139)", | |
"lightyellow": "rgb(255, 255, 224)", | |
"lightyellow1": "rgb(255, 255, 224)", | |
"lightyellow2": "rgb(238, 238, 209)", | |
"lightyellow3": "rgb(205, 205, 180)", | |
"lightyellow4": "rgb(139, 139, 122)", | |
"limegreen": "rgb(50, 205, 50)", | |
"linen": "rgb(250, 240, 230)", | |
"magenta": "rgb(255, 0, 255)", | |
"magenta1": "rgb(255, 0, 255)", | |
"magenta2": "rgb(238, 0, 238)", | |
"magenta3": "rgb(205, 0, 205)", | |
"magenta4": "rgb(139, 0, 139)", | |
"maroon": "rgb(176, 48, 96)", | |
"maroon1": "rgb(255, 52, 179)", | |
"maroon2": "rgb(238, 48, 167)", | |
"maroon3": "rgb(205, 41, 144)", | |
"maroon4": "rgb(139, 28, 98)", | |
"mediumaquamarine": "rgb(102, 205, 170)", | |
"mediumblue": "rgb(0, 0, 205)", | |
"mediumorchid": "rgb(186, 85, 211)", | |
"mediumorchid1": "rgb(224, 102, 255)", | |
"mediumorchid2": "rgb(209, 95, 238)", | |
"mediumorchid3": "rgb(180, 82, 205)", | |
"mediumorchid4": "rgb(122, 55, 139)", | |
"mediumpurple": "rgb(147, 112, 219)", | |
"mediumpurple1": "rgb(171, 130, 255)", | |
"mediumpurple2": "rgb(159, 121, 238)", | |
"mediumpurple3": "rgb(137, 104, 205)", | |
"mediumpurple4": "rgb(93, 71, 139)", | |
"mediumseagreen": "rgb(60, 179, 113)", | |
"mediumslateblue": "rgb(123, 104, 238)", | |
"mediumspringgreen": "rgb(0, 250, 154)", | |
"mediumturquoise": "rgb(72, 209, 204)", | |
"mediumvioletred": "rgb(199, 21, 133)", | |
"midnightblue": "rgb(25, 25, 112)", | |
"mintcream": "rgb(245, 255, 250)", | |
"mistyrose": "rgb(255, 228, 225)", | |
"mistyrose1": "rgb(255, 228, 225)", | |
"mistyrose2": "rgb(238, 213, 210)", | |
"mistyrose3": "rgb(205, 183, 181)", | |
"mistyrose4": "rgb(139, 125, 123)", | |
"moccasin": "rgb(255, 228, 181)", | |
"navajowhite": "rgb(255, 222, 173)", | |
"navajowhite1": "rgb(255, 222, 173)", | |
"navajowhite2": "rgb(238, 207, 161)", | |
"navajowhite3": "rgb(205, 179, 139)", | |
"navajowhite4": "rgb(139, 121, 94)", | |
"navy": "rgb(0, 0, 128)", | |
"navyblue": "rgb(0, 0, 128)", | |
"oldlace": "rgb(253, 245, 230)", | |
"olivedrab": "rgb(107, 142, 35)", | |
"olivedrab1": "rgb(192, 255, 62)", | |
"olivedrab2": "rgb(179, 238, 58)", | |
"olivedrab3": "rgb(154, 205, 50)", | |
"olivedrab4": "rgb(105, 139, 34)", | |
"orange": "rgb(255, 165, 0)", | |
"orange1": "rgb(255, 165, 0)", | |
"orange2": "rgb(238, 154, 0)", | |
"orange3": "rgb(205, 133, 0)", | |
"orange4": "rgb(139, 90, 0)", | |
"orangered": "rgb(255, 69, 0)", | |
"orangered1": "rgb(255, 69, 0)", | |
"orangered2": "rgb(238, 64, 0)", | |
"orangered3": "rgb(205, 55, 0)", | |
"orangered4": "rgb(139, 37, 0)", | |
"orchid": "rgb(218, 112, 214)", | |
"orchid1": "rgb(255, 131, 250)", | |
"orchid2": "rgb(238, 122, 233)", | |
"orchid3": "rgb(205, 105, 201)", | |
"orchid4": "rgb(139, 71, 137)", | |
"palegoldenrod": "rgb(238, 232, 170)", | |
"palegreen": "rgb(152, 251, 152)", | |
"palegreen1": "rgb(154, 255, 154)", | |
"palegreen2": "rgb(144, 238, 144)", | |
"palegreen3": "rgb(124, 205, 124)", | |
"palegreen4": "rgb(84, 139, 84)", | |
"paleturquoise": "rgb(175, 238, 238)", | |
"paleturquoise1": "rgb(187, 255, 255)", | |
"paleturquoise2": "rgb(174, 238, 238)", | |
"paleturquoise3": "rgb(150, 205, 205)", | |
"paleturquoise4": "rgb(102, 139, 139)", | |
"palevioletred": "rgb(219, 112, 147)", | |
"palevioletred1": "rgb(255, 130, 171)", | |
"palevioletred2": "rgb(238, 121, 159)", | |
"palevioletred3": "rgb(205, 104, 137)", | |
"palevioletred4": "rgb(139, 71, 93)", | |
"papayawhip": "rgb(255, 239, 213)", | |
"peachpuff": "rgb(255, 218, 185)", | |
"peachpuff1": "rgb(255, 218, 185)", | |
"peachpuff2": "rgb(238, 203, 173)", | |
"peachpuff3": "rgb(205, 175, 149)", | |
"peachpuff4": "rgb(139, 119, 101)", | |
"peru": "rgb(205, 133, 63)", | |
"pink": "rgb(255, 192, 203)", | |
"pink1": "rgb(255, 181, 197)", | |
"pink2": "rgb(238, 169, 184)", | |
"pink3": "rgb(205, 145, 158)", | |
"pink4": "rgb(139, 99, 108)", | |
"plum": "rgb(221, 160, 221)", | |
"plum1": "rgb(255, 187, 255)", | |
"plum2": "rgb(238, 174, 238)", | |
"plum3": "rgb(205, 150, 205)", | |
"plum4": "rgb(139, 102, 139)", | |
"powderblue": "rgb(176, 224, 230)", | |
"purple": "rgb(160, 32, 240)", | |
"purple1": "rgb(155, 48, 255)", | |
"purple2": "rgb(145, 44, 238)", | |
"purple3": "rgb(125, 38, 205)", | |
"purple4": "rgb(85, 26, 139)", | |
"red": "rgb(255, 0, 0)", | |
"red1": "rgb(255, 0, 0)", | |
"red2": "rgb(238, 0, 0)", | |
"red3": "rgb(205, 0, 0)", | |
"red4": "rgb(139, 0, 0)", | |
"rosybrown": "rgb(188, 143, 143)", | |
"rosybrown1": "rgb(255, 193, 193)", | |
"rosybrown2": "rgb(238, 180, 180)", | |
"rosybrown3": "rgb(205, 155, 155)", | |
"rosybrown4": "rgb(139, 105, 105)", | |
"royalblue": "rgb(65, 105, 225)", | |
"royalblue1": "rgb(72, 118, 255)", | |
"royalblue2": "rgb(67, 110, 238)", | |
"royalblue3": "rgb(58, 95, 205)", | |
"royalblue4": "rgb(39, 64, 139)", | |
"saddlebrown": "rgb(139, 69, 19)", | |
"salmon": "rgb(250, 128, 114)", | |
"salmon1": "rgb(255, 140, 105)", | |
"salmon2": "rgb(238, 130, 98)", | |
"salmon3": "rgb(205, 112, 84)", | |
"salmon4": "rgb(139, 76, 57)", | |
"sandybrown": "rgb(244, 164, 96)", | |
"seagreen": "rgb(46, 139, 87)", | |
"seagreen1": "rgb(84, 255, 159)", | |
"seagreen2": "rgb(78, 238, 148)", | |
"seagreen3": "rgb(67, 205, 128)", | |
"seagreen4": "rgb(46, 139, 87)", | |
"seashell": "rgb(255, 245, 238)", | |
"seashell1": "rgb(255, 245, 238)", | |
"seashell2": "rgb(238, 229, 222)", | |
"seashell3": "rgb(205, 197, 191)", | |
"seashell4": "rgb(139, 134, 130)", | |
"sienna": "rgb(160, 82, 45)", | |
"sienna1": "rgb(255, 130, 71)", | |
"sienna2": "rgb(238, 121, 66)", | |
"sienna3": "rgb(205, 104, 57)", | |
"sienna4": "rgb(139, 71, 38)", | |
"skyblue": "rgb(135, 206, 235)", | |
"skyblue1": "rgb(135, 206, 255)", | |
"skyblue2": "rgb(126, 192, 238)", | |
"skyblue3": "rgb(108, 166, 205)", | |
"skyblue4": "rgb(74, 112, 139)", | |
"slateblue": "rgb(106, 90, 205)", | |
"slateblue1": "rgb(131, 111, 255)", | |
"slateblue2": "rgb(122, 103, 238)", | |
"slateblue3": "rgb(105, 89, 205)", | |
"slateblue4": "rgb(71, 60, 139)", | |
"slategray": "rgb(112, 128, 144)", | |
"slategray1": "rgb(198, 226, 255)", | |
"slategray2": "rgb(185, 211, 238)", | |
"slategray3": "rgb(159, 182, 205)", | |
"slategray4": "rgb(108, 123, 139)", | |
"slategrey": "rgb(112, 128, 144)", | |
"snow": "rgb(255, 250, 250)", | |
"snow1": "rgb(255, 250, 250)", | |
"snow2": "rgb(238, 233, 233)", | |
"snow3": "rgb(205, 201, 201)", | |
"snow4": "rgb(139, 137, 137)", | |
"springgreen": "rgb(0, 255, 127)", | |
"springgreen1": "rgb(0, 255, 127)", | |
"springgreen2": "rgb(0, 238, 118)", | |
"springgreen3": "rgb(0, 205, 102)", | |
"springgreen4": "rgb(0, 139, 69)", | |
"steelblue": "rgb(70, 130, 180)", | |
"steelblue1": "rgb(99, 184, 255)", | |
"steelblue2": "rgb(92, 172, 238)", | |
"steelblue3": "rgb(79, 148, 205)", | |
"steelblue4": "rgb(54, 100, 139)", | |
"tan": "rgb(210, 180, 140)", | |
"tan1": "rgb(255, 165, 79)", | |
"tan2": "rgb(238, 154, 73)", | |
"tan3": "rgb(205, 133, 63)", | |
"tan4": "rgb(139, 90, 43)", | |
"thistle": "rgb(216, 191, 216)", | |
"thistle1": "rgb(255, 225, 255)", | |
"thistle2": "rgb(238, 210, 238)", | |
"thistle3": "rgb(205, 181, 205)", | |
"thistle4": "rgb(139, 123, 139)", | |
"tomato": "rgb(255, 99, 71)", | |
"tomato1": "rgb(255, 99, 71)", | |
"tomato2": "rgb(238, 92, 66)", | |
"tomato3": "rgb(205, 79, 57)", | |
"tomato4": "rgb(139, 54, 38)", | |
"turquoise": "rgb(64, 224, 208)", | |
"turquoise1": "rgb(0, 245, 255)", | |
"turquoise2": "rgb(0, 229, 238)", | |
"turquoise3": "rgb(0, 197, 205)", | |
"turquoise4": "rgb(0, 134, 139)", | |
"violet": "rgb(238, 130, 238)", | |
"violetred": "rgb(208, 32, 144)", | |
"violetred1": "rgb(255, 62, 150)", | |
"violetred2": "rgb(238, 58, 140)", | |
"violetred3": "rgb(205, 50, 120)", | |
"violetred4": "rgb(139, 34, 82)", | |
"wheat": "rgb(245, 222, 179)", | |
"wheat1": "rgb(255, 231, 186)", | |
"wheat2": "rgb(238, 216, 174)", | |
"wheat3": "rgb(205, 186, 150)", | |
"wheat4": "rgb(139, 126, 102)", | |
"white": "rgb(255, 255, 255)", | |
"whitesmoke": "rgb(245, 245, 245)", | |
"yellow": "rgb(255, 255, 0)", | |
"yellow1": "rgb(255, 255, 0)", | |
"yellow2": "rgb(238, 238, 0)", | |
"yellow3": "rgb(205, 205, 0)", | |
"yellow4": "rgb(139, 139, 0)", | |
"yellowgreen": "rgb(154, 205, 50)" | |
}; | |
// SOURCE FILE: libdot/js/lib_f.js | |
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
'use strict'; | |
/** | |
* Grab bag of utility functions. | |
*/ | |
lib.f = {}; | |
/** | |
* Replace variable references in a string. | |
* | |
* Variables are of the form %FUNCTION(VARNAME). FUNCTION is an optional | |
* escape function to apply to the value. | |
* | |
* For example | |
* lib.f.replaceVars("%(greeting), %encodeURIComponent(name)", | |
* { greeting: "Hello", | |
* name: "Google+" }); | |
* | |
* Will result in "Hello, Google%2B". | |
*/ | |
lib.f.replaceVars = function(str, vars) { | |
return str.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(match, fn, varname) { | |
if (typeof vars[varname] == 'undefined') | |
throw 'Unknown variable: ' + varname; | |
var rv = vars[varname]; | |
if (fn in lib.f.replaceVars.functions) { | |
rv = lib.f.replaceVars.functions[fn](rv); | |
} else if (fn) { | |
throw 'Unknown escape function: ' + fn; | |
} | |
return rv; | |
}); | |
}; | |
/** | |
* Functions that can be used with replaceVars. | |
* | |
* Clients can add to this list to extend lib.f.replaceVars(). | |
*/ | |
lib.f.replaceVars.functions = { | |
encodeURI: encodeURI, | |
encodeURIComponent: encodeURIComponent, | |
escapeHTML: function(str) { | |
var map = { | |
'<': '<', | |
'>': '>', | |
'&': '&', | |
'"': '"', | |
"'": ''' | |
}; | |
return str.replace(/[<>&\"\']/g, function(m) { return map[m] }); | |
} | |
}; | |
/** | |
* Get the list of accepted UI languages. | |
* | |
* @param {function(Array)} callback Function to invoke with the results. The | |
* parameter is a list of locale names. | |
*/ | |
lib.f.getAcceptLanguages = function(callback) { | |
if (window.chrome && chrome.i18n) { | |
chrome.i18n.getAcceptLanguages(callback); | |
} else { | |
setTimeout(function() { | |
callback([navigator.language.replace(/-/g, '_')]); | |
}, 0); | |
} | |
}; | |
/** | |
* Parse a query string into a hash. | |
* | |
* This takes a url query string in the form 'name1=value&name2=value' and | |
* converts it into an object of the form { name1: 'value', name2: 'value' }. | |
* If a given name appears multiple times in the query string, only the | |
* last value will appear in the result. | |
* | |
* Names and values are passed through decodeURIComponent before being added | |
* to the result object. | |
* | |
* @param {string} queryString The string to parse. If it starts with a | |
* leading '?', the '?' will be ignored. | |
*/ | |
lib.f.parseQuery = function(queryString) { | |
if (queryString.substr(0, 1) == '?') | |
queryString = queryString.substr(1); | |
var rv = {}; | |
var pairs = queryString.split('&'); | |
for (var i = 0; i < pairs.length; i++) { | |
var pair = pairs[i].split('='); | |
rv[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); | |
} | |
return rv; | |
}; | |
lib.f.getURL = function(path) { | |
if (window.chrome && chrome.runtime && chrome.runtime.getURL) | |
return chrome.runtime.getURL(path); | |
return path; | |
}; | |
/** | |
* Clamp a given integer to a specified range. | |
* | |
* @param {integer} v The value to be clamped. | |
* @param {integer} min The minimum acceptable value. | |
* @param {integer} max The maximum acceptable value. | |
*/ | |
lib.f.clamp = function(v, min, max) { | |
if (v < min) | |
return min; | |
if (v > max) | |
return max; | |
return v; | |
}; | |
/** | |
* Left pad a string to a given length using a given character. | |
* | |
* @param {string} str The string to pad. | |
* @param {integer} length The desired length. | |
* @param {string} opt_ch The optional padding character, defaults to ' '. | |
* @return {string} The padded string. | |
*/ | |
lib.f.lpad = function(str, length, opt_ch) { | |
str = String(str); | |
opt_ch = opt_ch || ' '; | |
while (str.length < length) | |
str = opt_ch + str; | |
return str; | |
}; | |
/** | |
* Left pad a number to a given length with leading zeros. | |
* | |
* @param {string|integer} number The number to pad. | |
* @param {integer} length The desired length. | |
* @return {string} The padded number as a string. | |
*/ | |
lib.f.zpad = function(number, length) { | |
return lib.f.lpad(number, length, '0'); | |
}; | |
/** | |
* Return a string containing a given number of space characters. | |
* | |
* This method maintains a static cache of the largest amount of whitespace | |
* ever requested. It shouldn't be used to generate an insanely huge amount of | |
* whitespace. | |
* | |
* @param {integer} length The desired amount of whitespace. | |
* @param {string} A string of spaces of the requested length. | |
*/ | |
lib.f.getWhitespace = function(length) { | |
if (length == 0) | |
return ''; | |
var f = this.getWhitespace; | |
if (!f.whitespace) | |
f.whitespace = ' '; | |
while (length > f.whitespace.length) { | |
f.whitespace += f.whitespace; | |
} | |
return f.whitespace.substr(0, length); | |
}; | |
/** | |
* Ensure that a function is called within a certain time limit. | |
* | |
* Simple usage looks like this... | |
* | |
* lib.registerInit(lib.f.alarm(onInit)); | |
* | |
* This will log a warning to the console if onInit() is not invoked within | |
* 5 seconds. | |
* | |
* If you're performing some operation that may take longer than 5 seconds you | |
* can pass a duration in milliseconds as the optional second parameter. | |
* | |
* If you pass a string identifier instead of a callback function, you'll get a | |
* wrapper generator rather than a single wrapper. Each call to the | |
* generator will return a wrapped version of the callback wired to | |
* a shared timeout. This is for cases where you want to ensure that at least | |
* one of a set of callbacks is invoked before a timeout expires. | |
* | |
* var alarm = lib.f.alarm('fetch object'); | |
* lib.foo.fetchObject(alarm(onSuccess), alarm(onFailure)); | |
* | |
* @param {function(*)} callback The function to wrap in an alarm. | |
* @param {int} opt_ms Optional number of milliseconds to wait before raising | |
* an alarm. Default is 5000 (5 seconds). | |
* @return {function} If callback is a function then the return value will be | |
* the wrapped callback. If callback is a string then the return value will | |
* be a function that generates new wrapped callbacks. | |
*/ | |
lib.f.alarm = function(callback, opt_ms) { | |
var ms = opt_ms || 5 * 1000; | |
var stack = lib.f.getStack(1); | |
return (function() { | |
// This outer function is called immediately. It's here to capture a new | |
// scope for the timeout variable. | |
// The 'timeout' variable is shared by this timeout function, and the | |
// callback wrapper. | |
var timeout = setTimeout(function() { | |
var name = (typeof callback == 'string') ? name : callback.name; | |
name = name ? (': ' + name) : ''; | |
console.warn('lib.f.alarm: timeout expired: ' + (ms / 1000) + 's' + name); | |
console.log(stack); | |
timeout = null; | |
}, ms); | |
var wrapperGenerator = function(callback) { | |
return function() { | |
if (timeout) { | |
clearTimeout(timeout); | |
timeout = null; | |
} | |
return callback.apply(null, arguments); | |
} | |
}; | |
if (typeof callback == 'string') | |
return wrapperGenerator; | |
return wrapperGenerator(callback); | |
})(); | |
}; | |
/** | |
* Return the current call stack after skipping a given number of frames. | |
* | |
* This method is intended to be used for debugging only. It returns an | |
* Object instead of an Array, because the console stringifies arrays by | |
* default and that's not what we want. | |
* | |
* A typical call might look like... | |
* | |
* console.log('Something wicked this way came', lib.f.getStack()); | |
* // Notice the comma ^ | |
* | |
* This would print the message to the js console, followed by an object | |
* which can be clicked to reveal the stack. | |
* | |
* @param {number} opt_ignoreFrames The optional number of stack frames to | |
* ignore. The actual 'getStack' call is always ignored. | |
*/ | |
lib.f.getStack = function(opt_ignoreFrames) { | |
var ignoreFrames = opt_ignoreFrames ? opt_ignoreFrames + 2 : 2; | |
var stackArray; | |
try { | |
throw new Error(); | |
} catch (ex) { | |
stackArray = ex.stack.split('\n'); | |
} | |
var stackObject = {}; | |
for (var i = ignoreFrames; i < stackArray.length; i++) { | |
stackObject[i - ignoreFrames] = stackArray[i].replace(/^\s*at\s+/, ''); | |
} | |
return stackObject; | |
}; | |
/** | |
* Divides the two numbers and floors the results, unless the remainder is less | |
* than an incredibly small value, in which case it returns the ceiling. | |
* This is useful when the number are truncated approximations of longer | |
* values, and so doing division with these numbers yields a result incredibly | |
* close to a whole number. | |
* | |
* @param {number} numerator | |
* @param {number} denominator | |
* @return {number} | |
*/ | |
lib.f.smartFloorDivide = function(numerator, denominator) { | |
var val = numerator / denominator; | |
var ceiling = Math.ceil(val); | |
if (ceiling - val < .0001) { | |
return ceiling; | |
} else { | |
return Math.floor(val); | |
} | |
}; | |
// SOURCE FILE: libdot/js/lib_message_manager.js | |
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
'use strict'; | |
/** | |
* MessageManager class handles internationalized strings. | |
* | |
* Note: chrome.i18n isn't sufficient because... | |
* 1. There's a bug in chrome that makes it unavailable in iframes: | |
* http://crbug.com/130200 | |
* 2. The client code may not be packaged in a Chrome extension. | |
* 3. The client code may be part of a library packaged in a third-party | |
* Chrome extension. | |
* | |
* @param {Array} languages List of languages to load, in the order they | |
* should be loaded. Newer messages replace older ones. 'en' is | |
* automatically added as the first language if it is not already present. | |
*/ | |
lib.MessageManager = function(languages) { | |
this.languages_ = languages.map( | |
function(el) { return el.replace(/-/g, '_') }); | |
if (this.languages_.indexOf('en') == -1) | |
this.languages_.unshift('en'); | |
this.messages = {}; | |
}; | |
/** | |
* Add message definitions to the message manager. | |
* | |
* This takes an object of the same format of a Chrome messages.json file. See | |
* <http://code.google.com/chrome/extensions/i18n-messages.html>. | |
*/ | |
lib.MessageManager.prototype.addMessages = function(defs) { | |
for (var key in defs) { | |
var def = defs[key]; | |
if (!def.placeholders) { | |
this.messages[key] = def.message; | |
} else { | |
// Replace "$NAME$" placeholders with "$1", etc. | |
this.messages[key] = def.message.replace( | |
/\$([a-z][^\s\$]+)\$/ig, | |
function(m, name) { | |
return defs[key].placeholders[name.toLowerCase()].content; | |
}); | |
} | |
} | |
}; | |
/** | |
* Load the first available language message bundle. | |
* | |
* @param {string} pattern A url pattern containing a "$1" where the locale | |
* name should go. | |
* @param {function(Array,Array)} onComplete Function to be called when loading | |
* is complete. The two arrays are the list of successful and failed | |
* locale names. If the first parameter is length 0, no locales were | |
* loaded. | |
*/ | |
lib.MessageManager.prototype.findAndLoadMessages = function( | |
pattern, onComplete) { | |
var languages = this.languages_.concat(); | |
var loaded = []; | |
var failed = []; | |
function onLanguageComplete(state) { | |
if (state) { | |
loaded = languages.shift(); | |
} else { | |
failed = languages.shift(); | |
} | |
if (languages.length) { | |
tryNextLanguage(); | |
} else { | |
onComplete(loaded, failed); | |
} | |
} | |
var tryNextLanguage = function() { | |
this.loadMessages(this.replaceReferences(pattern, languages), | |
onLanguageComplete.bind(this, true), | |
onLanguageComplete.bind(this, false)); | |
}.bind(this); | |
tryNextLanguage(); | |
}; | |
/** | |
* Load messages from a messages.json file. | |
*/ | |
lib.MessageManager.prototype.loadMessages = function( | |
url, onSuccess, opt_onError) { | |
var xhr = new XMLHttpRequest(); | |
xhr.onloadend = function() { | |
if (xhr.status != 200) { | |
if (opt_onError) | |
opt_onError(xhr.status); | |
return; | |
} | |
this.addMessages(JSON.parse(xhr.responseText)); | |
onSuccess(); | |
}.bind(this); | |
xhr.open('GET', url); | |
xhr.send(); | |
}; | |
/** | |
* Replace $1...$n references with the elements of the args array. | |
* | |
* @param {string} msg String containing the message and argument references. | |
* @param {Array} args Array containing the argument values. | |
*/ | |
lib.MessageManager.replaceReferences = function(msg, args) { | |
return msg.replace(/\$(\d+)/g, function (m, index) { | |
return args[index - 1]; | |
}); | |
}; | |
/** | |
* Per-instance copy of replaceReferences. | |
*/ | |
lib.MessageManager.prototype.replaceReferences = | |
lib.MessageManager.replaceReferences; | |
/** | |
* Get a message by name, optionally replacing arguments too. | |
* | |
* @param {string} msgname String containing the name of the message to get. | |
* @param {Array} opt_args Optional array containing the argument values. | |
* @param {string} opt_default Optional value to return if the msgname is not | |
* found. Returns the message name by default. | |
*/ | |
lib.MessageManager.prototype.get = function(msgname, opt_args, opt_default) { | |
var message; | |
if (msgname in this.messages) { | |
message = this.messages[msgname]; | |
} else { | |
if (window.chrome.i18n) | |
message = chrome.i18n.getMessage(msgname); | |
if (!message) { | |
console.warn('Unknown message: ' + msgname); | |
return (typeof opt_default == 'undefined') ? msgname : opt_default; | |
} | |
} | |
if (!opt_args) | |
return message; | |
if (!(opt_args instanceof Array)) | |
opt_args = [opt_args]; | |
return this.replaceReferences(message, opt_args); | |
}; | |
/** | |
* Process all of the "i18n" html attributes found in a given dom fragment. | |
* | |
* Each i18n attribute should contain a JSON object. The keys are taken to | |
* be attribute names, and the values are message names. | |
* | |
* If the JSON object has a "_" (underscore) key, it's value is used as the | |
* textContent of the element. | |
* | |
* Message names can refer to other attributes on the same element with by | |
* prefixing with a dollar sign. For example... | |
* | |
* <button id='send-button' | |
* i18n='{"aria-label": "$id", "_": "SEND_BUTTON_LABEL"}' | |
* ></button> | |
* | |
* The aria-label message name will be computed as "SEND_BUTTON_ARIA_LABEL". | |
* Notice that the "id" attribute was appended to the target attribute, and | |
* the result converted to UPPER_AND_UNDER style. | |
*/ | |
lib.MessageManager.prototype.processI18nAttributes = function(dom) { | |
// Convert the "lower-and-dashes" attribute names into | |
// "UPPER_AND_UNDER" style. | |
function thunk(str) { return str.replace(/-/g, '_').toUpperCase() } | |
var nodes = dom.querySelectorAll('[i18n]'); | |
for (var i = 0; i < nodes.length; i++) { | |
var node = nodes[i]; | |
var i18n = node.getAttribute('i18n'); | |
if (!i18n) | |
continue; | |
try { | |
i18n = JSON.parse(i18n); | |
} catch (ex) { | |
console.error('Can\'t parse ' + node.tagName + '#' + node.id + ': ' + | |
i18n); | |
throw ex; | |
} | |
for (var key in i18n) { | |
var msgname = i18n[key]; | |
if (msgname.substr(0, 1) == '$') | |
msgname = thunk(node.getAttribute(msgname.substr(1)) + '_' + key); | |
var msg = this.get(msgname); | |
if (key == '_') { | |
node.textContent = msg; | |
} else { | |
node.setAttribute(key, msg); | |
} | |
} | |
} | |
}; | |
// SOURCE FILE: libdot/js/lib_preference_manager.js | |
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
'use strict'; | |
/** | |
* Constructor for lib.PreferenceManager objects. | |
* | |
* These objects deal with persisting changes to stable storage and notifying | |
* consumers when preferences change. | |
* | |
* It is intended that the backing store could be something other than HTML5 | |
* storage, but there aren't any use cases at the moment. In the future there | |
* may be a chrome api to store sync-able name/value pairs, and we'd want | |
* that. | |
* | |
* @param {lib.Storage.*} storage The storage object to use as a backing | |
* store. | |
* @param {string} opt_prefix The optional prefix to be used for all preference | |
* names. The '/' character should be used to separate levels of heirarchy, | |
* if you're going to have that kind of thing. If provided, the prefix | |
* should start with a '/'. If not provided, it defaults to '/'. | |
*/ | |
lib.PreferenceManager = function(storage, opt_prefix) { | |
this.storage = storage; | |
this.storageObserver_ = this.onStorageChange_.bind(this); | |
this.isActive_ = false; | |
this.activate(); | |
this.trace = false; | |
var prefix = opt_prefix || '/'; | |
if (prefix.substr(prefix.length - 1) != '/') | |
prefix += '/'; | |
this.prefix = prefix; | |
this.prefRecords_ = {}; | |
this.globalObservers_ = []; | |
this.childFactories_ = {}; | |
// Map of list-name to {map of child pref managers} | |
// As in... | |
// | |
// this.childLists_ = { | |
// 'profile-ids': { | |
// 'one': PreferenceManager, | |
// 'two': PreferenceManager, | |
// ... | |
// }, | |
// | |
// 'frob-ids': { | |
// ... | |
// } | |
// } | |
this.childLists_ = {}; | |
}; | |
/** | |
* Used internally to indicate that the current value of the preference should | |
* be taken from the default value defined with the preference. | |
* | |
* Equality tests against this value MUST use '===' or '!==' to be accurate. | |
*/ | |
lib.PreferenceManager.prototype.DEFAULT_VALUE = new String('DEFAULT'); | |
/** | |
* An individual preference. | |
* | |
* These objects are managed by the PreferenceManager, you shoudn't need to | |
* handle them directly. | |
*/ | |
lib.PreferenceManager.Record = function(name, defaultValue) { | |
this.name = name; | |
this.defaultValue = defaultValue; | |
this.currentValue = this.DEFAULT_VALUE; | |
this.observers = []; | |
}; | |
/** | |
* A local copy of the DEFAULT_VALUE constant to make it less verbose. | |
*/ | |
lib.PreferenceManager.Record.prototype.DEFAULT_VALUE = | |
lib.PreferenceManager.prototype.DEFAULT_VALUE; | |
/** | |
* Register a callback to be invoked when this preference changes. | |
* | |
* @param {function(value, string, lib.PreferenceManager} observer The function | |
* to invoke. It will receive the new value, the name of the preference, | |
* and a reference to the PreferenceManager as parameters. | |
*/ | |
lib.PreferenceManager.Record.prototype.addObserver = function(observer) { | |
this.observers.push(observer); | |
}; | |
/** | |
* Unregister an observer callback. | |
* | |
* @param {function} observer A previously registered callback. | |
*/ | |
lib.PreferenceManager.Record.prototype.removeObserver = function(observer) { | |
var i = this.observers.indexOf(observer); | |
if (i >= 0) | |
this.observers.splice(i, 1); | |
}; | |
/** | |
* Fetch the value of this preference. | |
*/ | |
lib.PreferenceManager.Record.prototype.get = function() { | |
if (this.currentValue === this.DEFAULT_VALUE) { | |
if (/^(string|number)$/.test(typeof this.defaultValue)) | |
return this.defaultValue; | |
if (typeof this.defaultValue == 'object') { | |
// We want to return a COPY of the default value so that users can | |
// modify the array or object without changing the default value. | |
return JSON.parse(JSON.stringify(this.defaultValue)); | |
} | |
return this.defaultValue; | |
} | |
return this.currentValue; | |
}; | |
/** | |
* Stop this preference manager from tracking storage changes. | |
* | |
* Call this if you're going to swap out one preference manager for another so | |
* that you don't get notified about irrelevant changes. | |
*/ | |
lib.PreferenceManager.prototype.deactivate = function() { | |
if (!this.isActive_) | |
throw new Error('Not activated'); | |
this.isActive_ = false; | |
this.storage.removeObserver(this.storageObserver_); | |
}; | |
/** | |
* Start tracking storage changes. | |
* | |
* If you previously deactivated this preference manager, you can reactivate it | |
* with this method. You don't need to call this at initialization time, as | |
* it's automatically called as part of the constructor. | |
*/ | |
lib.PreferenceManager.prototype.activate = function() { | |
if (this.isActive_) | |
throw new Error('Already activated'); | |
this.isActive_ = true; | |
this.storage.addObserver(this.storageObserver_); | |
}; | |
/** | |
* Read the backing storage for these preferences. | |
* | |
* You should do this once at initialization time to prime the local cache | |
* of preference values. The preference manager will monitor the backing | |
* storage for changes, so you should not need to call this more than once. | |
* | |
* This function recursively reads storage for all child preference managers as | |
* well. | |
* | |
* This function is asynchronous, if you need to read preference values, you | |
* *must* wait for the callback. | |
* | |
* @param {function()} opt_callback Optional function to invoke when the read | |
* has completed. | |
*/ | |
lib.PreferenceManager.prototype.readStorage = function(opt_callback) { | |
var pendingChildren = 0; | |
function onChildComplete() { | |
if (--pendingChildren == 0 && opt_callback) | |
opt_callback(); | |
} | |
var keys = Object.keys(this.prefRecords_).map( | |
function(el) { return this.prefix + el }.bind(this)); | |
if (this.trace) | |
console.log('Preferences read: ' + this.prefix); | |
this.storage.getItems(keys, function(items) { | |
var prefixLength = this.prefix.length; | |
for (var key in items) { | |
var value = items[key]; | |
var name = key.substr(prefixLength); | |
var needSync = (name in this.childLists_ && | |
(JSON.stringify(value) != | |
JSON.stringify(this.prefRecords_[name].currentValue))); | |
this.prefRecords_[name].currentValue = value; | |
if (needSync) { | |
pendingChildren++; | |
this.syncChildList(name, onChildComplete); | |
} | |
} | |
if (pendingChildren == 0 && opt_callback) | |
setTimeout(opt_callback); | |
}.bind(this)); | |
}; | |
/** | |
* Define a preference. | |
* | |
* This registers a name, default value, and onChange handler for a preference. | |
* | |
* @param {string} name The name of the preference. This will be prefixed by | |
* the prefix of this PreferenceManager before written to local storage. | |
* @param {string|number|boolean|Object|Array|null} value The default value of | |
* this preference. Anything that can be represented in JSON is a valid | |
* default value. | |
* @param {function(value, string, lib.PreferenceManager} opt_observer A | |
* function to invoke when the preference changes. It will receive the new | |
* value, the name of the preference, and a reference to the | |
* PreferenceManager as parameters. | |
*/ | |
lib.PreferenceManager.prototype.definePreference = function( | |
name, value, opt_onChange) { | |
var record = this.prefRecords_[name]; | |
if (record) { | |
this.changeDefault(name, value); | |
} else { | |
record = this.prefRecords_[name] = | |
new lib.PreferenceManager.Record(name, value); | |
} | |
if (opt_onChange) | |
record.addObserver(opt_onChange); | |
}; | |
/** | |
* Define multiple preferences with a single function call. | |
* | |
* @param {Array} defaults An array of 3-element arrays. Each three element | |
* array should contain the [key, value, onChange] parameters for a | |
* preference. | |
*/ | |
lib.PreferenceManager.prototype.definePreferences = function(defaults) { | |
for (var i = 0; i < defaults.length; i++) { | |
this.definePreference(defaults[i][0], defaults[i][1], defaults[i][2]); | |
} | |
}; | |
/** | |
* Define an ordered list of child preferences. | |
* | |
* Child preferences are different from just storing an array of JSON objects | |
* in that each child is an instance of a preference manager. This means you | |
* can observe changes to individual child preferences, and get some validation | |
* that you're not reading or writing to an undefined child preference value. | |
* | |
* @param {string} listName A name for the list of children. This must be | |
* unique in this preference manager. The listName will become a | |
* preference on this PreferenceManager used to store the ordered list of | |
* child ids. It is also used in get/add/remove operations to identify the | |
* list of children to operate on. | |
* @param {function} childFactory A function that will be used to generate | |
* instances of these childred. The factory function will receive the | |
* parent lib.PreferenceManager object and a unique id for the new child | |
* preferences. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment