1 // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2 //
  3 // Licensed under the Apache License, Version 2.0 (the "License");
  4 // you may not use this file except in compliance with the License.
  5 // You may obtain a copy of the License at
  6 //
  7 //      http://www.apache.org/licenses/LICENSE-2.0
  8 //
  9 // Unless required by applicable law or agreed to in writing, software
 10 // distributed under the License is distributed on an "AS-IS" BASIS,
 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 // See the License for the specific language governing permissions and
 13 // limitations under the License.
 14 
 15 /**
 16  * @fileoverview Bootstrap for the Google JS Library (Closure).
 17  *
 18  * In uncompiled mode base.js will write out Closure's deps file, unless the
 19  * global <code>CLOSURE_NO_DEPS</code> is set to true.  This allows projects to
 20  * include their own deps file(s) from different locations.
 21  *
 22 *
 23 *
 24  */
 25 
 26 /**
 27  * @define {boolean} Overridden to true by the compiler when --closure_pass
 28  *     or --mark_as_compiled is specified.
 29  */
 30 var COMPILED = false;
 31 
 32 
 33 /**
 34  * Base namespace for the Closure library.  Checks to see goog is
 35  * already defined in the current scope before assigning to prevent
 36  * clobbering if base.js is loaded more than once.
 37  */
 38 var goog = goog || {}; // Check to see if already defined in current scope
 39 
 40 
 41 /**
 42  * Reference to the global context.  In most cases this will be 'window'.
 43  */
 44 goog.global = this;
 45 
 46 
 47 /**
 48  * @define {boolean} DEBUG is provided as a convenience so that debugging code
 49  * that should not be included in a production js_binary can be easily stripped
 50  * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most
 51  * toString() methods should be declared inside an "if (goog.DEBUG)" conditional
 52  * because they are generally used for debugging purposes and it is difficult
 53  * for the JSCompiler to statically determine whether they are used.
 54  */
 55 goog.DEBUG = true;
 56 
 57 
 58 /**
 59  * @define {string} LOCALE defines the locale being used for compilation. It is
 60  * used to select locale specific data to be compiled in js binary. BUILD rule
 61  * can specify this value by "--define goog.LOCALE=<locale_name>" as JSCompiler
 62  * option.
 63  *
 64  * Take into account that the locale code format is important. You should use
 65  * the canonical Unicode format with hyphen as a delimiter. Language must be
 66  * lowercase, Language Script - Capitalized, Region - UPPERCASE.
 67  * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.
 68  *
 69  * See more info about locale codes here:
 70  * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers
 71  *
 72  * For language codes you should use values defined by ISO 693-1. See it here
 73  * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from
 74  * this rule: the Hebrew language. For legacy reasons the old code (iw) should
 75  * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.
 76  */
 77 goog.LOCALE = 'en';  // default to en
 78 
 79 
 80 /**
 81  * Indicates whether or not we can call 'eval' directly to eval code in the
 82  * global scope. Set to a Boolean by the first call to goog.globalEval (which
 83  * empirically tests whether eval works for globals). @see goog.globalEval
 84  * @type {?boolean}
 85  * @private
 86  */
 87 goog.evalWorksForGlobals_ = null;
 88 
 89 
 90 /**
 91  * Creates object stubs for a namespace. When present in a file, goog.provide
 92  * also indicates that the file defines the indicated object. Calls to
 93  * goog.provide are resolved by the compiler if --closure_pass is set.
 94  * @param {string} name name of the object that this file defines.
 95  */
 96 goog.provide = function(name) {
 97   if (!COMPILED) {
 98     // Ensure that the same namespace isn't provided twice. This is intended
 99     // to teach new developers that 'goog.provide' is effectively a variable
100     // declaration. And when JSCompiler transforms goog.provide into a real
101     // variable declaration, the compiled JS should work the same as the raw
102     // JS--even when the raw JS uses goog.provide incorrectly.
103     if (goog.getObjectByName(name) && !goog.implicitNamespaces_[name]) {
104       throw Error('Namespace "' + name + '" already declared.');
105     }
106 
107     var namespace = name;
108     while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
109       goog.implicitNamespaces_[namespace] = true;
110     }
111   }
112 
113   goog.exportPath_(name);
114 };
115 
116 
117 if (!COMPILED) {
118   /**
119    * Namespaces implicitly defined by goog.provide. For example,
120    * goog.provide('goog.events.Event') implicitly declares
121    * that 'goog' and 'goog.events' must be namespaces.
122    *
123    * @type {Object}
124    * @private
125    */
126   goog.implicitNamespaces_ = {};
127 }
128 
129 
130 /**
131  * Builds an object structure for the provided namespace path,
132  * ensuring that names that already exist are not overwritten. For
133  * example:
134  * "a.b.c" -> a = {};a.b={};a.b.c={};
135  * Used by goog.provide and goog.exportSymbol.
136  * @param {string} name name of the object that this file defines.
137  * @param {*=} opt_object the object to expose at the end of the path.
138  * @param {Object=} opt_objectToExportTo The object to add the path to; default
139  *     is |goog.global|.
140  * @private
141  */
142 goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
143   var parts = name.split('.');
144   var cur = opt_objectToExportTo || goog.global;
145 
146   // Internet Explorer exhibits strange behavior when throwing errors from
147   // methods externed in this manner.  See the testExportSymbolExceptions in
148   // base_test.html for an example.
149   if (!(parts[0] in cur) && cur.execScript) {
150     cur.execScript('var ' + parts[0]);
151   }
152 
153   // Certain browsers cannot parse code in the form for((a in b); c;);
154   // This pattern is produced by the JSCompiler when it collapses the
155   // statement above into the conditional loop below. To prevent this from
156   // happening, use a for-loop and reserve the init logic as below.
157 
158   // Parentheses added to eliminate strict JS warning in Firefox.
159   for (var part; parts.length && (part = parts.shift());) {
160     if (!parts.length && goog.isDef(opt_object)) {
161       // last part and we have an object; use it
162       cur[part] = opt_object;
163     } else if (cur[part]) {
164       cur = cur[part];
165     } else {
166       cur = cur[part] = {};
167     }
168   }
169 };
170 
171 
172 /**
173  * Returns an object based on its fully qualified external name.  If you are
174  * using a compilation pass that renames property names beware that using this
175  * function will not find renamed properties.
176  *
177  * @param {string} name The fully qualified name.
178  * @param {Object=} opt_obj The object within which to look; default is
179  *     |goog.global|.
180  * @return {Object} The object or, if not found, null.
181  */
182 goog.getObjectByName = function(name, opt_obj) {
183   var parts = name.split('.');
184   var cur = opt_obj || goog.global;
185   for (var part; part = parts.shift(); ) {
186     if (cur[part]) {
187       cur = cur[part];
188     } else {
189       return null;
190     }
191   }
192   return cur;
193 };
194 
195 
196 /**
197  * Globalizes a whole namespace, such as goog or goog.lang.
198  *
199  * @param {Object} obj The namespace to globalize.
200  * @param {Object=} opt_global The object to add the properties to.
201  * @deprecated Properties may be explicitly exported to the global scope, but
202  *     this should no longer be done in bulk.
203  */
204 goog.globalize = function(obj, opt_global) {
205   var global = opt_global || goog.global;
206   for (var x in obj) {
207     global[x] = obj[x];
208   }
209 };
210 
211 
212 /**
213  * Adds a dependency from a file to the files it requires.
214  * @param {string} relPath The path to the js file.
215  * @param {Array} provides An array of strings with the names of the objects
216  *                         this file provides.
217  * @param {Array} requires An array of strings with the names of the objects
218  *                         this file requires.
219  */
220 goog.addDependency = function(relPath, provides, requires) {
221   if (!COMPILED) {
222     var provide, require;
223     var path = relPath.replace(/\\/g, '/');
224     var deps = goog.dependencies_;
225     for (var i = 0; provide = provides[i]; i++) {
226       deps.nameToPath[provide] = path;
227       if (!(path in deps.pathToNames)) {
228         deps.pathToNames[path] = {};
229       }
230       deps.pathToNames[path][provide] = true;
231     }
232     for (var j = 0; require = requires[j]; j++) {
233       if (!(path in deps.requires)) {
234         deps.requires[path] = {};
235       }
236       deps.requires[path][require] = true;
237     }
238   }
239 };
240 
241 
242 
243 /**
244  * Implements a system for the dynamic resolution of dependencies
245  * that works in parallel with the BUILD system. Note that all calls
246  * to goog.require will be stripped by the JSCompiler when the
247  * --closure_pass option is used.
248  * @param {string} rule Rule to include, in the form goog.package.part.
249  */
250 goog.require = function(rule) {
251 
252   // if the object already exists we do not need do do anything
253   // TODO(user): If we start to support require based on file name this has
254   //            to change
255   // TODO(user): If we allow goog.foo.* this has to change
256   // TODO(user): If we implement dynamic load after page load we should probably
257   //            not remove this code for the compiled output
258   if (!COMPILED) {
259     if (goog.getObjectByName(rule)) {
260       return;
261     }
262     var path = goog.getPathFromDeps_(rule);
263     if (path) {
264       goog.included_[path] = true;
265       goog.writeScripts_();
266     } else {
267       var errorMessage = 'goog.require could not find: ' + rule;
268       if (goog.global.console) {
269         goog.global.console['error'](errorMessage);
270       }
271 
272       
273         throw Error(errorMessage);
274         
275     }
276   }
277 };
278 
279 
280 /**
281  * Path for included scripts
282  * @type {string}
283  */
284 goog.basePath = '';
285 
286 
287 /**
288  * A hook for overriding the base path.
289  * @type {string|undefined}
290  */
291 goog.global.CLOSURE_BASE_PATH;
292 
293 
294 /**
295  * Whether to write out Closure's deps file. By default,
296  * the deps are written.
297  * @type {boolean|undefined}
298  */
299 goog.global.CLOSURE_NO_DEPS;
300 
301 
302 /**
303  * Null function used for default values of callbacks, etc.
304  * @type {!Function}
305  */
306 goog.nullFunction = function() {};
307 
308 
309 /**
310  * The identity function. Returns its first argument.
311  *
312  * @param {...*} var_args The arguments of the function.
313  * @return {*} The first argument.
314  * @deprecated Use goog.functions.identity instead.
315  */
316 goog.identityFunction = function(var_args) {
317   return arguments[0];
318 };
319 
320 
321 /**
322  * When defining a class Foo with an abstract method bar(), you can do:
323  *
324  * Foo.prototype.bar = goog.abstractMethod
325  *
326  * Now if a subclass of Foo fails to override bar(), an error
327  * will be thrown when bar() is invoked.
328  *
329  * Note: This does not take the name of the function to override as
330  * an argument because that would make it more difficult to obfuscate
331  * our JavaScript code.
332  *
333  * @type {!Function}
334  * @throws {Error} when invoked to indicate the method should be
335  *   overridden.
336  */
337 goog.abstractMethod = function() {
338   throw Error('unimplemented abstract method');
339 };
340 
341 
342 /**
343  * Adds a {@code getInstance} static method that always return the same instance
344  * object.
345  * @param {!Function} ctor The constructor for the class to add the static
346  *     method to.
347  */
348 goog.addSingletonGetter = function(ctor) {
349   ctor.getInstance = function() {
350     return ctor.instance_ || (ctor.instance_ = new ctor());
351   };
352 };
353 
354 
355 if (!COMPILED) {
356   /**
357    * Object used to keep track of urls that have already been added. This
358    * record allows the prevention of circular dependencies.
359    * @type {Object}
360    * @private
361    */
362   goog.included_ = {};
363 
364 
365   /**
366    * This object is used to keep track of dependencies and other data that is
367    * used for loading scripts
368    * @private
369    * @type {Object}
370    */
371   goog.dependencies_ = {
372     pathToNames: {}, // 1 to many
373     nameToPath: {}, // 1 to 1
374     requires: {}, // 1 to many
375     visited: {}, // used when resolving dependencies to prevent us from
376                  // visiting the file twice
377     written: {} // used to keep track of script files we have written
378   };
379 
380 
381   /**
382    * Tries to detect whether is in the context of an HTML document.
383    * @return {boolean} True if it looks like HTML document.
384    * @private
385    */
386   goog.inHtmlDocument_ = function() {
387     var doc = goog.global.document;
388     return typeof doc != 'undefined' &&
389            'write' in doc;  // XULDocument misses write.
390   };
391 
392 
393   /**
394    * Tries to detect the base path of the base.js script that bootstraps Closure
395    * @private
396    */
397   goog.findBasePath_ = function() {
398     if (!goog.inHtmlDocument_()) {
399       return;
400     }
401     var doc = goog.global.document;
402     if (goog.global.CLOSURE_BASE_PATH) {
403       goog.basePath = goog.global.CLOSURE_BASE_PATH;
404       return;
405     }
406     var scripts = doc.getElementsByTagName('script');
407     // Search backwards since the current script is in almost all cases the one
408     // that has base.js.
409     for (var i = scripts.length - 1; i >= 0; --i) {
410       var src = scripts[i].src;
411       var l = src.length;
412       if (src.substr(l - 7) == 'base.js') {
413         goog.basePath = src.substr(0, l - 7);
414         return;
415       }
416     }
417   };
418 
419 
420   /**
421    * Writes a script tag if, and only if, that script hasn't already been added
422    * to the document.  (Must be called at execution time)
423    * @param {string} src Script source.
424    * @private
425    */
426   goog.writeScriptTag_ = function(src) {
427     if (goog.inHtmlDocument_() &&
428         !goog.dependencies_.written[src]) {
429       goog.dependencies_.written[src] = true;
430       var doc = goog.global.document;
431       doc.write('<script type="text/javascript" src="' +
432                 src + '"></' + 'script>');
433     }
434   };
435 
436 
437   /**
438    * Resolves dependencies based on the dependencies added using addDependency
439    * and calls writeScriptTag_ in the correct order.
440    * @private
441    */
442   goog.writeScripts_ = function() {
443     // the scripts we need to write this time
444     var scripts = [];
445     var seenScript = {};
446     var deps = goog.dependencies_;
447 
448     function visitNode(path) {
449       if (path in deps.written) {
450         return;
451       }
452 
453       // we have already visited this one. We can get here if we have cyclic
454       // dependencies
455       if (path in deps.visited) {
456         if (!(path in seenScript)) {
457           seenScript[path] = true;
458           scripts.push(path);
459         }
460         return;
461       }
462 
463       deps.visited[path] = true;
464 
465       if (path in deps.requires) {
466         for (var requireName in deps.requires[path]) {
467           if (requireName in deps.nameToPath) {
468             visitNode(deps.nameToPath[requireName]);
469           } else if (!goog.getObjectByName(requireName)) {
470             // If the required name is defined, we assume that this
471             // dependency was bootstapped by other means. Otherwise,
472             // throw an exception.
473             throw Error('Undefined nameToPath for ' + requireName);
474           }
475         }
476       }
477 
478       if (!(path in seenScript)) {
479         seenScript[path] = true;
480         scripts.push(path);
481       }
482     }
483 
484     for (var path in goog.included_) {
485       if (!deps.written[path]) {
486         visitNode(path);
487       }
488     }
489 
490     for (var i = 0; i < scripts.length; i++) {
491       if (scripts[i]) {
492 	
493         goog.writeScriptTag_(goog.basePath + scripts[i]);
494       } else {
495         throw Error('Undefined script input');
496       }
497     }
498   };
499 
500 
501   /**
502    * Looks at the dependency rules and tries to determine the script file that
503    * fulfills a particular rule.
504    * @param {string} rule In the form goog.namespace.Class or project.script.
505    * @return {?string} Url corresponding to the rule, or null.
506    * @private
507    */
508   goog.getPathFromDeps_ = function(rule) {
509     if (rule in goog.dependencies_.nameToPath) {
510       return goog.dependencies_.nameToPath[rule];
511     } else {
512       return null;
513     }
514   };
515 
516   goog.findBasePath_();
517 
518   // Allow projects to manage the deps files themselves.
519   if (!goog.global.CLOSURE_NO_DEPS) {
520     goog.writeScriptTag_(goog.basePath + 'deps.js');
521   }
522 }
523 
524 
525 
526 //==============================================================================
527 // Language Enhancements
528 //==============================================================================
529 
530 
531 /**
532  * This is a "fixed" version of the typeof operator.  It differs from the typeof
533  * operator in such a way that null returns 'null' and arrays return 'array'.
534  * @param {*} value The value to get the type of.
535  * @return {string} The name of the type.
536  */
537 goog.typeOf = function(value) {
538   var s = typeof value;
539   if (s == 'object') {
540     if (value) {
541       // We cannot use constructor == Array or instanceof Array because
542       // different frames have different Array objects. In IE6, if the iframe
543       // where the array was created is destroyed, the array loses its
544       // prototype. Then dereferencing val.splice here throws an exception, so
545       // we can't use goog.isFunction. Calling typeof directly returns 'unknown'
546       // so that will work. In this case, this function will return false and
547       // most array functions will still work because the array is still
548       // array-like (supports length and []) even though it has lost its
549       // prototype.
550       // Mark Miller noticed that Object.prototype.toString
551       // allows access to the unforgeable [[Class]] property.
552       //  15.2.4.2 Object.prototype.toString ( )
553       //  When the toString method is called, the following steps are taken:
554       //      1. Get the [[Class]] property of this object.
555       //      2. Compute a string value by concatenating the three strings
556       //         "[object ", Result(1), and "]".
557       //      3. Return Result(2).
558       // and this behavior survives the destruction of the execution context.
559       if (value instanceof Array ||  // Works quickly in same execution context.
560           // If value is from a different execution context then
561           // !(value instanceof Object), which lets us early out in the common
562           // case when value is from the same context but not an array.
563           // The {if (value)} check above means we don't have to worry about
564           // undefined behavior of Object.prototype.toString on null/undefined.
565           //
566           // HACK: In order to use an Object prototype method on the arbitrary
567           //   value, the compiler requires the value be cast to type Object,
568           //   even though the ECMA spec explicitly allows it.
569           (!(value instanceof Object) &&
570            (Object.prototype.toString.call(
571                /** @type {Object} */ (value)) == '[object Array]') ||
572 
573            // In IE all non value types are wrapped as objects across window
574            // boundaries (not iframe though) so we have to do object detection
575            // for this edge case
576            typeof value.length == 'number' &&
577            typeof value.splice != 'undefined' &&
578            typeof value.propertyIsEnumerable != 'undefined' &&
579            !value.propertyIsEnumerable('splice')
580 
581           )) {
582         return 'array';
583       }
584       // HACK: There is still an array case that fails.
585       //     function ArrayImpostor() {}
586       //     ArrayImpostor.prototype = [];
587       //     var impostor = new ArrayImpostor;
588       // this can be fixed by getting rid of the fast path
589       // (value instanceof Array) and solely relying on
590       // (value && Object.prototype.toString.vall(value) === '[object Array]')
591       // but that would require many more function calls and is not warranted
592       // unless closure code is receiving objects from untrusted sources.
593 
594       // IE in cross-window calls does not correctly marshal the function type
595       // (it appears just as an object) so we cannot use just typeof val ==
596       // 'function'. However, if the object has a call property, it is a
597       // function.
598       if (!(value instanceof Object) &&
599           (Object.prototype.toString.call(
600               /** @type {Object} */ (value)) == '[object Function]' ||
601           typeof value.call != 'undefined' &&
602           typeof value.propertyIsEnumerable != 'undefined' &&
603           !value.propertyIsEnumerable('call'))) {
604         return 'function';
605       }
606 
607 
608     } else {
609       return 'null';
610     }
611 
612   // In Safari typeof nodeList returns 'function', and on Firefox
613   // typeof behaves similarly for HTML{Applet,Embed,Object}Elements
614   // and RegExps.  We would like to return object for those and we can
615   // detect an invalid function by making sure that the function
616   // object has a call method.
617   } else if (s == 'function' && typeof value.call == 'undefined') {
618     return 'object';
619   }
620   return s;
621 };
622 
623 
624 /**
625  * Safe way to test whether a property is enumarable.  It allows testing
626  * for enumerable on objects where 'propertyIsEnumerable' is overridden or
627  * does not exist (like DOM nodes in IE). Does not use browser native
628  * Object.propertyIsEnumerable.
629  * @param {Object} object The object to test if the property is enumerable.
630  * @param {string} propName The property name to check for.
631  * @return {boolean} True if the property is enumarable.
632  * @private
633  */
634 goog.propertyIsEnumerableCustom_ = function(object, propName) {
635   // KJS in Safari 2 is not ECMAScript compatible and lacks crucial methods
636   // such as propertyIsEnumerable.  We therefore use a workaround.
637   // Does anyone know a more efficient work around?
638   if (propName in object) {
639     for (var key in object) {
640       if (key == propName &&
641           Object.prototype.hasOwnProperty.call(object, propName)) {
642         return true;
643       }
644     }
645   }
646   return false;
647 };
648 
649 
650 /**
651  * Safe way to test whether a property is enumarable.  It allows testing
652  * for enumerable on objects where 'propertyIsEnumerable' is overridden or
653  * does not exist (like DOM nodes in IE).
654  * @param {Object} object The object to test if the property is enumerable.
655  * @param {string} propName The property name to check for.
656  * @return {boolean} True if the property is enumarable.
657  * @private
658  */
659 goog.propertyIsEnumerable_ = function(object, propName) {
660   // In IE if object is from another window, cannot use propertyIsEnumerable
661   // from this window's Object. Will raise a 'JScript object expected' error.
662   if (object instanceof Object) {
663     return Object.prototype.propertyIsEnumerable.call(object, propName);
664   } else {
665     return goog.propertyIsEnumerableCustom_(object, propName);
666   }
667 };
668 
669 
670 /**
671  * Returns true if the specified value is not |undefined|.
672  * WARNING: Do not use this to test if an object has a property. Use the in
673  * operator instead.  Additionally, this function assumes that the global
674  * undefined variable has not been redefined.
675  * @param {*} val Variable to test.
676  * @return {boolean} Whether variable is defined.
677  */
678 goog.isDef = function(val) {
679   return val !== undefined;
680 };
681 
682 
683 /**
684  * Returns true if the specified value is |null|
685  * @param {*} val Variable to test.
686  * @return {boolean} Whether variable is null.
687  */
688 goog.isNull = function(val) {
689   return val === null;
690 };
691 
692 
693 /**
694  * Returns true if the specified value is defined and not null
695  * @param {*} val Variable to test.
696  * @return {boolean} Whether variable is defined and not null.
697  */
698 goog.isDefAndNotNull = function(val) {
699   // Note that undefined == null.
700   return val != null;
701 };
702 
703 
704 /**
705  * Returns true if the specified value is an array
706  * @param {*} val Variable to test.
707  * @return {boolean} Whether variable is an array.
708  */
709 goog.isArray = function(val) {
710   return goog.typeOf(val) == 'array';
711 };
712 
713 
714 /**
715  * Returns true if the object looks like an array. To qualify as array like
716  * the value needs to be either a NodeList or an object with a Number length
717  * property.
718  * @param {*} val Variable to test.
719  * @return {boolean} Whether variable is an array.
720  */
721 goog.isArrayLike = function(val) {
722   var type = goog.typeOf(val);
723   return type == 'array' || type == 'object' && typeof val.length == 'number';
724 };
725 
726 
727 /**
728  * Returns true if the object looks like a Date. To qualify as Date-like
729  * the value needs to be an object and have a getFullYear() function.
730  * @param {*} val Variable to test.
731  * @return {boolean} Whether variable is a like a Date.
732  */
733 goog.isDateLike = function(val) {
734   return goog.isObject(val) && typeof val.getFullYear == 'function';
735 };
736 
737 
738 /**
739  * Returns true if the specified value is a string
740  * @param {*} val Variable to test.
741  * @return {boolean} Whether variable is a string.
742  */
743 goog.isString = function(val) {
744   return typeof val == 'string';
745 };
746 
747 
748 /**
749  * Returns true if the specified value is a boolean
750  * @param {*} val Variable to test.
751  * @return {boolean} Whether variable is boolean.
752  */
753 goog.isBoolean = function(val) {
754   return typeof val == 'boolean';
755 };
756 
757 
758 /**
759  * Returns true if the specified value is a number
760  * @param {*} val Variable to test.
761  * @return {boolean} Whether variable is a number.
762  */
763 goog.isNumber = function(val) {
764   return typeof val == 'number';
765 };
766 
767 
768 /**
769  * Returns true if the specified value is a function
770  * @param {*} val Variable to test.
771  * @return {boolean} Whether variable is a function.
772  */
773 goog.isFunction = function(val) {
774   return goog.typeOf(val) == 'function';
775 };
776 
777 
778 /**
779  * Returns true if the specified value is an object.  This includes arrays
780  * and functions.
781  * @param {*} val Variable to test.
782  * @return {boolean} Whether variable is an object.
783  */
784 goog.isObject = function(val) {
785   var type = goog.typeOf(val);
786   return type == 'object' || type == 'array' || type == 'function';
787 };
788 
789 
790 /**
791  * Gets a unique ID for an object. This mutates the object so that further
792  * calls with the same object as a parameter returns the same value. The unique
793  * ID is guaranteed to be unique across the current session amongst objects that
794  * are passed into {@code getUid}. There is no guarantee that the ID is unique
795  * or consistent across sessions.
796  *
797  * @param {Object} obj The object to get the unique ID for.
798  * @return {number} The unique ID for the object.
799  */
800 goog.getUid = function(obj) {
801   // TODO(user): Make the type stricter, do not accept null.
802 
803   // In IE, DOM nodes do not extend Object so they do not have this method.
804   // we need to check hasOwnProperty because the proto might have this set.
805   if (obj.hasOwnProperty && obj.hasOwnProperty(goog.UID_PROPERTY_)) {
806     return obj[goog.UID_PROPERTY_];
807   }
808   if (!obj[goog.UID_PROPERTY_]) {
809     obj[goog.UID_PROPERTY_] = ++goog.uidCounter_;
810   }
811   return obj[goog.UID_PROPERTY_];
812 };
813 
814 
815 /**
816  * Removes the unique ID from an object. This is useful if the object was
817  * previously mutated using {@code goog.getUid} in which case the mutation is
818  * undone.
819  * @param {Object} obj The object to remove the unique ID field from.
820  */
821 goog.removeUid = function(obj) {
822   // TODO(user): Make the type stricter, do not accept null.
823 
824   // DOM nodes in IE are not instance of Object and throws exception
825   // for delete. Instead we try to use removeAttribute
826   if ('removeAttribute' in obj) {
827     obj.removeAttribute(goog.UID_PROPERTY_);
828   }
829   /** @preserveTry */
830   try {
831     delete obj[goog.UID_PROPERTY_];
832   } catch (ex) {
833   }
834 };
835 
836 
837 /**
838  * Name for unique ID property. Initialized in a way to help avoid collisions
839  * with other closure javascript on the same page.
840  * @type {string}
841  * @private
842  */
843 goog.UID_PROPERTY_ = 'closure_uid_' +
844     Math.floor(Math.random() * 2147483648).toString(36);
845 
846 
847 /**
848  * Counter for UID.
849  * @type {number}
850  * @private
851  */
852 goog.uidCounter_ = 0;
853 
854 
855 /**
856  * Adds a hash code field to an object. The hash code is unique for the
857  * given object.
858  * @param {Object} obj The object to get the hash code for.
859  * @return {number} The hash code for the object.
860  * @deprecated Use goog.getUid instead.
861  */
862 goog.getHashCode = goog.getUid;
863 
864 
865 /**
866  * Removes the hash code field from an object.
867  * @param {Object} obj The object to remove the field from.
868  * @deprecated Use goog.removeUid instead.
869  */
870 goog.removeHashCode = goog.removeUid;
871 
872 
873 /**
874  * Clones a value. The input may be an Object, Array, or basic type. Objects and
875  * arrays will be cloned recursively.
876  *
877  * WARNINGS:
878  * <code>goog.cloneObject</code> does not detect reference loops. Objects that
879  * refer to themselves will cause infinite recursion.
880  *
881  * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies
882  * UIDs created by <code>getUid</code> into cloned results.
883  *
884  * @param {*} obj The value to clone.
885  * @return {*} A clone of the input value.
886  * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.
887  */
888 goog.cloneObject = function(obj) {
889   var type = goog.typeOf(obj);
890   if (type == 'object' || type == 'array') {
891     if (obj.clone) {
892       return obj.clone();
893     }
894     var clone = type == 'array' ? [] : {};
895     for (var key in obj) {
896       clone[key] = goog.cloneObject(obj[key]);
897     }
898     return clone;
899   }
900 
901   return obj;
902 };
903 
904 
905 /**
906  * Forward declaration for the clone method. This is necessary until the
907  * compiler can better support duck-typing constructs as used in
908  * goog.cloneObject.
909  *
910  * TODO(user): Remove once the JSCompiler can infer that the check for
911  * proto.clone is safe in goog.cloneObject.
912  *
913  * @type {Function}
914  */
915 Object.prototype.clone;
916 
917 
918 /**
919  * Partially applies this function to a particular 'this object' and zero or
920  * more arguments. The result is a new function with some arguments of the first
921  * function pre-filled and the value of |this| 'pre-specified'.<br><br>
922  *
923  * Remaining arguments specified at call-time are appended to the pre-
924  * specified ones.<br><br>
925  *
926  * Also see: {@link #partial}.<br><br>
927  *
928  * Usage:
929  * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
930  * barMethBound('arg3', 'arg4');</pre>
931  *
932  * @param {Function} fn A function to partially apply.
933  * @param {Object|undefined} selfObj Specifies the object which |this| should
934  *     point to when the function is run. If the value is null or undefined, it
935  *     will default to the global object.
936  * @param {...*} var_args Additional arguments that are partially
937  *     applied to the function.
938  *
939  * @return {!Function} A partially-applied form of the function bind() was
940  *     invoked as a method of.
941  */
942 goog.bind = function(fn, selfObj, var_args) {
943   var context = selfObj || goog.global;
944 
945   if (arguments.length > 2) {
946     var boundArgs = Array.prototype.slice.call(arguments, 2);
947     return function() {
948       // Prepend the bound arguments to the current arguments.
949       var newArgs = Array.prototype.slice.call(arguments);
950       Array.prototype.unshift.apply(newArgs, boundArgs);
951       return fn.apply(context, newArgs);
952     };
953 
954   } else {
955     return function() {
956       return fn.apply(context, arguments);
957     };
958   }
959 };
960 
961 
962 /**
963  * Like bind(), except that a 'this object' is not required. Useful when the
964  * target function is already bound.
965  *
966  * Usage:
967  * var g = partial(f, arg1, arg2);
968  * g(arg3, arg4);
969  *
970  * @param {Function} fn A function to partially apply.
971  * @param {...*} var_args Additional arguments that are partially
972  *     applied to fn.
973  * @return {!Function} A partially-applied form of the function bind() was
974  *     invoked as a method of.
975  */
976 goog.partial = function(fn, var_args) {
977   var args = Array.prototype.slice.call(arguments, 1);
978   return function() {
979     // Prepend the bound arguments to the current arguments.
980     var newArgs = Array.prototype.slice.call(arguments);
981     newArgs.unshift.apply(newArgs, args);
982     return fn.apply(this, newArgs);
983   };
984 };
985 
986 
987 /**
988  * Copies all the members of a source object to a target object. This method
989  * does not work on all browsers for all objects that contain keys such as
990  * toString or hasOwnProperty. Use goog.object.extend for this purpose.
991  * @param {Object} target Target.
992  * @param {Object} source Source.
993  */
994 goog.mixin = function(target, source) {
995   for (var x in source) {
996     target[x] = source[x];
997   }
998 
999   // For IE7 or lower, the for-in-loop does not contain any properties that are
1000   // not enumerable on the prototype object (for example, isPrototypeOf from
1001   // Object.prototype) but also it will not include 'replace' on objects that
1002   // extend String and change 'replace' (not that it is common for anyone to
1003   // extend anything except Object).
1004 };
1005 
1006 
1007 /**
1008  * @return {number} An integer value representing the number of milliseconds
1009  *     between midnight, January 1, 1970 and the current time.
1010  */
1011 goog.now = Date.now || (function() {
1012   // Unary plus operator converts its operand to a number which in the case of
1013   // a date is done by calling getTime().
1014   return +new Date();
1015 });
1016 
1017 
1018 /**
1019  * Evals javascript in the global scope.  In IE this uses execScript, other
1020  * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
1021  * global scope (for example, in Safari), appends a script tag instead.
1022  * Throws an exception if neither execScript or eval is defined.
1023  * @param {string} script JavaScript string.
1024  */
1025 goog.globalEval = function(script) {
1026   if (goog.global.execScript) {
1027     goog.global.execScript(script, 'JavaScript');
1028   } else if (goog.global.eval) {
1029     // Test to see if eval works
1030     if (goog.evalWorksForGlobals_ == null) {
1031       goog.global.eval('var _et_ = 1;');
1032       if (typeof goog.global['_et_'] != 'undefined') {
1033         delete goog.global['_et_'];
1034         goog.evalWorksForGlobals_ = true;
1035       } else {
1036         goog.evalWorksForGlobals_ = false;
1037       }
1038     }
1039 
1040     if (goog.evalWorksForGlobals_) {
1041       goog.global.eval(script);
1042     } else {
1043       var doc = goog.global.document;
1044       var scriptElt = doc.createElement('script');
1045       scriptElt.type = 'text/javascript';
1046       scriptElt.defer = false;
1047       // Note(user): can't use .innerHTML since "t('<test>')" will fail and
1048       // .text doesn't work in Safari 2.  Therefore we append a text node.
1049       scriptElt.appendChild(doc.createTextNode(script));
1050       doc.body.appendChild(scriptElt);
1051       doc.body.removeChild(scriptElt);
1052     }
1053   } else {
1054     throw Error('goog.globalEval not available');
1055   }
1056 };
1057 
1058 
1059 /**
1060  * A macro for defining composite types.
1061  *
1062  * By assigning goog.typedef to a name, this tells JSCompiler that this is not
1063  * the name of a class, but rather it's the name of a composite type.
1064  *
1065  * For example,
1066  * /** @type {Array|NodeList} / goog.ArrayLike = goog.typedef;
1067  * will tell JSCompiler to replace all appearances of goog.ArrayLike in type
1068  * definitions with the union of Array and NodeList.
1069  *
1070  * Does nothing in uncompiled code.
1071  */
1072 goog.typedef = true;
1073 
1074 
1075 /**
1076  * Optional map of CSS class names to obfuscated names used with
1077  * goog.getCssName().
1078  * @type {Object|undefined}
1079  * @private
1080  * @see goog.setCssNameMapping
1081  */
1082 goog.cssNameMapping_;
1083 
1084 
1085 /**
1086  * Handles strings that are intended to be used as CSS class names.
1087  *
1088  * Without JS Compiler the arguments are simple joined with a hyphen and passed
1089  * through unaltered.
1090  *
1091  * With the JS Compiler the arguments are inlined, e.g:
1092  *     var x = goog.getCssName('foo');
1093  *     var y = goog.getCssName(this.baseClass, 'active');
1094  *  becomes:
1095  *     var x= 'foo';
1096  *     var y = this.baseClass + '-active';
1097  *
1098  * If a CSS renaming map is passed to the compiler it will replace symbols in
1099  * the classname.  If one argument is passed it will be processed, if two are
1100  * passed only the modifier will be processed, as it is assumed the first
1101  * argument was generated as a result of calling goog.getCssName.
1102  *
1103  * Names are split on 'hyphen' and processed in parts such that the following
1104  * are equivalent:
1105  *   var base = goog.getCssName('baseclass');
1106  *   goog.getCssName(base, 'modifier');
1107  *   goog.getCSsName('baseclass-modifier');
1108  *
1109  * If any part does not appear in the renaming map a warning is logged and the
1110  * original, unobfuscated class name is inlined.
1111  *
1112  * @param {string} className The class name.
1113  * @param {string=} opt_modifier A modifier to be appended to the class name.
1114  * @return {string} The class name or the concatenation of the class name and
1115  *     the modifier.
1116  */
1117 goog.getCssName = function(className, opt_modifier) {
1118   var cssName = className + (opt_modifier ? '-' + opt_modifier : '');
1119   return (goog.cssNameMapping_ && (cssName in goog.cssNameMapping_)) ?
1120       goog.cssNameMapping_[cssName] : cssName;
1121 };
1122 
1123 
1124 /**
1125  * Sets the map to check when returning a value from goog.getCssName(). Example:
1126  * <pre>
1127  * goog.setCssNameMapping({
1128  *   "goog-menu": "a",
1129  *   "goog-menu-disabled": "a-b",
1130  *   "CSS_LOGO": "b",
1131  *   "hidden": "c"
1132  * });
1133  *
1134  * // The following evaluates to: "a a-b".
1135  * goog.getCssName('goog-menu') + ' ' + goog.getCssName('goog-menu', 'disabled')
1136  * </pre>
1137  * When declared as a map of string literals to string literals, the JSCompiler
1138  * will replace all calls to goog.getCssName() using the supplied map if the
1139  * --closure_pass flag is set.
1140  *
1141  * @param {!Object} mapping A map of strings to strings where keys are possible
1142  *     arguments to goog.getCssName() and values are the corresponding values
1143  *     that should be returned.
1144  */
1145 goog.setCssNameMapping = function(mapping) {
1146   goog.cssNameMapping_ = mapping;
1147 };
1148 
1149 
1150 /**
1151  * Abstract implementation of goog.getMsg for use with localized messages.
1152  * @param {string} str Translatable string, places holders in the form {$foo}.
1153  * @param {Object=} opt_values Map of place holder name to value.
1154  * @return {string} message with placeholders filled.
1155  */
1156 goog.getMsg = function(str, opt_values) {
1157   var values = opt_values || {};
1158   for (var key in values) {
1159     str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), values[key]);
1160   }
1161   return str;
1162 };
1163 
1164 
1165 /**
1166  * Exposes an unobfuscated global namespace path for the given object.
1167  * Note that fields of the exported object *will* be obfuscated,
1168  * unless they are exported in turn via this function or
1169  * goog.exportProperty
1170  *
1171  * <p>Also handy for making public items that are defined in anonymous
1172  * closures.
1173  *
1174  * ex. goog.exportSymbol('Foo', Foo);
1175  *
1176  * ex. goog.exportSymbol('public.path.Foo.staticFunction',
1177  *                       Foo.staticFunction);
1178  *     public.path.Foo.staticFunction();
1179  *
1180  * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
1181  *                       Foo.prototype.myMethod);
1182  *     new public.path.Foo().myMethod();
1183  *
1184  * @param {string} publicPath Unobfuscated name to export.
1185  * @param {*} object Object the name should point to.
1186  * @param {Object=} opt_objectToExportTo The object to add the path to; default
1187  *     is |goog.global|.
1188  */
1189 goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
1190   goog.exportPath_(publicPath, object, opt_objectToExportTo);
1191 };
1192 
1193 
1194 /**
1195  * Exports a property unobfuscated into the object's namespace.
1196  * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
1197  * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
1198  * @param {Object} object Object whose static property is being exported.
1199  * @param {string} publicName Unobfuscated name to export.
1200  * @param {*} symbol Object the name should point to.
1201  */
1202 goog.exportProperty = function(object, publicName, symbol) {
1203   object[publicName] = symbol;
1204 };
1205 
1206 
1207 /**
1208  * Inherit the prototype methods from one constructor into another.
1209  *
1210  * Usage:
1211  * <pre>
1212  * function ParentClass(a, b) { }
1213  * ParentClass.prototype.foo = function(a) { }
1214  *
1215  * function ChildClass(a, b, c) {
1216  *   ParentClass.call(this, a, b);
1217  * }
1218  *
1219  * goog.inherits(ChildClass, ParentClass);
1220  *
1221  * var child = new ChildClass('a', 'b', 'see');
1222  * child.foo(); // works
1223  * </pre>
1224  *
1225  * In addition, a superclass' implementation of a method can be invoked
1226  * as follows:
1227  *
1228  * <pre>
1229  * ChildClass.prototype.foo = function(a) {
1230  *   ChildClass.superClass_.foo.call(this, a);
1231  *   // other code
1232  * };
1233  * </pre>
1234  *
1235  * @param {Function} childCtor Child class.
1236  * @param {Function} parentCtor Parent class.
1237  */
1238 goog.inherits = function(childCtor, parentCtor) {
1239   /** @constructor */
1240   function tempCtor() {};
1241   tempCtor.prototype = parentCtor.prototype;
1242   childCtor.superClass_ = parentCtor.prototype;
1243   childCtor.prototype = new tempCtor();
1244   childCtor.prototype.constructor = childCtor;
1245 };
1246 
1247 
1248 /**
1249  * Call up to the superclass.
1250  *
1251  * If this is called from a constructor, then this calls the superclass
1252  * contructor with arguments 1-N.
1253  *
1254  * If this is called from a prototype method, then you must pass
1255  * the name of the method as the second argument to this function. If
1256  * you do not, you will get a runtime error. This calls the superclass'
1257  * method with arguments 2-N.
1258  *
1259  * This function only works if you use goog.inherits to express
1260  * inheritance relationships between your classes.
1261  *
1262  * This function is a compiler primitive. At compile-time, the
1263  * compiler will do macro expansion to remove a lot of
1264  * the extra overhead that this function introduces. The compiler
1265  * will also enforce a lot of the assumptions that this function
1266  * makes, and treat it as a compiler error if you break them.
1267  *
1268  * @param {!Object} me Should always be "this".
1269  * @param {*=} opt_methodName The method name if calling a super method.
1270  * @param {...*} var_args The rest of the arguments.
1271  * @return {*} The return value of the superclass method.
1272  */
1273 goog.base = function(me, opt_methodName, var_args) {
1274   var caller = arguments.callee.caller;
1275   if (caller.superClass_) {
1276     // This is a constructor. Call the superclass constructor.
1277     return caller.superClass_.constructor.apply(
1278         me, Array.prototype.slice.call(arguments, 1));
1279   }
1280 
1281   var args = Array.prototype.slice.call(arguments, 2);
1282   var foundCaller = false;
1283   for (var ctor = me.constructor;
1284        ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
1285     if (ctor.prototype[opt_methodName] === caller) {
1286       foundCaller = true;
1287     } else if (foundCaller) {
1288       return ctor.prototype[opt_methodName].apply(me, args);
1289     }
1290   }
1291 
1292   // If we did not find the caller in the prototype chain,
1293   // then one of two things happened:
1294   // 1) The caller is an instance method.
1295   // 2) This method was not called by the right caller.
1296   if (me[opt_methodName] === caller) {
1297     return me.constructor.prototype[opt_methodName].apply(me, args);
1298   } else {
1299     throw Error(
1300         'goog.base called from a method of one name ' +
1301         'to a method of a different name');
1302   }
1303 };
1304 
1305 
1306 
1307