]> source.dussan.org Git - jquery-ui.git/commitdiff
Replace $.global with Globalize, update Spinner to use it. Related demos currently...
authorJörn Zaefferer <joern.zaefferer@gmail.com>
Wed, 10 Aug 2011 12:55:16 +0000 (14:55 +0200)
committerJörn Zaefferer <joern.zaefferer@gmail.com>
Wed, 10 Aug 2011 12:55:16 +0000 (14:55 +0200)
demos/spinner/currency.html
demos/spinner/decimal.html
demos/spinner/time.html
external/globalize.culture.de-DE.js [new file with mode: 0644]
external/globalize.culture.ja-JP.js [new file with mode: 0644]
external/globalize.js [new file with mode: 0644]
external/jquery.global.de-DE.js [deleted file]
external/jquery.global.ja-JP.js [deleted file]
external/jquery.global.js [deleted file]
ui/jquery.ui.spinner.js

index 18d479de8c1a62b55232b71dcb9bb338ec754e83..f73c19f80cd35c90bfb0d8bf4b312499000b4272 100644 (file)
@@ -6,9 +6,9 @@
        <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
        <script src="../../jquery-1.6.2.js"></script>
        <script src="../../external/jquery.mousewheel-3.0.4.js"></script>
-       <script src="../../external/jquery.global.js"></script>
-       <script src="../../external/jquery.global.de-DE.js"></script>
-       <script src="../../external/jquery.global.ja-JP.js"></script>
+       <script src="../../external/globalize.js"></script>
+       <script src="../../external/globalize.culture.de-DE.js"></script>
+       <script src="../../external/globalize.culture.ja-JP.js"></script>
        <script src="../../ui/jquery.ui.core.js"></script>
        <script src="../../ui/jquery.ui.widget.js"></script>
        <script src="../../ui/jquery.ui.button.js"></script>
@@ -18,7 +18,7 @@
        $(function() {
                $( "#currency" ).change(function() {
                        var current = $( "#spinner" ).spinner( "value" );
-                       $.global.preferCulture( $(this).val() );
+                       Globalize.culture( $(this).val() );
                        $( "#spinner" ).spinner( "value", current );
                });
 
@@ -28,7 +28,7 @@
                        step: 25,
                        start: 1000,
                        numberFormat: "C"
-               });     
+               });
        });
        </script>
 </head>
@@ -42,7 +42,7 @@
                <option value="en-US">US $</option>
                <option value="de-DE">EUR €</option>
                <option value="ja-JP">YEN ¥</option>
-       </select>       
+       </select>
 </p>
 <p>
        <label for="spinner">Amount to donate:</label>
index 70e0e99fdb4b8824412ef0d462f9454daa495ee1..9d96613fe1887dac4249feb56abecf9d0cb3a1e8 100644 (file)
@@ -6,9 +6,9 @@
        <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
        <script src="../../jquery-1.6.2.js"></script>
        <script src="../../external/jquery.mousewheel-3.0.4.js"></script>
-       <script src="../../external/jquery.global.js"></script>
-       <script src="../../external/jquery.global.de-DE.js"></script>
-       <script src="../../external/jquery.global.ja-JP.js"></script>
+       <script src="../../external/globalize.js"></script>
+       <script src="../../external/globalize.culture.de-DE.js"></script>
+       <script src="../../external/globalize.culture.ja-JP.js"></script>
        <script src="../../ui/jquery.ui.core.js"></script>
        <script src="../../ui/jquery.ui.widget.js"></script>
        <script src="../../ui/jquery.ui.button.js"></script>
                $( "#spinner" ).spinner({
                        step: 0.01,
                        numberFormat: "n"
-               });     
+               });
 
                $( "#culture" ).change(function() {
                        var current = $( "#spinner" ).spinner( "value" );
-                       $.global.preferCulture( $(this).val() );
+                       Globalize.culture( $(this).val() );
                        $( "#spinner" ).spinner( "value", current );
                });
        });
index 5a3c3767ea75eadb14542a13311402e6a515030b..860ae3f482db8dca92a787b00d34adc5a5b997b3 100644 (file)
@@ -6,8 +6,8 @@
        <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
        <script src="../../jquery-1.6.2.js"></script>
        <script src="../../external/jquery.mousewheel-3.0.4.js"></script>
-       <script src="../../external/jquery.global.js"></script>
-       <script src="../../external/jquery.global.de-DE.js"></script>
+       <script src="../../external/globalize.js"></script>
+       <script src="../../external/globalize.culture.de-DE.js"></script>
        <script src="../../ui/jquery.ui.core.js"></script>
        <script src="../../ui/jquery.ui.widget.js"></script>
        <script src="../../ui/jquery.ui.button.js"></script>
 
                _parse: function( value ) {
                        if ( typeof value === "string" ) {
-                               return +$.global.parseDate( value );
+                               return +Globalize.parseDate( value );
                        }
                        return value;
                },
 
                _format: function() {
-                       this.element.val( $.global.format( new Date(this.options.value), "t" ) );
+                       this.element.val( Globalize.format( new Date(this.options.value), "t" ) );
                }
        });
 
@@ -39,7 +39,7 @@
 
                $( "#culture" ).change(function() {
                        var current = $( "#spinner" ).timespinner( "value" );
-                       $.global.preferCulture( $(this).val() );
+                       Globalize.culture( $(this).val() );
                        $( "#spinner" ).timespinner( "value", current );
                });
        });
diff --git a/external/globalize.culture.de-DE.js b/external/globalize.culture.de-DE.js
new file mode 100644 (file)
index 0000000..5466bd7
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Globalize Culture de-DE
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * This file was generated by the Globalize Culture Generator
+ * Translation: bugs found in this file need to be fixed in the generator
+ */
+
+(function( window, undefined ) {
+
+var Globalize;
+
+if ( typeof require !== "undefined"
+       && typeof exports !== "undefined"
+       && typeof module !== "undefined" ) {
+       // Assume CommonJS
+       Globalize = require( "globalize" );
+} else {
+       // Global variable
+       Globalize = window.Globalize;
+}
+
+Globalize.addCultureInfo( "de-DE", "default", {
+       name: "de-DE",
+       englishName: "German (Germany)",
+       nativeName: "Deutsch (Deutschland)",
+       language: "de",
+       numberFormat: {
+               ",": ".",
+               ".": ",",
+               NaN: "n. def.",
+               negativeInfinity: "-unendlich",
+               positiveInfinity: "+unendlich",
+               percent: {
+                       pattern: ["-n%","n%"],
+                       ",": ".",
+                       ".": ","
+               },
+               currency: {
+                       pattern: ["-n $","n $"],
+                       ",": ".",
+                       ".": ",",
+                       symbol: "€"
+               }
+       },
+       calendars: {
+               standard: {
+                       "/": ".",
+                       firstDay: 1,
+                       days: {
+                               names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],
+                               namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"],
+                               namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"]
+                       },
+                       months: {
+                               names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],
+                               namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""]
+                       },
+                       AM: null,
+                       PM: null,
+                       eras: [{"name":"n. Chr.","start":null,"offset":0}],
+                       patterns: {
+                               d: "dd.MM.yyyy",
+                               D: "dddd, d. MMMM yyyy",
+                               t: "HH:mm",
+                               T: "HH:mm:ss",
+                               f: "dddd, d. MMMM yyyy HH:mm",
+                               F: "dddd, d. MMMM yyyy HH:mm:ss",
+                               M: "dd MMMM",
+                               Y: "MMMM yyyy"
+                       }
+               }
+       }
+});
+
+}( this ));
diff --git a/external/globalize.culture.ja-JP.js b/external/globalize.culture.ja-JP.js
new file mode 100644 (file)
index 0000000..a9469d7
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Globalize Culture ja-JP
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * This file was generated by the Globalize Culture Generator
+ * Translation: bugs found in this file need to be fixed in the generator
+ */
+
+(function( window, undefined ) {
+
+var Globalize;
+
+if ( typeof require !== "undefined"
+       && typeof exports !== "undefined"
+       && typeof module !== "undefined" ) {
+       // Assume CommonJS
+       Globalize = require( "globalize" );
+} else {
+       // Global variable
+       Globalize = window.Globalize;
+}
+
+Globalize.addCultureInfo( "ja-JP", "default", {
+       name: "ja-JP",
+       englishName: "Japanese (Japan)",
+       nativeName: "日本語 (日本)",
+       language: "ja",
+       numberFormat: {
+               NaN: "NaN (非数値)",
+               negativeInfinity: "-∞",
+               positiveInfinity: "+∞",
+               percent: {
+                       pattern: ["-n%","n%"]
+               },
+               currency: {
+                       pattern: ["-$n","$n"],
+                       decimals: 0,
+                       symbol: "¥"
+               }
+       },
+       calendars: {
+               standard: {
+                       days: {
+                               names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
+                               namesAbbr: ["日","月","火","水","木","金","土"],
+                               namesShort: ["日","月","火","水","木","金","土"]
+                       },
+                       months: {
+                               names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],
+                               namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""]
+                       },
+                       AM: ["午前","午前","午前"],
+                       PM: ["午後","午後","午後"],
+                       eras: [{"name":"西暦","start":null,"offset":0}],
+                       patterns: {
+                               d: "yyyy/MM/dd",
+                               D: "yyyy'年'M'月'd'日'",
+                               t: "H:mm",
+                               T: "H:mm:ss",
+                               f: "yyyy'年'M'月'd'日' H:mm",
+                               F: "yyyy'年'M'月'd'日' H:mm:ss",
+                               M: "M'月'd'日'",
+                               Y: "yyyy'年'M'月'"
+                       }
+               },
+               Japanese: {
+                       name: "Japanese",
+                       days: {
+                               names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
+                               namesAbbr: ["日","月","火","水","木","金","土"],
+                               namesShort: ["日","月","火","水","木","金","土"]
+                       },
+                       months: {
+                               names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],
+                               namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""]
+                       },
+                       AM: ["午前","午前","午前"],
+                       PM: ["午後","午後","午後"],
+                       eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}],
+                       twoDigitYearMax: 99,
+                       patterns: {
+                               d: "gg y/M/d",
+                               D: "gg y'年'M'月'd'日'",
+                               t: "H:mm",
+                               T: "H:mm:ss",
+                               f: "gg y'年'M'月'd'日' H:mm",
+                               F: "gg y'年'M'月'd'日' H:mm:ss",
+                               M: "M'月'd'日'",
+                               Y: "gg y'年'M'月'"
+                       }
+               }
+       }
+});
+
+}( this ));
diff --git a/external/globalize.js b/external/globalize.js
new file mode 100644 (file)
index 0000000..ebaca17
--- /dev/null
@@ -0,0 +1,1573 @@
+/*!
+ * Globalize
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ */
+
+(function( window, undefined ) {
+
+var Globalize,
+       // private variables
+       regexHex,
+       regexInfinity,
+       regexParseFloat,
+       regexTrim,
+       // private JavaScript utility functions
+       arrayIndexOf,
+       endsWith,
+       extend,
+       isArray,
+       isFunction,
+       isObject,
+       startsWith,
+       trim,
+       truncate,
+       zeroPad,
+       // private Globalization utility functions
+       appendPreOrPostMatch,
+       expandFormat,
+       formatDate,
+       formatNumber,
+       getTokenRegExp,
+       getEra,
+       getEraYear,
+       parseExact,
+       parseNegativePattern;
+
+// Global variable (Globalize) or CommonJS module (globalize)
+Globalize = function( cultureSelector ) {
+       return new Globalize.prototype.init( cultureSelector );
+};
+
+if ( typeof require !== "undefined"
+       && typeof exports !== "undefined"
+       && typeof module !== "undefined" ) {
+       // Assume CommonJS
+       module.exports = Globalize;
+} else {
+       // Export as global variable
+       window.Globalize = Globalize;
+}
+
+Globalize.cultures = {};
+
+Globalize.prototype = {
+       constructor: Globalize,
+       init: function( cultureSelector ) {
+               this.cultures = Globalize.cultures;
+               this.cultureSelector = cultureSelector;
+
+               return this;
+       }
+};
+Globalize.prototype.init.prototype = Globalize.prototype;
+
+// 1.   When defining a culture, all fields are required except the ones stated as optional.
+// 2.   Each culture should have a ".calendars" object with at least one calendar named "standard"
+//              which serves as the default calendar in use by that culture.
+// 3.   Each culture should have a ".calendar" object which is the current calendar being used,
+//              it may be dynamically changed at any time to one of the calendars in ".calendars".
+Globalize.cultures[ "default" ] = {
+       // A unique name for the culture in the form <language code>-<country/region code>
+       name: "en",
+       // the name of the culture in the english language
+       englishName: "English",
+       // the name of the culture in its own language
+       nativeName: "English",
+       // whether the culture uses right-to-left text
+       isRTL: false,
+       // "language" is used for so-called "specific" cultures.
+       // For example, the culture "es-CL" means "Spanish, in Chili".
+       // It represents the Spanish-speaking culture as it is in Chili,
+       // which might have different formatting rules or even translations
+       // than Spanish in Spain. A "neutral" culture is one that is not
+       // specific to a region. For example, the culture "es" is the generic
+       // Spanish culture, which may be a more generalized version of the language
+       // that may or may not be what a specific culture expects.
+       // For a specific culture like "es-CL", the "language" field refers to the
+       // neutral, generic culture information for the language it is using.
+       // This is not always a simple matter of the string before the dash.
+       // For example, the "zh-Hans" culture is netural (Simplified Chinese).
+       // And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage
+       // field is "zh-CHS", not "zh".
+       // This field should be used to navigate from a specific culture to it's
+       // more general, neutral culture. If a culture is already as general as it
+       // can get, the language may refer to itself.
+       language: "en",
+       // numberFormat defines general number formatting rules, like the digits in
+       // each grouping, the group separator, and how negative numbers are displayed.
+       numberFormat: {
+               // [negativePattern]
+               // Note, numberFormat.pattern has no "positivePattern" unlike percent and currency,
+               // but is still defined as an array for consistency with them.
+               //   negativePattern: one of "(n)|-n|- n|n-|n -"
+               pattern: [ "-n" ],
+               // number of decimal places normally shown
+               decimals: 2,
+               // string that separates number groups, as in 1,000,000
+               ",": ",",
+               // string that separates a number from the fractional portion, as in 1.99
+               ".": ".",
+               // array of numbers indicating the size of each number group.
+               // TODO: more detailed description and example
+               groupSizes: [ 3 ],
+               // symbol used for positive numbers
+               "+": "+",
+               // symbol used for negative numbers
+               "-": "-",
+               // symbol used for NaN (Not-A-Number)
+               NaN: "NaN",
+               // symbol used for Negative Infinity
+               negativeInfinity: "-Infinity",
+               // symbol used for Positive Infinity
+               positiveInfinity: "Infinity",
+               percent: {
+                       // [negativePattern, positivePattern]
+                       //   negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %"
+                       //   positivePattern: one of "n %|n%|%n|% n"
+                       pattern: [ "-n %", "n %" ],
+                       // number of decimal places normally shown
+                       decimals: 2,
+                       // array of numbers indicating the size of each number group.
+                       // TODO: more detailed description and example
+                       groupSizes: [ 3 ],
+                       // string that separates number groups, as in 1,000,000
+                       ",": ",",
+                       // string that separates a number from the fractional portion, as in 1.99
+                       ".": ".",
+                       // symbol used to represent a percentage
+                       symbol: "%"
+               },
+               currency: {
+                       // [negativePattern, positivePattern]
+                       //   negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)"
+                       //   positivePattern: one of "$n|n$|$ n|n $"
+                       pattern: [ "($n)", "$n" ],
+                       // number of decimal places normally shown
+                       decimals: 2,
+                       // array of numbers indicating the size of each number group.
+                       // TODO: more detailed description and example
+                       groupSizes: [ 3 ],
+                       // string that separates number groups, as in 1,000,000
+                       ",": ",",
+                       // string that separates a number from the fractional portion, as in 1.99
+                       ".": ".",
+                       // symbol used to represent currency
+                       symbol: "$"
+               }
+       },
+       // calendars defines all the possible calendars used by this culture.
+       // There should be at least one defined with name "standard", and is the default
+       // calendar used by the culture.
+       // A calendar contains information about how dates are formatted, information about
+       // the calendar's eras, a standard set of the date formats,
+       // translations for day and month names, and if the calendar is not based on the Gregorian
+       // calendar, conversion functions to and from the Gregorian calendar.
+       calendars: {
+               standard: {
+                       // name that identifies the type of calendar this is
+                       name: "Gregorian_USEnglish",
+                       // separator of parts of a date (e.g. "/" in 11/05/1955)
+                       "/": "/",
+                       // separator of parts of a time (e.g. ":" in 05:44 PM)
+                       ":": ":",
+                       // the first day of the week (0 = Sunday, 1 = Monday, etc)
+                       firstDay: 0,
+                       days: {
+                               // full day names
+                               names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
+                               // abbreviated day names
+                               namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
+                               // shortest day names
+                               namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]
+                       },
+                       months: {
+                               // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar)
+                               names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ],
+                               // abbreviated month names
+                               namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ]
+                       },
+                       // AM and PM designators in one of these forms:
+                       // The usual view, and the upper and lower case versions
+                       //   [ standard, lowercase, uppercase ]
+                       // The culture does not use AM or PM (likely all standard date formats use 24 hour time)
+                       //   null
+                       AM: [ "AM", "am", "AM" ],
+                       PM: [ "PM", "pm", "PM" ],
+                       eras: [
+                               // eras in reverse chronological order.
+                               // name: the name of the era in this culture (e.g. A.D., C.E.)
+                               // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era.
+                               // offset: offset in years from gregorian calendar
+                               {
+                                       "name": "A.D.",
+                                       "start": null,
+                                       "offset": 0
+                               }
+                       ],
+                       // when a two digit year is given, it will never be parsed as a four digit
+                       // year greater than this year (in the appropriate era for the culture)
+                       // Set it as a full year (e.g. 2029) or use an offset format starting from
+                       // the current year: "+19" would correspond to 2029 if the current year 2010.
+                       twoDigitYearMax: 2029,
+                       // set of predefined date and time patterns used by the culture
+                       // these represent the format someone in this culture would expect
+                       // to see given the portions of the date that are shown.
+                       patterns: {
+                               // short date pattern
+                               d: "M/d/yyyy",
+                               // long date pattern
+                               D: "dddd, MMMM dd, yyyy",
+                               // short time pattern
+                               t: "h:mm tt",
+                               // long time pattern
+                               T: "h:mm:ss tt",
+                               // long date, short time pattern
+                               f: "dddd, MMMM dd, yyyy h:mm tt",
+                               // long date, long time pattern
+                               F: "dddd, MMMM dd, yyyy h:mm:ss tt",
+                               // month/day pattern
+                               M: "MMMM dd",
+                               // month/year pattern
+                               Y: "yyyy MMMM",
+                               // S is a sortable format that does not vary by culture
+                               S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss"
+                       }
+                       // optional fields for each calendar:
+                       /*
+                       monthsGenitive:
+                               Same as months but used when the day preceeds the month.
+                               Omit if the culture has no genitive distinction in month names.
+                               For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx
+                       convert:
+                               Allows for the support of non-gregorian based calendars. This convert object is used to
+                               to convert a date to and from a gregorian calendar date to handle parsing and formatting.
+                               The two functions:
+                                       fromGregorian( date )
+                                               Given the date as a parameter, return an array with parts [ year, month, day ]
+                                               corresponding to the non-gregorian based year, month, and day for the calendar.
+                                       toGregorian( year, month, day )
+                                               Given the non-gregorian year, month, and day, return a new Date() object
+                                               set to the corresponding date in the gregorian calendar.
+                       */
+               }
+       },
+       // For localized strings
+       messages: {}
+};
+
+Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard;
+
+Globalize.cultures[ "en" ] = Globalize.cultures[ "default" ];
+
+Globalize.cultureSelector = "en";
+
+//
+// private variables
+//
+
+regexHex = /^0x[a-f0-9]+$/i;
+regexInfinity = /^[+-]?infinity$/i;
+regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/;
+regexTrim = /^\s+|\s+$/g;
+
+//
+// private JavaScript utility functions
+//
+
+arrayIndexOf = function( array, item ) {
+       if ( array.indexOf ) {
+               return array.indexOf( item );
+       }
+       for ( var i = 0, length = array.length; i < length; i++ ) {
+               if ( array[i] === item ) {
+                       return i;
+               }
+       }
+       return -1;
+};
+
+endsWith = function( value, pattern ) {
+       return value.substr( value.length - pattern.length ) === pattern;
+};
+
+extend = function( deep ) {
+       var options, name, src, copy, copyIsArray, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+               target = arguments[1] || {};
+               // skip the boolean and the target
+               i = 2;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !isFunction(target) ) {
+               target = {};
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) {
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && isArray(src) ? src : [];
+
+                                       } else {
+                                               clone = src && isObject(src) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+isArray = Array.isArray || function( obj ) {
+       return Object.prototype.toString.call( obj ) === "[object Array]";
+};
+
+isFunction = function( obj ) {
+       return Object.prototype.toString.call( obj ) === "[object Function]"
+}
+
+isObject = function( obj ) {
+       return Object.prototype.toString.call( obj ) === "[object Object]";
+};
+
+startsWith = function( value, pattern ) {
+       return value.indexOf( pattern ) === 0;
+};
+
+trim = function( value ) {
+       return ( value + "" ).replace( regexTrim, "" );
+};
+
+truncate = function( value ) {
+       return value | 0;
+};
+
+zeroPad = function( str, count, left ) {
+       var l;
+       for ( l = str.length; l < count; l += 1 ) {
+               str = ( left ? ("0" + str) : (str + "0") );
+       }
+       return str;
+};
+
+//
+// private Globalization utility functions
+//
+
+appendPreOrPostMatch = function( preMatch, strings ) {
+       // appends pre- and post- token match strings while removing escaped characters.
+       // Returns a single quote count which is used to determine if the token occurs
+       // in a string literal.
+       var quoteCount = 0,
+               escaped = false;
+       for ( var i = 0, il = preMatch.length; i < il; i++ ) {
+               var c = preMatch.charAt( i );
+               switch ( c ) {
+                       case "\'":
+                               if ( escaped ) {
+                                       strings.push( "\'" );
+                               }
+                               else {
+                                       quoteCount++;
+                               }
+                               escaped = false;
+                               break;
+                       case "\\":
+                               if ( escaped ) {
+                                       strings.push( "\\" );
+                               }
+                               escaped = !escaped;
+                               break;
+                       default:
+                               strings.push( c );
+                               escaped = false;
+                               break;
+               }
+       }
+       return quoteCount;
+};
+
+expandFormat = function( cal, format ) {
+       // expands unspecified or single character date formats into the full pattern.
+       format = format || "F";
+       var pattern,
+               patterns = cal.patterns,
+               len = format.length;
+       if ( len === 1 ) {
+               pattern = patterns[ format ];
+               if ( !pattern ) {
+                       throw "Invalid date format string \'" + format + "\'.";
+               }
+               format = pattern;
+       }
+       else if ( len === 2 && format.charAt(0) === "%" ) {
+               // %X escape format -- intended as a custom format string that is only one character, not a built-in format.
+               format = format.charAt( 1 );
+       }
+       return format;
+};
+
+formatDate = function( value, format, culture ) {
+       var cal = culture.calendar,
+               convert = cal.convert;
+
+       if ( !format || !format.length || format === "i" ) {
+               var ret;
+               if ( culture && culture.name.length ) {
+                       if ( convert ) {
+                               // non-gregorian calendar, so we cannot use built-in toLocaleString()
+                               ret = formatDate( value, cal.patterns.F, culture );
+                       }
+                       else {
+                               var eraDate = new Date( value.getTime() ),
+                                       era = getEra( value, cal.eras );
+                               eraDate.setFullYear( getEraYear(value, cal, era) );
+                               ret = eraDate.toLocaleString();
+                       }
+               }
+               else {
+                       ret = value.toString();
+               }
+               return ret;
+       }
+
+       var eras = cal.eras,
+               sortable = format === "s";
+       format = expandFormat( cal, format );
+
+       // Start with an empty string
+       ret = [];
+       var hour,
+               zeros = [ "0", "00", "000" ],
+               foundDay,
+               checkedDay,
+               dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g,
+               quoteCount = 0,
+               tokenRegExp = getTokenRegExp(),
+               converted;
+
+       function padZeros( num, c ) {
+               var r, s = num + "";
+               if ( c > 1 && s.length < c ) {
+                       r = ( zeros[c - 2] + s);
+                       return r.substr( r.length - c, c );
+               }
+               else {
+                       r = s;
+               }
+               return r;
+       }
+
+       function hasDay() {
+               if ( foundDay || checkedDay ) {
+                       return foundDay;
+               }
+               foundDay = dayPartRegExp.test( format );
+               checkedDay = true;
+               return foundDay;
+       }
+
+       function getPart( date, part ) {
+               if ( converted ) {
+                       return converted[ part ];
+               }
+               switch ( part ) {
+                       case 0: return date.getFullYear();
+                       case 1: return date.getMonth();
+                       case 2: return date.getDate();
+               }
+       }
+
+       if ( !sortable && convert ) {
+               converted = convert.fromGregorian( value );
+       }
+
+       for ( ; ; ) {
+               // Save the current index
+               var index = tokenRegExp.lastIndex,
+                       // Look for the next pattern
+                       ar = tokenRegExp.exec( format );
+
+               // Append the text before the pattern (or the end of the string if not found)
+               var preMatch = format.slice( index, ar ? ar.index : format.length );
+               quoteCount += appendPreOrPostMatch( preMatch, ret );
+
+               if ( !ar ) {
+                       break;
+               }
+
+               // do not replace any matches that occur inside a string literal.
+               if ( quoteCount % 2 ) {
+                       ret.push( ar[0] );
+                       continue;
+               }
+
+               var current = ar[ 0 ],
+                       clength = current.length;
+
+               switch ( current ) {
+                       case "ddd":
+                               //Day of the week, as a three-letter abbreviation
+                       case "dddd":
+                               // Day of the week, using the full name
+                               var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names;
+                               ret.push( names[value.getDay()] );
+                               break;
+                       case "d":
+                               // Day of month, without leading zero for single-digit days
+                       case "dd":
+                               // Day of month, with leading zero for single-digit days
+                               foundDay = true;
+                               ret.push(
+                                       padZeros( getPart(value, 2), clength )
+                               );
+                               break;
+                       case "MMM":
+                               // Month, as a three-letter abbreviation
+                       case "MMMM":
+                               // Month, using the full name
+                               var part = getPart( value, 1 );
+                               ret.push(
+                                       ( cal.monthsGenitive && hasDay() )
+                                       ?
+                                       cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ]
+                                       :
+                                       cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ]
+                               );
+                               break;
+                       case "M":
+                               // Month, as digits, with no leading zero for single-digit months
+                       case "MM":
+                               // Month, as digits, with leading zero for single-digit months
+                               ret.push(
+                                       padZeros( getPart(value, 1) + 1, clength )
+                               );
+                               break;
+                       case "y":
+                               // Year, as two digits, but with no leading zero for years less than 10
+                       case "yy":
+                               // Year, as two digits, with leading zero for years less than 10
+                       case "yyyy":
+                               // Year represented by four full digits
+                               part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable );
+                               if ( clength < 4 ) {
+                                       part = part % 100;
+                               }
+                               ret.push(
+                                       padZeros( part, clength )
+                               );
+                               break;
+                       case "h":
+                               // Hours with no leading zero for single-digit hours, using 12-hour clock
+                       case "hh":
+                               // Hours with leading zero for single-digit hours, using 12-hour clock
+                               hour = value.getHours() % 12;
+                               if ( hour === 0 ) hour = 12;
+                               ret.push(
+                                       padZeros( hour, clength )
+                               );
+                               break;
+                       case "H":
+                               // Hours with no leading zero for single-digit hours, using 24-hour clock
+                       case "HH":
+                               // Hours with leading zero for single-digit hours, using 24-hour clock
+                               ret.push(
+                                       padZeros( value.getHours(), clength )
+                               );
+                               break;
+                       case "m":
+                               // Minutes with no leading zero for single-digit minutes
+                       case "mm":
+                               // Minutes with leading zero for single-digit minutes
+                               ret.push(
+                                       padZeros( value.getMinutes(), clength )
+                               );
+                               break;
+                       case "s":
+                               // Seconds with no leading zero for single-digit seconds
+                       case "ss":
+                               // Seconds with leading zero for single-digit seconds
+                               ret.push(
+                                       padZeros( value.getSeconds(), clength )
+                               );
+                               break;
+                       case "t":
+                               // One character am/pm indicator ("a" or "p")
+                       case "tt":
+                               // Multicharacter am/pm indicator
+                               part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " );
+                               ret.push( clength === 1 ? part.charAt(0) : part );
+                               break;
+                       case "f":
+                               // Deciseconds
+                       case "ff":
+                               // Centiseconds
+                       case "fff":
+                               // Milliseconds
+                               ret.push(
+                                       padZeros( value.getMilliseconds(), 3 ).substr( 0, clength )
+                               );
+                               break;
+                       case "z":
+                               // Time zone offset, no leading zero
+                       case "zz":
+                               // Time zone offset with leading zero
+                               hour = value.getTimezoneOffset() / 60;
+                               ret.push(
+                                       ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength )
+                               );
+                               break;
+                       case "zzz":
+                               // Time zone offset with leading zero
+                               hour = value.getTimezoneOffset() / 60;
+                               ret.push(
+                                       ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 )
+                                       // Hard coded ":" separator, rather than using cal.TimeSeparator
+                                       // Repeated here for consistency, plus ":" was already assumed in date parsing.
+                                       + ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 )
+                               );
+                               break;
+                       case "g":
+                       case "gg":
+                               if ( cal.eras ) {
+                                       ret.push(
+                                               cal.eras[ getEra(value, eras) ].name
+                                       );
+                               }
+                               break;
+               case "/":
+                       ret.push( cal["/"] );
+                       break;
+               default:
+                       throw "Invalid date format pattern \'" + current + "\'.";
+                       break;
+               }
+       }
+       return ret.join( "" );
+};
+
+// formatNumber
+(function() {
+       var expandNumber;
+
+       expandNumber = function( number, precision, formatInfo ) {
+               var groupSizes = formatInfo.groupSizes,
+                       curSize = groupSizes[ 0 ],
+                       curGroupIndex = 1,
+                       factor = Math.pow( 10, precision ),
+                       rounded = Math.round( number * factor ) / factor;
+
+               if ( !isFinite(rounded) ) {
+                       rounded = number;
+               }
+               number = rounded;
+
+               var numberString = number+"",
+                       right = "",
+                       split = numberString.split( /e/i ),
+                       exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0;
+               numberString = split[ 0 ];
+               split = numberString.split( "." );
+               numberString = split[ 0 ];
+               right = split.length > 1 ? split[ 1 ] : "";
+
+               var l;
+               if ( exponent > 0 ) {
+                       right = zeroPad( right, exponent, false );
+                       numberString += right.slice( 0, exponent );
+                       right = right.substr( exponent );
+               }
+               else if ( exponent < 0 ) {
+                       exponent = -exponent;
+                       numberString = zeroPad( numberString, exponent + 1 );
+                       right = numberString.slice( -exponent, numberString.length ) + right;
+                       numberString = numberString.slice( 0, -exponent );
+               }
+
+               if ( precision > 0 ) {
+                       right = formatInfo[ "." ] +
+                               ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) );
+               }
+               else {
+                       right = "";
+               }
+
+               var stringIndex = numberString.length - 1,
+                       sep = formatInfo[ "," ],
+                       ret = "";
+
+               while ( stringIndex >= 0 ) {
+                       if ( curSize === 0 || curSize > stringIndex ) {
+                               return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right );
+                       }
+                       ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" );
+
+                       stringIndex -= curSize;
+
+                       if ( curGroupIndex < groupSizes.length ) {
+                               curSize = groupSizes[ curGroupIndex ];
+                               curGroupIndex++;
+                       }
+               }
+
+               return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right;
+       };
+
+       formatNumber = function( value, format, culture ) {
+               if ( !isFinite(value) ) {
+                       if ( value === Infinity ) {
+                               return culture.numberFormat.positiveInfinity;
+                       }
+                       if ( value === -Infinity ) {
+                               return culture.numberFormat.negativeInfinity;
+                       }
+                       return culture.numberFormat.NaN;
+               }
+               if ( !format || format === "i" ) {
+                       return culture.name.length ? value.toLocaleString() : value.toString();
+               }
+               format = format || "D";
+
+               var nf = culture.numberFormat,
+                       number = Math.abs( value ),
+                       precision = -1,
+                       pattern;
+               if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 );
+
+               var current = format.charAt( 0 ).toUpperCase(),
+                       formatInfo;
+
+               switch ( current ) {
+                       case "D":
+                               pattern = "n";
+                               number = truncate( number );
+                               if ( precision !== -1 ) {
+                                       number = zeroPad( "" + number, precision, true );
+                               }
+                               if ( value < 0 ) number = "-" + number;
+                               break;
+                       case "N":
+                               formatInfo = nf;
+                               // fall through
+                       case "C":
+                               formatInfo = formatInfo || nf.currency;
+                               // fall through
+                       case "P":
+                               formatInfo = formatInfo || nf.percent;
+                               pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" );
+                               if ( precision === -1 ) precision = formatInfo.decimals;
+                               number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo );
+                               break;
+                       default:
+                               throw "Bad number format specifier: " + current;
+               }
+
+               var patternParts = /n|\$|-|%/g,
+                       ret = "";
+               for ( ; ; ) {
+                       var index = patternParts.lastIndex,
+                               ar = patternParts.exec( pattern );
+
+                       ret += pattern.slice( index, ar ? ar.index : pattern.length );
+
+                       if ( !ar ) {
+                               break;
+                       }
+
+                       switch ( ar[0] ) {
+                               case "n":
+                                       ret += number;
+                                       break;
+                               case "$":
+                                       ret += nf.currency.symbol;
+                                       break;
+                               case "-":
+                                       // don't make 0 negative
+                                       if ( /[1-9]/.test(number) ) {
+                                               ret += nf[ "-" ];
+                                       }
+                                       break;
+                               case "%":
+                                       ret += nf.percent.symbol;
+                                       break;
+                       }
+               }
+
+               return ret;
+       };
+
+}());
+
+getTokenRegExp = function() {
+       // regular expression for matching date and time tokens in format strings.
+       return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g;
+};
+
+getEra = function( date, eras ) {
+       if ( !eras ) return 0;
+       var start, ticks = date.getTime();
+       for ( var i = 0, l = eras.length; i < l; i++ ) {
+               start = eras[ i ].start;
+               if ( start === null || ticks >= start ) {
+                       return i;
+               }
+       }
+       return 0;
+};
+
+getEraYear = function( date, cal, era, sortable ) {
+       var year = date.getFullYear();
+       if ( !sortable && cal.eras ) {
+               // convert normal gregorian year to era-shifted gregorian
+               // year by subtracting the era offset
+               year -= cal.eras[ era ].offset;
+       }
+       return year;
+};
+
+// parseExact
+(function() {
+       var expandYear,
+               getDayIndex,
+               getMonthIndex,
+               getParseRegExp,
+               outOfRange,
+               toUpper,
+               toUpperArray;
+
+       expandYear = function( cal, year ) {
+               // expands 2-digit year into 4 digits.
+               var now = new Date(),
+                       era = getEra( now );
+               if ( year < 100 ) {
+                       var twoDigitYearMax = cal.twoDigitYearMax;
+                       twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
+                       var curr = getEraYear( now, cal, era );
+                       year += curr - ( curr % 100 );
+                       if ( year > twoDigitYearMax ) {
+                               year -= 100;
+                       }
+               }
+               return year;
+       };
+
+       getDayIndex = function  ( cal, value, abbr ) {
+               var ret,
+                       days = cal.days,
+                       upperDays = cal._upperDays;
+               if ( !upperDays ) {
+                       cal._upperDays = upperDays = [
+                               toUpperArray( days.names ),
+                               toUpperArray( days.namesAbbr ),
+                               toUpperArray( days.namesShort )
+                       ];
+               }
+               value = toUpper( value );
+               if ( abbr ) {
+                       ret = arrayIndexOf( upperDays[1], value );
+                       if ( ret === -1 ) {
+                               ret = arrayIndexOf( upperDays[2], value );
+                       }
+               }
+               else {
+                       ret = arrayIndexOf( upperDays[0], value );
+               }
+               return ret;
+       };
+
+       getMonthIndex = function( cal, value, abbr ) {
+               var months = cal.months,
+                       monthsGen = cal.monthsGenitive || cal.months,
+                       upperMonths = cal._upperMonths,
+                       upperMonthsGen = cal._upperMonthsGen;
+               if ( !upperMonths ) {
+                       cal._upperMonths = upperMonths = [
+                               toUpperArray( months.names ),
+                               toUpperArray( months.namesAbbr )
+                       ];
+                       cal._upperMonthsGen = upperMonthsGen = [
+                               toUpperArray( monthsGen.names ),
+                               toUpperArray( monthsGen.namesAbbr )
+                       ];
+               }
+               value = toUpper( value );
+               var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value );
+               if ( i < 0 ) {
+                       i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value );
+               }
+               return i;
+       };
+
+       getParseRegExp = function( cal, format ) {
+               // converts a format string into a regular expression with groups that
+               // can be used to extract date fields from a date string.
+               // check for a cached parse regex.
+               var re = cal._parseRegExp;
+               if ( !re ) {
+                       cal._parseRegExp = re = {};
+               }
+               else {
+                       var reFormat = re[ format ];
+                       if ( reFormat ) {
+                               return reFormat;
+                       }
+               }
+
+               // expand single digit formats, then escape regular expression characters.
+               var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ),
+                       regexp = [ "^" ],
+                       groups = [],
+                       index = 0,
+                       quoteCount = 0,
+                       tokenRegExp = getTokenRegExp(),
+                       match;
+
+               // iterate through each date token found.
+               while ( (match = tokenRegExp.exec(expFormat)) !== null ) {
+                       var preMatch = expFormat.slice( index, match.index );
+                       index = tokenRegExp.lastIndex;
+
+                       // don't replace any matches that occur inside a string literal.
+                       quoteCount += appendPreOrPostMatch( preMatch, regexp );
+                       if ( quoteCount % 2 ) {
+                               regexp.push( match[0] );
+                               continue;
+                       }
+
+                       // add a regex group for the token.
+                       var m = match[ 0 ],
+                               len = m.length,
+                               add;
+                       switch ( m ) {
+                               case "dddd": case "ddd":
+                               case "MMMM": case "MMM":
+                               case "gg": case "g":
+                                       add = "(\\D+)";
+                                       break;
+                               case "tt": case "t":
+                                       add = "(\\D*)";
+                                       break;
+                               case "yyyy":
+                               case "fff":
+                               case "ff":
+                               case "f":
+                                       add = "(\\d{" + len + "})";
+                                       break;
+                               case "dd": case "d":
+                               case "MM": case "M":
+                               case "yy": case "y":
+                               case "HH": case "H":
+                               case "hh": case "h":
+                               case "mm": case "m":
+                               case "ss": case "s":
+                                       add = "(\\d\\d?)";
+                                       break;
+                               case "zzz":
+                                       add = "([+-]?\\d\\d?:\\d{2})";
+                                       break;
+                               case "zz": case "z":
+                                       add = "([+-]?\\d\\d?)";
+                                       break;
+                               case "/":
+                                       add = "(\\" + cal[ "/" ] + ")";
+                                       break;
+                               default:
+                                       throw "Invalid date format pattern \'" + m + "\'.";
+                                       break;
+                       }
+                       if ( add ) {
+                               regexp.push( add );
+                       }
+                       groups.push( match[0] );
+               }
+               appendPreOrPostMatch( expFormat.slice(index), regexp );
+               regexp.push( "$" );
+
+               // allow whitespace to differ when matching formats.
+               var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ),
+                       parseRegExp = { "regExp": regexpStr, "groups": groups };
+
+               // cache the regex for this format.
+               return re[ format ] = parseRegExp;
+       };
+
+       outOfRange = function( value, low, high ) {
+               return value < low || value > high;
+       };
+
+       toUpper = function( value ) {
+               // "he-IL" has non-breaking space in weekday names.
+               return value.split( "\u00A0" ).join( " " ).toUpperCase();
+       };
+
+       toUpperArray = function( arr ) {
+               var results = [];
+               for ( var i = 0, l = arr.length; i < l; i++ ) {
+                       results[ i ] = toUpper( arr[i] );
+               }
+               return results;
+       };
+
+       parseExact = function( value, format, culture ) {
+               // try to parse the date string by matching against the format string
+               // while using the specified culture for date field names.
+               value = trim( value );
+               var cal = culture.calendar,
+                       // convert date formats into regular expressions with groupings.
+                       // use the regexp to determine the input format and extract the date fields.
+                       parseInfo = getParseRegExp( cal, format ),
+                       match = new RegExp( parseInfo.regExp ).exec( value );
+               if ( match === null ) {
+                       return null;
+               }
+               // found a date format that matches the input.
+               var groups = parseInfo.groups,
+                       era = null, year = null, month = null, date = null, weekDay = null,
+                       hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null,
+                       pmHour = false;
+               // iterate the format groups to extract and set the date fields.
+               for ( var j = 0, jl = groups.length; j < jl; j++ ) {
+                       var matchGroup = match[ j + 1 ];
+                       if ( matchGroup ) {
+                               var current = groups[ j ],
+                                       clength = current.length,
+                                       matchInt = parseInt( matchGroup, 10 );
+                               switch ( current ) {
+                                       case "dd": case "d":
+                                               // Day of month.
+                                               date = matchInt;
+                                               // check that date is generally in valid range, also checking overflow below.
+                                               if ( outOfRange(date, 1, 31) ) return null;
+                                               break;
+                                       case "MMM": case "MMMM":
+                                               month = getMonthIndex( cal, matchGroup, clength === 3 );
+                                               if ( outOfRange(month, 0, 11) ) return null;
+                                               break;
+                                       case "M": case "MM":
+                                               // Month.
+                                               month = matchInt - 1;
+                                               if ( outOfRange(month, 0, 11) ) return null;
+                                               break;
+                                       case "y": case "yy":
+                                       case "yyyy":
+                                               year = clength < 4 ? expandYear( cal, matchInt ) : matchInt;
+                                               if ( outOfRange(year, 0, 9999) ) return null;
+                                               break;
+                                       case "h": case "hh":
+                                               // Hours (12-hour clock).
+                                               hour = matchInt;
+                                               if ( hour === 12 ) hour = 0;
+                                               if ( outOfRange(hour, 0, 11) ) return null;
+                                               break;
+                                       case "H": case "HH":
+                                               // Hours (24-hour clock).
+                                               hour = matchInt;
+                                               if ( outOfRange(hour, 0, 23) ) return null;
+                                               break;
+                                       case "m": case "mm":
+                                               // Minutes.
+                                               min = matchInt;
+                                               if ( outOfRange(min, 0, 59) ) return null;
+                                               break;
+                                       case "s": case "ss":
+                                               // Seconds.
+                                               sec = matchInt;
+                                               if ( outOfRange(sec, 0, 59) ) return null;
+                                               break;
+                                       case "tt": case "t":
+                                               // AM/PM designator.
+                                               // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of
+                                               // the AM tokens. If not, fail the parse for this format.
+                                               pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] );
+                                               if (
+                                                       !pmHour && (
+                                                               !cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] )
+                                                       )
+                                               ) return null;
+                                               break;
+                                       case "f":
+                                               // Deciseconds.
+                                       case "ff":
+                                               // Centiseconds.
+                                       case "fff":
+                                               // Milliseconds.
+                                               msec = matchInt * Math.pow( 10, 3 - clength );
+                                               if ( outOfRange(msec, 0, 999) ) return null;
+                                               break;
+                                       case "ddd":
+                                               // Day of week.
+                                       case "dddd":
+                                               // Day of week.
+                                               weekDay = getDayIndex( cal, matchGroup, clength === 3 );
+                                               if ( outOfRange(weekDay, 0, 6) ) return null;
+                                               break;
+                                       case "zzz":
+                                               // Time zone offset in +/- hours:min.
+                                               var offsets = matchGroup.split( /:/ );
+                                               if ( offsets.length !== 2 ) return null;
+                                               hourOffset = parseInt( offsets[0], 10 );
+                                               if ( outOfRange(hourOffset, -12, 13) ) return null;
+                                               var minOffset = parseInt( offsets[1], 10 );
+                                               if ( outOfRange(minOffset, 0, 59) ) return null;
+                                               tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset );
+                                               break;
+                                       case "z": case "zz":
+                                               // Time zone offset in +/- hours.
+                                               hourOffset = matchInt;
+                                               if ( outOfRange(hourOffset, -12, 13) ) return null;
+                                               tzMinOffset = hourOffset * 60;
+                                               break;
+                                       case "g": case "gg":
+                                               var eraName = matchGroup;
+                                               if ( !eraName || !cal.eras ) return null;
+                                               eraName = trim( eraName.toLowerCase() );
+                                               for ( var i = 0, l = cal.eras.length; i < l; i++ ) {
+                                                       if ( eraName === cal.eras[i].name.toLowerCase() ) {
+                                                               era = i;
+                                                               break;
+                                                       }
+                                               }
+                                               // could not find an era with that name
+                                               if ( era === null ) return null;
+                                               break;
+                               }
+                       }
+               }
+               var result = new Date(), defaultYear, convert = cal.convert;
+               defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear();
+               if ( year === null ) {
+                       year = defaultYear;
+               }
+               else if ( cal.eras ) {
+                       // year must be shifted to normal gregorian year
+                       // but not if year was not specified, its already normal gregorian
+                       // per the main if clause above.
+                       year += cal.eras[( era || 0 )].offset;
+               }
+               // set default day and month to 1 and January, so if unspecified, these are the defaults
+               // instead of the current day/month.
+               if ( month === null ) {
+                       month = 0;
+               }
+               if ( date === null ) {
+                       date = 1;
+               }
+               // now have year, month, and date, but in the culture's calendar.
+               // convert to gregorian if necessary
+               if ( convert ) {
+                       result = convert.toGregorian( year, month, date );
+                       // conversion failed, must be an invalid match
+                       if ( result === null ) return null;
+               }
+               else {
+                       // have to set year, month and date together to avoid overflow based on current date.
+                       result.setFullYear( year, month, date );
+                       // check to see if date overflowed for specified month (only checked 1-31 above).
+                       if ( result.getDate() !== date ) return null;
+                       // invalid day of week.
+                       if ( weekDay !== null && result.getDay() !== weekDay ) {
+                               return null;
+                       }
+               }
+               // if pm designator token was found make sure the hours fit the 24-hour clock.
+               if ( pmHour && hour < 12 ) {
+                       hour += 12;
+               }
+               result.setHours( hour, min, sec, msec );
+               if ( tzMinOffset !== null ) {
+                       // adjust timezone to utc before applying local offset.
+                       var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() );
+                       // Safari limits hours and minutes to the range of -127 to 127.  We need to use setHours
+                       // to ensure both these fields will not exceed this range.      adjustedMin will range
+                       // somewhere between -1440 and 1500, so we only need to split this into hours.
+                       result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 );
+               }
+               return result;
+       };
+}());
+
+parseNegativePattern = function( value, nf, negativePattern ) {
+       var neg = nf[ "-" ],
+               pos = nf[ "+" ],
+               ret;
+       switch ( negativePattern ) {
+               case "n -":
+                       neg = " " + neg;
+                       pos = " " + pos;
+                       // fall through
+               case "n-":
+                       if ( endsWith(value, neg) ) {
+                               ret = [ "-", value.substr(0, value.length - neg.length) ];
+                       }
+                       else if ( endsWith(value, pos) ) {
+                               ret = [ "+", value.substr(0, value.length - pos.length) ];
+                       }
+                       break;
+               case "- n":
+                       neg += " ";
+                       pos += " ";
+                       // fall through
+               case "-n":
+                       if ( startsWith(value, neg) ) {
+                               ret = [ "-", value.substr(neg.length) ];
+                       }
+                       else if ( startsWith(value, pos) ) {
+                               ret = [ "+", value.substr(pos.length) ];
+                       }
+                       break;
+               case "(n)":
+                       if ( startsWith(value, "(") && endsWith(value, ")") ) {
+                               ret = [ "-", value.substr(1, value.length - 2) ];
+                       }
+                       break;
+       }
+       return ret || [ "", value ];
+};
+
+//
+// public instance functions
+//
+
+Globalize.prototype.findClosestCulture = function( cultureSelector ) {
+       return Globalize.findClosestCulture.call( this, cultureSelector );
+};
+
+Globalize.prototype.format = function( value, format, cultureSelector ) {
+       return Globalize.format.call( this, value, format, cultureSelector );
+};
+
+Globalize.prototype.localize = function( key, cultureSelector ) {
+       return Globalize.localize.call( this, key, cultureSelector );
+};
+
+Globalize.prototype.parseInt = function( value, radix, cultureSelector ) {
+       return Globalize.parseInt.call( this, value, radix, cultureSelector );
+};
+
+Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) {
+       return Globalize.parseFloat.call( this, value, radix, cultureSelector );
+};
+
+Globalize.prototype.culture = function( cultureSelector ) {
+       return Globalize.culture.call( this, cultureSelector );
+};
+
+//
+// public singleton functions
+//
+
+Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) {
+
+       var base = {},
+               isNew = false;
+
+       if ( typeof cultureName !== "string" ) {
+               // cultureName argument is optional string. If not specified, assume info is first
+               // and only argument. Specified info deep-extends current culture.
+               info = cultureName;
+               cultureName = this.culture().name;
+               base = this.cultures[ cultureName ];
+       } else if ( typeof baseCultureName !== "string" ) {
+               // baseCultureName argument is optional string. If not specified, assume info is second
+               // argument. Specified info deep-extends specified culture.
+               // If specified culture does not exist, create by deep-extending default
+               info = baseCultureName;
+               isNew = ( this.cultures[ cultureName ] == null );
+               base = this.cultures[ cultureName ] || this.cultures[ "default" ];
+       } else {
+               // cultureName and baseCultureName specified. Assume a new culture is being created
+               // by deep-extending an specified base culture
+               isNew = true;
+               base = this.cultures[ baseCultureName ];
+       }
+
+       this.cultures[ cultureName ] = extend(true, {},
+               base,
+               info
+       );
+       // Make the standard calendar the current culture if it's a new culture
+       if ( isNew ) {
+               this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard;
+       }
+};
+
+Globalize.findClosestCulture = function( name ) {
+       var match;
+       if ( !name ) {
+               return this.cultures[ this.cultureSelector ] || this.cultures[ "default" ];
+       }
+       if ( typeof name === "string" ) {
+               name = name.split( "," );
+       }
+       if ( isArray(name) ) {
+               var lang,
+                       cultures = this.cultures,
+                       list = name,
+                       i, l = list.length,
+                       prioritized = [];
+               for ( i = 0; i < l; i++ ) {
+                       name = trim( list[i] );
+                       var pri, parts = name.split( ";" );
+                       lang = trim( parts[0] );
+                       if ( parts.length === 1 ) {
+                               pri = 1;
+                       }
+                       else {
+                               name = trim( parts[1] );
+                               if ( name.indexOf("q=") === 0 ) {
+                                       name = name.substr( 2 );
+                                       pri = parseFloat( name );
+                                       pri = isNaN( pri ) ? 0 : pri;
+                               }
+                               else {
+                                       pri = 1;
+                               }
+                       }
+                       prioritized.push({ lang: lang, pri: pri });
+               }
+               prioritized.sort(function( a, b ) {
+                       return a.pri < b.pri ? 1 : -1;
+               });
+
+               // exact match
+               for ( i = 0; i < l; i++ ) {
+                       lang = prioritized[ i ].lang;
+                       match = cultures[ lang ];
+                       if ( match ) {
+                               return match;
+                       }
+               }
+
+               // neutral language match
+               for ( i = 0; i < l; i++ ) {
+                       lang = prioritized[ i ].lang;
+                       do {
+                               var index = lang.lastIndexOf( "-" );
+                               if ( index === -1 ) {
+                                       break;
+                               }
+                               // strip off the last part. e.g. en-US => en
+                               lang = lang.substr( 0, index );
+                               match = cultures[ lang ];
+                               if ( match ) {
+                                       return match;
+                               }
+                       }
+                       while ( 1 );
+               }
+
+               // last resort: match first culture using that language
+               for ( i = 0; i < l; i++ ) {
+                       lang = prioritized[ i ].lang;
+                       for ( var cultureKey in cultures ) {
+                               var culture = cultures[ cultureKey ];
+                               if ( culture.language == lang ) {
+                                       return culture;
+                               }
+                       }
+               }
+       }
+       else if ( typeof name === "object" ) {
+               return name;
+       }
+       return match || null;
+};
+
+Globalize.format = function( value, format, cultureSelector ) {
+       culture = this.findClosestCulture( cultureSelector );
+       if ( value instanceof Date ) {
+               value = formatDate( value, format, culture );
+       }
+       else if ( typeof value === "number" ) {
+               value = formatNumber( value, format, culture );
+       }
+       return value;
+};
+
+Globalize.localize = function( key, cultureSelector ) {
+       return this.findClosestCulture( cultureSelector ).messages[ key ] ||
+               this.cultures[ "default" ].messages[ key ];
+};
+
+Globalize.parseDate = function( value, formats, culture ) {
+       culture = this.findClosestCulture( culture );
+
+       var date, prop, patterns;
+       if ( formats ) {
+               if ( typeof formats === "string" ) {
+                       formats = [ formats ];
+               }
+               if ( formats.length ) {
+                       for ( var i = 0, l = formats.length; i < l; i++ ) {
+                               var format = formats[ i ];
+                               if ( format ) {
+                                       date = parseExact( value, format, culture );
+                                       if ( date ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       } else {
+               patterns = culture.calendar.patterns;
+               for ( prop in patterns ) {
+                       date = parseExact( value, patterns[prop], culture );
+                       if ( date ) {
+                               break;
+                       }
+               }
+       }
+
+       return date || null;
+};
+
+Globalize.parseInt = function( value, radix, cultureSelector ) {
+       return truncate( Globalize.parseFloat(value, radix, cultureSelector) );
+};
+
+Globalize.parseFloat = function( value, radix, cultureSelector ) {
+       // radix argument is optional
+       if ( typeof radix !== "number" ) {
+               cultureSelector = radix;
+               radix = 10;
+       }
+
+       var culture = this.findClosestCulture( cultureSelector );
+       var ret = NaN,
+               nf = culture.numberFormat;
+
+       if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) {
+               // remove currency symbol
+               value = value.replace( culture.numberFormat.currency.symbol, "" );
+               // replace decimal seperator
+               value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] );
+       }
+
+       // trim leading and trailing whitespace
+       value = trim( value );
+
+       // allow infinity or hexidecimal
+       if ( regexInfinity.test(value) ) {
+               ret = parseFloat( value );
+       }
+       else if ( !radix && regexHex.test(value) ) {
+               ret = parseInt( value, 16 );
+       }
+       else {
+
+               // determine sign and number
+               var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
+                       sign = signInfo[ 0 ],
+                       num = signInfo[ 1 ];
+
+               // #44 - try parsing as "(n)"
+               if ( sign === "" && nf.pattern[0] !== "(n)" ) {
+                       signInfo = parseNegativePattern( value, nf, "(n)" );
+                       sign = signInfo[ 0 ];
+                       num = signInfo[ 1 ];
+               }
+
+               // try parsing as "-n"
+               if ( sign === "" && nf.pattern[0] !== "-n" ) {
+                       signInfo = parseNegativePattern( value, nf, "-n" );
+                       sign = signInfo[ 0 ];
+                       num = signInfo[ 1 ];
+               }
+
+               sign = sign || "+";
+
+               // determine exponent and number
+               var exponent,
+                       intAndFraction,
+                       exponentPos = num.indexOf( "e" );
+               if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" );
+               if ( exponentPos < 0 ) {
+                       intAndFraction = num;
+                       exponent = null;
+               }
+               else {
+                       intAndFraction = num.substr( 0, exponentPos );
+                       exponent = num.substr( exponentPos + 1 );
+               }
+               // determine decimal position
+               var integer,
+                       fraction,
+                       decSep = nf[ "." ],
+                       decimalPos = intAndFraction.indexOf( decSep );
+               if ( decimalPos < 0 ) {
+                       integer = intAndFraction;
+                       fraction = null;
+               }
+               else {
+                       integer = intAndFraction.substr( 0, decimalPos );
+                       fraction = intAndFraction.substr( decimalPos + decSep.length );
+               }
+               // handle groups (e.g. 1,000,000)
+               var groupSep = nf[ "," ];
+               integer = integer.split( groupSep ).join( "" );
+               var altGroupSep = groupSep.replace( /\u00A0/g, " " );
+               if ( groupSep !== altGroupSep ) {
+                       integer = integer.split( altGroupSep ).join( "" );
+               }
+               // build a natively parsable number string
+               var p = sign + integer;
+               if ( fraction !== null ) {
+                       p += "." + fraction;
+               }
+               if ( exponent !== null ) {
+                       // exponent itself may have a number patternd
+                       var expSignInfo = parseNegativePattern( exponent, nf, "-n" );
+                       p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ];
+               }
+               if ( regexParseFloat.test(p) ) {
+                       ret = parseFloat( p );
+               }
+       }
+       return ret;
+};
+
+Globalize.culture = function( cultureSelector ) {
+       // setter
+       if ( typeof cultureSelector !== "undefined" ) {
+               this.cultureSelector = cultureSelector;
+       }
+       // getter
+       return this.findClosestCulture( cultureSelector ) || this.culture[ "default" ];
+};
+
+}( this ));
diff --git a/external/jquery.global.de-DE.js b/external/jquery.global.de-DE.js
deleted file mode 100644 (file)
index e526e78..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-(function($) {
-    var cultures = $.global.cultures,
-        en = cultures.en,
-        standard = en.calendars.standard,
-        culture = cultures["de-DE"] = $.extend(true, {}, en, {
-        name: "de-DE",
-        englishName: "German (Germany)",
-        nativeName: "Deutsch (Deutschland)",
-        language: "de",
-        numberFormat: {
-            ',': ".",
-            '.': ",",
-            percent: {
-                pattern: ["-n%","n%"],
-                ',': ".",
-                '.': ","
-            },
-            currency: {
-                pattern: ["-n $","n $"],
-                ',': ".",
-                '.': ",",
-                symbol: "€"
-            }
-        },
-        calendars: {
-            standard: $.extend(true, {}, standard, {
-                '/': ".",
-                firstDay: 1,
-                days: {
-                    names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],
-                    namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"],
-                    namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"]
-                },
-                months: {
-                    names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],
-                    namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""]
-                },
-                AM: null,
-                PM: null,
-                eras: [{"name":"n. Chr.","start":null,"offset":0}],
-                patterns: {
-                    d: "dd.MM.yyyy",
-                    D: "dddd, d. MMMM yyyy",
-                    t: "HH:mm",
-                    T: "HH:mm:ss",
-                    f: "dddd, d. MMMM yyyy HH:mm",
-                    F: "dddd, d. MMMM yyyy HH:mm:ss",
-                    M: "dd MMMM",
-                    Y: "MMMM yyyy"
-                }
-            })
-        }
-    }, cultures["de-DE"]);
-    culture.calendar = culture.calendars.standard;
-})(jQuery);
\ No newline at end of file
diff --git a/external/jquery.global.ja-JP.js b/external/jquery.global.ja-JP.js
deleted file mode 100644 (file)
index 3673cef..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-(function($) {
-    var cultures = $.global.cultures,
-        en = cultures.en,
-        standard = en.calendars.standard,
-        culture = cultures["ja-JP"] = $.extend(true, {}, en, {
-        name: "ja-JP",
-        englishName: "Japanese (Japan)",
-        nativeName: "日本語 (日本)",
-        language: "ja",
-        numberFormat: {
-            percent: {
-                pattern: ["-n%","n%"]
-            },
-            currency: {
-                pattern: ["-$n","$n"],
-                decimals: 0,
-                symbol: "¥"
-            }
-        },
-        calendars: {
-            standard: $.extend(true, {}, standard, {
-                days: {
-                    names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
-                    namesAbbr: ["日","月","火","水","木","金","土"],
-                    namesShort: ["日","月","火","水","木","金","土"]
-                },
-                months: {
-                    names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],
-                    namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""]
-                },
-                AM: ["午前","午前","午前"],
-                PM: ["午後","午後","午後"],
-                eras: [{"name":"西暦","start":null,"offset":0}],
-                patterns: {
-                    d: "yyyy/MM/dd",
-                    D: "yyyy'年'M'月'd'日'",
-                    t: "H:mm",
-                    T: "H:mm:ss",
-                    f: "yyyy'年'M'月'd'日' H:mm",
-                    F: "yyyy'年'M'月'd'日' H:mm:ss",
-                    M: "M'月'd'日'",
-                    Y: "yyyy'年'M'月'"
-                }
-            }),
-            Japanese: $.extend(true, {}, standard, {
-                name: "Japanese",
-                days: {
-                    names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
-                    namesAbbr: ["日","月","火","水","木","金","土"],
-                    namesShort: ["日","月","火","水","木","金","土"]
-                },
-                months: {
-                    names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],
-                    namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""]
-                },
-                AM: ["午前","午前","午前"],
-                PM: ["午後","午後","午後"],
-                eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}],
-                twoDigitYearMax: 99,
-                patterns: {
-                    d: "gg y/M/d",
-                    D: "gg y'年'M'月'd'日'",
-                    t: "H:mm",
-                    T: "H:mm:ss",
-                    f: "gg y'年'M'月'd'日' H:mm",
-                    F: "gg y'年'M'月'd'日' H:mm:ss",
-                    M: "M'月'd'日'",
-                    Y: "gg y'年'M'月'"
-                }
-            })
-        }
-    }, cultures["ja-JP"]);
-    culture.calendar = culture.calendars.standard;
-})(jQuery);
\ No newline at end of file
diff --git a/external/jquery.global.js b/external/jquery.global.js
deleted file mode 100644 (file)
index 29ae5c6..0000000
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*!
- * jQuery Globalization Plugin
- * http://github.com/jquery/jquery-global
- *
- * Copyright Software Freedom Conservancy, Inc.
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- */
-(function() {
-
-var Globalization = {}, localized = { en: {} };
-localized["default"] = localized.en;
-
-Globalization.extend = function( deep ) {
-    var target = arguments[ 1 ] || {};
-    for ( var i = 2, l = arguments.length; i < l; i++ ) {
-        var source = arguments[ i ];
-        if ( source ) {
-            for ( var field in source ) {
-                var sourceVal = source[ field ];
-                if ( typeof sourceVal !== "undefined" ) {
-                    if ( deep && (isObject( sourceVal ) || isArray( sourceVal )) ) {
-                        var targetVal = target[ field ];
-                        // extend onto the existing value, or create a new one
-                        targetVal = targetVal && (isObject( targetVal ) || isArray( targetVal ))
-                            ? targetVal
-                            : (isArray( sourceVal ) ? [] : {});
-                        target[ field ] = this.extend( true, targetVal, sourceVal );
-                    }
-                    else {
-                        target[ field ] = sourceVal;
-                    }
-                }
-            }
-        }
-    }
-    return target;
-}
-
-Globalization.findClosestCulture = function(name) {
-    var match;
-    if ( !name ) {
-        return this.culture || this.cultures["default"];
-    }
-    if ( isString( name ) ) {
-        name = name.split( ',' );
-    }
-    if ( isArray( name ) ) {
-        var lang,
-            cultures = this.cultures,
-            list = name,
-            i, l = list.length,
-            prioritized = [];
-        for ( i = 0; i < l; i++ ) {
-            name = trim( list[ i ] );
-            var pri, parts = name.split( ';' );
-            lang = trim( parts[ 0 ] );
-            if ( parts.length === 1 ) {
-                pri = 1;
-            }
-            else {
-                name = trim( parts[ 1 ] );
-                if ( name.indexOf("q=") === 0 ) {
-                    name = name.substr( 2 );
-                    pri = parseFloat( name, 10 );
-                    pri = isNaN( pri ) ? 0 : pri;
-                }
-                else {
-                    pri = 1;
-                }
-            }
-            prioritized.push( { lang: lang, pri: pri } );
-        }
-        prioritized.sort(function(a, b) {
-            return a.pri < b.pri ? 1 : -1;
-        });
-        for ( i = 0; i < l; i++ ) {
-            lang = prioritized[ i ].lang;
-            match = cultures[ lang ];
-            // exact match?
-            if ( match ) {
-                return match;
-            }
-        }
-        for ( i = 0; i < l; i++ ) {
-            lang = prioritized[ i ].lang;
-            // for each entry try its neutral language
-            do {
-                var index = lang.lastIndexOf( "-" );
-                if ( index === -1 ) {
-                    break;
-                }
-                // strip off the last part. e.g. en-US => en
-                lang = lang.substr( 0, index );
-                match = cultures[ lang ];
-                if ( match ) {
-                    return match;
-                }
-            }
-            while ( 1 );
-        }
-    }
-    else if ( typeof name === 'object' ) {
-        return name;
-    }
-    return match || null;
-}
-Globalization.preferCulture = function(name) {
-    this.culture = this.findClosestCulture( name ) || this.cultures["default"];
-}
-Globalization.localize = function(key, culture, value) {
-    // usign default culture in case culture is not provided
-    if (typeof culture !== 'string') {
-        culture = this.culture.name || this.culture || "default";
-    }
-    culture = this.cultures[ culture ] || { name: culture };
-
-    var local = localized[ culture.name ];
-    if ( arguments.length === 3 ) {
-        if ( !local) {
-            local = localized[ culture.name ] = {};
-        }
-        local[ key ] = value;
-    }
-    else {
-        if ( local ) {
-            value = local[ key ];
-        }
-        if ( typeof value === 'undefined' ) {
-            var language = localized[ culture.language ];
-            if ( language ) {
-                value = language[ key ];
-            }
-            if ( typeof value === 'undefined' ) {
-                value = localized["default"][ key ];
-            }
-        }
-    }
-    return typeof value === "undefined" ? null : value;
-}
-Globalization.format = function(value, format, culture) {
-    culture = this.findClosestCulture( culture );
-    if ( typeof value === "number" ) {
-        value = formatNumber( value, format, culture );
-    }
-    else if ( value instanceof Date ) {
-        value = formatDate( value, format, culture );
-    }
-    return value;
-}
-Globalization.parseInt = function(value, radix, culture) {
-    return Math.floor( this.parseFloat( value, radix, culture ) );
-}
-Globalization.parseFloat = function(value, radix, culture) {
-       // make radix optional
-       if (typeof radix === "string") {
-               culture = radix;
-               radix = 10;
-       }
-       
-    culture = this.findClosestCulture( culture );
-    var ret = NaN,
-        nf = culture.numberFormat;
-
-       if (value.indexOf(culture.numberFormat.currency.symbol) > -1) {
-               // remove currency symbol
-               value = value.replace(culture.numberFormat.currency.symbol, "");
-               // replace decimal seperator
-               value = value.replace(culture.numberFormat.currency["."], culture.numberFormat["."]);
-       }
-
-    // trim leading and trailing whitespace
-    value = trim( value );
-
-    // allow infinity or hexidecimal
-    if (regexInfinity.test(value)) {
-        ret = parseFloat(value, radix);
-    }
-    else if (!radix && regexHex.test(value)) {
-        ret = parseInt(value, 16);
-    }
-    else {
-        var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
-            sign = signInfo[0],
-            num = signInfo[1];
-        // determine sign and number
-        if ( sign === "" && nf.pattern[0] !== "-n" ) {
-            signInfo = parseNegativePattern( value, nf, "-n" );
-            sign = signInfo[0];
-            num = signInfo[1];
-        }
-        sign = sign || "+";
-        // determine exponent and number
-        var exponent,
-            intAndFraction,
-            exponentPos = num.indexOf( 'e' );
-        if ( exponentPos < 0 ) exponentPos = num.indexOf( 'E' );
-        if ( exponentPos < 0 ) {
-            intAndFraction = num;
-            exponent = null;
-        }
-        else {
-            intAndFraction = num.substr( 0, exponentPos );
-            exponent = num.substr( exponentPos + 1 );
-        }
-        // determine decimal position
-        var integer,
-            fraction,
-            decSep = nf['.'],
-            decimalPos = intAndFraction.indexOf( decSep );
-        if ( decimalPos < 0 ) {
-            integer = intAndFraction;
-            fraction = null;
-        }
-        else {
-            integer = intAndFraction.substr( 0, decimalPos );
-            fraction = intAndFraction.substr( decimalPos + decSep.length );
-        }
-        // handle groups (e.g. 1,000,000)
-        var groupSep = nf[","];
-        integer = integer.split(groupSep).join('');
-        var altGroupSep = groupSep.replace(/\u00A0/g, " ");
-        if ( groupSep !== altGroupSep ) {
-            integer = integer.split(altGroupSep).join('');
-        }
-        // build a natively parsable number string
-        var p = sign + integer;
-        if ( fraction !== null ) {
-            p += '.' + fraction;
-        }
-        if ( exponent !== null ) {
-            // exponent itself may have a number patternd
-            var expSignInfo = parseNegativePattern( exponent, nf, "-n" );
-            p += 'e' + (expSignInfo[0] || "+") + expSignInfo[1];
-        }
-        if ( regexParseFloat.test( p ) ) {
-            ret = parseFloat( p );
-        }
-    }
-    return ret;
-}
-Globalization.parseDate = function(value, formats, culture) {
-    culture = this.findClosestCulture( culture );
-
-    var date, prop, patterns;
-    if ( formats ) {
-        if ( typeof formats === "string" ) {
-            formats = [ formats ];
-        }
-        if ( formats.length ) {
-            for ( var i = 0, l = formats.length; i < l; i++ ) {
-                var format = formats[ i ];
-                if ( format ) {
-                    date = parseExact( value, format, culture );
-                    if ( date ) {
-                        break;
-                    }
-                }
-            }
-        }
-    }
-    else {
-        patterns = culture.calendar.patterns;
-        for ( prop in patterns ) {
-            date = parseExact( value, patterns[prop], culture );
-            if ( date ) {
-                break;
-            }
-        }
-    }
-    return date || null;
-}
-
-// 1.    When defining a culture, all fields are required except the ones stated as optional.
-// 2.    You can use Globalization.extend to copy an existing culture and provide only the differing values,
-//       a good practice since most cultures do not differ too much from the 'default' culture.
-//       DO use the 'default' culture if you do this, as it is the only one that definitely
-//       exists.
-// 3.    Other plugins may add to the culture information provided by extending it. However,
-//       that plugin may extend it prior to the culture being defined, or after. Therefore,
-//       do not overwrite values that already exist when defining the baseline for a culture,
-//       by extending your culture object with the existing one.
-// 4.    Each culture should have a ".calendars" object with at least one calendar named "standard"
-//       which serves as the default calendar in use by that culture.
-// 5.    Each culture should have a ".calendar" object which is the current calendar being used,
-//       it may be dynamically changed at any time to one of the calendars in ".calendars".
-
-// To define a culture, use the following pattern, which handles defining the culture based
-// on the 'default culture, extending it with the existing culture if it exists, and defining
-// it if it does not exist.
-// Globalization.cultures.foo = Globalization.extend(true, Globalization.extend(true, {}, Globalization.cultures['default'], fooCulture), Globalization.cultures.foo)
-
-var cultures = Globalization.cultures = Globalization.cultures || {};
-var en = cultures["default"] = cultures.en = Globalization.extend(true, {
-    // A unique name for the culture in the form <language code>-<country/region code>
-    name: "en",
-    // the name of the culture in the english language
-    englishName: "English",
-    // the name of the culture in its own language
-    nativeName: "English",
-    // whether the culture uses right-to-left text
-    isRTL: false,
-    // 'language' is used for so-called "specific" cultures.
-    // For example, the culture "es-CL" means "Spanish, in Chili".
-    // It represents the Spanish-speaking culture as it is in Chili,
-    // which might have different formatting rules or even translations
-    // than Spanish in Spain. A "neutral" culture is one that is not
-    // specific to a region. For example, the culture "es" is the generic
-    // Spanish culture, which may be a more generalized version of the language
-    // that may or may not be what a specific culture expects.
-    // For a specific culture like "es-CL", the 'language' field refers to the
-    // neutral, generic culture information for the language it is using.
-    // This is not always a simple matter of the string before the dash.
-    // For example, the "zh-Hans" culture is netural (Simplified Chinese).
-    // And the 'zh-SG' culture is Simplified Chinese in Singapore, whose lanugage
-    // field is "zh-CHS", not "zh".
-    // This field should be used to navigate from a specific culture to it's
-    // more general, neutral culture. If a culture is already as general as it
-    // can get, the language may refer to itself.
-    language: "en",
-    // numberFormat defines general number formatting rules, like the digits in
-    // each grouping, the group separator, and how negative numbers are displayed.
-    numberFormat: {
-        // [negativePattern]
-        // Note, numberFormat.pattern has no 'positivePattern' unlike percent and currency,
-        // but is still defined as an array for consistency with them.
-        //  negativePattern: one of "(n)|-n|- n|n-|n -"
-        pattern: ["-n"],
-        // number of decimal places normally shown
-        decimals: 2,
-        // string that separates number groups, as in 1,000,000
-        ',': ",",
-        // string that separates a number from the fractional portion, as in 1.99
-        '.': ".",
-        // array of numbers indicating the size of each number group.
-        // TODO: more detailed description and example
-        groupSizes: [3],
-        // symbol used for positive numbers
-        '+': "+",
-        // symbol used for negative numbers
-        '-': "-",
-        percent: {
-            // [negativePattern, positivePattern]
-            //     negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %"
-            //     positivePattern: one of "n %|n%|%n|% n"
-            pattern: ["-n %","n %"],
-            // number of decimal places normally shown
-            decimals: 2,
-            // array of numbers indicating the size of each number group.
-            // TODO: more detailed description and example
-            groupSizes: [3],
-            // string that separates number groups, as in 1,000,000
-            ',': ",",
-            // string that separates a number from the fractional portion, as in 1.99
-            '.': ".",
-            // symbol used to represent a percentage
-            symbol: "%"
-        },
-        currency: {
-            // [negativePattern, positivePattern]
-            //     negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)"
-            //     positivePattern: one of "$n|n$|$ n|n $"
-            pattern: ["($n)","$n"],
-            // number of decimal places normally shown
-            decimals: 2,
-            // array of numbers indicating the size of each number group.
-            // TODO: more detailed description and example
-            groupSizes: [3],
-            // string that separates number groups, as in 1,000,000
-            ',': ",",
-            // string that separates a number from the fractional portion, as in 1.99
-            '.': ".",
-            // symbol used to represent currency
-            symbol: "$"
-        }
-    },
-    // calendars defines all the possible calendars used by this culture.
-    // There should be at least one defined with name 'standard', and is the default
-    // calendar used by the culture.
-    // A calendar contains information about how dates are formatted, information about
-    // the calendar's eras, a standard set of the date formats,
-    // translations for day and month names, and if the calendar is not based on the Gregorian
-    // calendar, conversion functions to and from the Gregorian calendar.
-    calendars: {
-        standard: {
-            // name that identifies the type of calendar this is
-            name: "Gregorian_USEnglish",
-            // separator of parts of a date (e.g. '/' in 11/05/1955)
-            '/': "/",
-            // separator of parts of a time (e.g. ':' in 05:44 PM)
-            ':': ":",
-            // the first day of the week (0 = Sunday, 1 = Monday, etc)
-            firstDay: 0,
-            days: {
-                // full day names
-                names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
-                // abbreviated day names
-                namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
-                // shortest day names
-                namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"]
-            },
-            months: {
-                // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar)
-                names: ["January","February","March","April","May","June","July","August","September","October","November","December",""],
-                // abbreviated month names
-                namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""]
-            },
-            // AM and PM designators in one of these forms:
-            // The usual view, and the upper and lower case versions
-            //      [standard,lowercase,uppercase]
-            // The culture does not use AM or PM (likely all standard date formats use 24 hour time)
-            //      null
-            AM: ["AM", "am", "AM"],
-            PM: ["PM", "pm", "PM"],
-            eras: [
-                // eras in reverse chronological order.
-                // name: the name of the era in this culture (e.g. A.D., C.E.)
-                // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era.
-                // offset: offset in years from gregorian calendar
-                { "name": "A.D.", "start": null, "offset": 0 }
-            ],
-            // when a two digit year is given, it will never be parsed as a four digit
-            // year greater than this year (in the appropriate era for the culture)
-            // Set it as a full year (e.g. 2029) or use an offset format starting from
-            // the current year: "+19" would correspond to 2029 if the current year 2010.
-            twoDigitYearMax: 2029,
-            // set of predefined date and time patterns used by the culture
-            // these represent the format someone in this culture would expect
-            // to see given the portions of the date that are shown.
-            patterns: {
-                // short date pattern
-                d: "M/d/yyyy",
-                // long date pattern
-                D: "dddd, MMMM dd, yyyy",
-                // short time pattern
-                t: "h:mm tt",
-                // long time pattern
-                T: "h:mm:ss tt",
-                // long date, short time pattern
-                f: "dddd, MMMM dd, yyyy h:mm tt",
-                // long date, long time pattern
-                F: "dddd, MMMM dd, yyyy h:mm:ss tt",
-                // month/day pattern
-                M: "MMMM dd",
-                // month/year pattern
-                Y: "yyyy MMMM",
-                // S is a sortable format that does not vary by culture
-                S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss"
-            }
-            // optional fields for each calendar:
-            /*
-            monthsGenitive:
-                Same as months but used when the day preceeds the month.
-                Omit if the culture has no genitive distinction in month names.
-                For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx
-            convert:
-                Allows for the support of non-gregorian based calendars. This convert object is used to
-                to convert a date to and from a gregorian calendar date to handle parsing and formatting.
-                The two functions:
-                    fromGregorian(date)
-                        Given the date as a parameter, return an array with parts [year, month, day]
-                        corresponding to the non-gregorian based year, month, and day for the calendar.
-                    toGregorian(year, month, day)
-                        Given the non-gregorian year, month, and day, return a new Date() object
-                        set to the corresponding date in the gregorian calendar.
-            */
-        }
-    }
-}, cultures.en);
-en.calendar = en.calendar || en.calendars.standard;
-
-var regexTrim = /^\s+|\s+$/g,
-    regexInfinity = /^[+-]?infinity$/i,
-    regexHex = /^0x[a-f0-9]+$/i,
-    regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/,
-    toString = Object.prototype.toString;
-
-function startsWith(value, pattern) {
-    return value.indexOf( pattern ) === 0;
-}
-
-function endsWith(value, pattern) {
-    return value.substr( value.length - pattern.length ) === pattern;
-}
-
-function trim(value) {
-    return (value+"").replace( regexTrim, "" );
-}
-
-function zeroPad(str, count, left) {
-    for (var l=str.length; l < count; l++) {
-        str = (left ? ('0' + str) : (str + '0'));
-    }
-    return str;
-}
-
-function isArray(obj) {
-    return toString.call(obj) === "[object Array]";
-}
-
-function isString(obj) {
-    return toString.call(obj) === "[object String]";
-}
-
-function isObject(obj) {
-    return toString.call(obj) === "[object Object]";
-}
-
-function arrayIndexOf( array, item ) {
-    if ( array.indexOf ) {
-        return array.indexOf( item );
-    }
-    for ( var i = 0, length = array.length; i < length; i++ ) {
-        if ( array[ i ] === item ) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-// *************************************** Numbers ***************************************
-
-function expandNumber(number, precision, formatInfo) {
-    var groupSizes = formatInfo.groupSizes,
-        curSize = groupSizes[ 0 ],
-        curGroupIndex = 1,
-        factor = Math.pow( 10, precision ),
-        rounded = Math.round( number * factor ) / factor;
-    if ( !isFinite(rounded) ) {
-        rounded = number;
-    }
-    number = rounded;
-
-    var numberString = number+"",
-        right = "",
-        split = numberString.split(/e/i),
-        exponent = split.length > 1 ? parseInt( split[ 1 ], 10 ) : 0;
-    numberString = split[ 0 ];
-    split = numberString.split( "." );
-    numberString = split[ 0 ];
-    right = split.length > 1 ? split[ 1 ] : "";
-
-    var l;
-    if ( exponent > 0 ) {
-        right = zeroPad( right, exponent, false );
-        numberString += right.slice( 0, exponent );
-        right = right.substr( exponent );
-    }
-    else if ( exponent < 0 ) {
-        exponent = -exponent;
-        numberString = zeroPad( numberString, exponent + 1 );
-        right = numberString.slice( -exponent, numberString.length ) + right;
-        numberString = numberString.slice( 0, -exponent );
-    }
-
-    if ( precision > 0 ) {
-        right = formatInfo['.'] +
-            ((right.length > precision) ? right.slice( 0, precision ) : zeroPad( right, precision ));
-    }
-    else {
-        right = "";
-    }
-
-    var stringIndex = numberString.length - 1,
-        sep = formatInfo[","],
-        ret = "";
-
-    while ( stringIndex >= 0 ) {
-        if ( curSize === 0 || curSize > stringIndex ) {
-            return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? ( sep + ret + right ) : right );
-        }
-        ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? ( sep + ret ) : "" );
-
-        stringIndex -= curSize;
-
-        if ( curGroupIndex < groupSizes.length ) {
-            curSize = groupSizes[ curGroupIndex ];
-            curGroupIndex++;
-        }
-    }
-    return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right;
-}
-
-
-function parseNegativePattern(value, nf, negativePattern) {
-    var neg = nf["-"],
-        pos = nf["+"],
-        ret;
-    switch (negativePattern) {
-        case "n -":
-            neg = ' ' + neg;
-            pos = ' ' + pos;
-            // fall through
-        case "n-":
-            if ( endsWith( value, neg ) ) {
-                ret = [ '-', value.substr( 0, value.length - neg.length ) ];
-            }
-            else if ( endsWith( value, pos ) ) {
-                ret = [ '+', value.substr( 0, value.length - pos.length ) ];
-            }
-            break;
-        case "- n":
-            neg += ' ';
-            pos += ' ';
-            // fall through
-        case "-n":
-            if ( startsWith( value, neg ) ) {
-                ret = [ '-', value.substr( neg.length ) ];
-            }
-            else if ( startsWith(value, pos) ) {
-                ret = [ '+', value.substr( pos.length ) ];
-            }
-            break;
-        case "(n)":
-            if ( startsWith( value, '(' ) && endsWith( value, ')' ) ) {
-                ret = [ '-', value.substr( 1, value.length - 2 ) ];
-            }
-            break;
-    }
-    return ret || [ '', value ];
-}
-
-function formatNumber(value, format, culture) {
-    if ( !format || format === 'i' ) {
-        return culture.name.length ? value.toLocaleString() : value.toString();
-    }
-    format = format || "D";
-
-    var nf = culture.numberFormat,
-        number = Math.abs(value),
-        precision = -1,
-        pattern;
-    if (format.length > 1) precision = parseInt( format.slice( 1 ), 10 );
-
-    var current = format.charAt( 0 ).toUpperCase(),
-        formatInfo;
-
-    switch (current) {
-        case "D":
-            pattern = 'n';
-            if (precision !== -1) {
-                number = zeroPad( ""+number, precision, true );
-            }
-            if (value < 0) number = -number;
-            break;
-        case "N":
-            formatInfo = nf;
-            // fall through
-        case "C":
-            formatInfo = formatInfo || nf.currency;
-            // fall through
-        case "P":
-            formatInfo = formatInfo || nf.percent;
-            pattern = value < 0 ? formatInfo.pattern[0] : (formatInfo.pattern[1] || "n");
-            if (precision === -1) precision = formatInfo.decimals;
-            number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo );
-            break;
-        default:
-            throw "Bad number format specifier: " + current;
-    }
-
-    var patternParts = /n|\$|-|%/g,
-        ret = "";
-    for (;;) {
-        var index = patternParts.lastIndex,
-            ar = patternParts.exec(pattern);
-
-        ret += pattern.slice( index, ar ? ar.index : pattern.length );
-
-        if (!ar) {
-            break;
-        }
-
-        switch (ar[0]) {
-            case "n":
-                ret += number;
-                break;
-            case "$":
-                ret += nf.currency.symbol;
-                break;
-            case "-":
-                // don't make 0 negative
-                if ( /[1-9]/.test( number ) ) {
-                    ret += nf["-"];
-                }
-                break;
-            case "%":
-                ret += nf.percent.symbol;
-                break;
-        }
-    }
-
-    return ret;
-}
-
-// *************************************** Dates ***************************************
-
-function outOfRange(value, low, high) {
-    return value < low || value > high;
-}
-
-function expandYear(cal, year) {
-    // expands 2-digit year into 4 digits.
-    var now = new Date(),
-        era = getEra(now);
-    if ( year < 100 ) {
-        var twoDigitYearMax = cal.twoDigitYearMax;
-        twoDigitYearMax = typeof twoDigitYearMax === 'string' ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
-        var curr = getEraYear( now, cal, era );
-        year += curr - ( curr % 100 );
-        if ( year > twoDigitYearMax ) {
-            year -= 100;
-        }
-    }
-    return year;
-}
-
-function getEra(date, eras) {
-    if ( !eras ) return 0;
-    var start, ticks = date.getTime();
-    for ( var i = 0, l = eras.length; i < l; i++ ) {
-        start = eras[ i ].start;
-        if ( start === null || ticks >= start ) {
-            return i;
-        }
-    }
-    return 0;
-}
-
-function toUpper(value) {
-    // 'he-IL' has non-breaking space in weekday names.
-    return value.split( "\u00A0" ).join(' ').toUpperCase();
-}
-
-function toUpperArray(arr) {
-    var results = [];
-    for ( var i = 0, l = arr.length; i < l; i++ ) {
-        results[i] = toUpper(arr[i]);
-    }
-    return results;
-}
-
-function getEraYear(date, cal, era, sortable) {
-    var year = date.getFullYear();
-    if ( !sortable && cal.eras ) {
-        // convert normal gregorian year to era-shifted gregorian
-        // year by subtracting the era offset
-        year -= cal.eras[ era ].offset;
-    }
-    return year;
-}
-
-function getDayIndex(cal, value, abbr) {
-    var ret,
-        days = cal.days,
-        upperDays = cal._upperDays;
-    if ( !upperDays ) {
-        cal._upperDays = upperDays = [
-            toUpperArray( days.names ),
-            toUpperArray( days.namesAbbr ),
-            toUpperArray( days.namesShort )
-        ];
-    }
-    value = toUpper( value );
-    if ( abbr ) {
-        ret = arrayIndexOf( upperDays[ 1 ], value );
-        if ( ret === -1 ) {
-            ret = arrayIndexOf( upperDays[ 2 ], value );
-        }
-    }
-    else {
-        ret = arrayIndexOf( upperDays[ 0 ], value );
-    }
-    return ret;
-}
-
-function getMonthIndex(cal, value, abbr) {
-    var months = cal.months,
-        monthsGen = cal.monthsGenitive || cal.months,
-        upperMonths = cal._upperMonths,
-        upperMonthsGen = cal._upperMonthsGen;
-    if ( !upperMonths ) {
-        cal._upperMonths = upperMonths = [
-            toUpperArray( months.names ),
-            toUpperArray( months.namesAbbr )
-        ];
-        cal._upperMonthsGen = upperMonthsGen = [
-            toUpperArray( monthsGen.names ),
-            toUpperArray( monthsGen.namesAbbr )
-        ];
-    }
-    value = toUpper( value );
-    var i = arrayIndexOf( abbr ? upperMonths[ 1 ] : upperMonths[ 0 ], value );
-    if ( i < 0 ) {
-        i = arrayIndexOf( abbr ? upperMonthsGen[ 1 ] : upperMonthsGen[ 0 ], value );
-    }
-    return i;
-}
-
-function appendPreOrPostMatch(preMatch, strings) {
-    // appends pre- and post- token match strings while removing escaped characters.
-    // Returns a single quote count which is used to determine if the token occurs
-    // in a string literal.
-    var quoteCount = 0,
-        escaped = false;
-    for ( var i = 0, il = preMatch.length; i < il; i++ ) {
-        var c = preMatch.charAt( i );
-        switch ( c ) {
-            case '\'':
-                if ( escaped ) {
-                    strings.push( "'" );
-                }
-                else {
-                    quoteCount++;
-                }
-                escaped = false;
-                break;
-            case '\\':
-                if ( escaped ) {
-                    strings.push( "\\" );
-                }
-                escaped = !escaped;
-                break;
-            default:
-                strings.push( c );
-                escaped = false;
-                break;
-        }
-    }
-    return quoteCount;
-}
-
-function expandFormat(cal, format) {
-    // expands unspecified or single character date formats into the full pattern.
-    format = format || "F";
-    var pattern,
-        patterns = cal.patterns,
-        len = format.length;
-    if ( len === 1 ) {
-        pattern = patterns[ format ];
-        if ( !pattern ) {
-            throw "Invalid date format string '" + format + "'.";
-        }
-        format = pattern;
-    }
-    else if ( len === 2  && format.charAt(0) === "%" ) {
-        // %X escape format -- intended as a custom format string that is only one character, not a built-in format.
-        format = format.charAt( 1 );
-    }
-    return format;
-}
-
-function getParseRegExp(cal, format) {
-    // converts a format string into a regular expression with groups that
-    // can be used to extract date fields from a date string.
-    // check for a cached parse regex.
-    var re = cal._parseRegExp;
-    if ( !re ) {
-        cal._parseRegExp = re = {};
-    }
-    else {
-        var reFormat = re[ format ];
-        if ( reFormat ) {
-            return reFormat;
-        }
-    }
-
-    // expand single digit formats, then escape regular expression characters.
-    var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ),
-        regexp = ["^"],
-        groups = [],
-        index = 0,
-        quoteCount = 0,
-        tokenRegExp = getTokenRegExp(),
-        match;
-
-    // iterate through each date token found.
-    while ( (match = tokenRegExp.exec( expFormat )) !== null ) {
-        var preMatch = expFormat.slice( index, match.index );
-        index = tokenRegExp.lastIndex;
-
-        // don't replace any matches that occur inside a string literal.
-        quoteCount += appendPreOrPostMatch( preMatch, regexp );
-        if ( quoteCount % 2 ) {
-            regexp.push( match[ 0 ] );
-            continue;
-        }
-
-        // add a regex group for the token.
-        var m = match[ 0 ],
-            len = m.length,
-            add;
-        switch ( m ) {
-            case 'dddd': case 'ddd':
-            case 'MMMM': case 'MMM':
-            case 'gg': case 'g':
-                add = "(\\D+)";
-                break;
-            case 'tt': case 't':
-                add = "(\\D*)";
-                break;
-            case 'yyyy':
-            case 'fff':
-            case 'ff':
-            case 'f':
-                add = "(\\d{" + len + "})";
-                break;
-            case 'dd': case 'd':
-            case 'MM': case 'M':
-            case 'yy': case 'y':
-            case 'HH': case 'H':
-            case 'hh': case 'h':
-            case 'mm': case 'm':
-            case 'ss': case 's':
-                add = "(\\d\\d?)";
-                break;
-            case 'zzz':
-                add = "([+-]?\\d\\d?:\\d{2})";
-                break;
-            case 'zz': case 'z':
-                add = "([+-]?\\d\\d?)";
-                break;
-            case '/':
-                add = "(\\" + cal["/"] + ")";
-                break;
-            default:
-                throw "Invalid date format pattern '" + m + "'.";
-                break;
-        }
-        if ( add ) {
-            regexp.push( add );
-        }
-        groups.push( match[ 0 ] );
-    }
-    appendPreOrPostMatch( expFormat.slice( index ), regexp );
-    regexp.push( "$" );
-
-    // allow whitespace to differ when matching formats.
-    var regexpStr = regexp.join( '' ).replace( /\s+/g, "\\s+" ),
-        parseRegExp = {'regExp': regexpStr, 'groups': groups};
-
-    // cache the regex for this format.
-    return re[ format ] = parseRegExp;
-}
-
-function getTokenRegExp() {
-    // regular expression for matching date and time tokens in format strings.
-    return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g;
-}
-
-function parseExact(value, format, culture) {
-    // try to parse the date string by matching against the format string
-    // while using the specified culture for date field names.
-    value = trim( value );
-    var cal = culture.calendar,
-        // convert date formats into regular expressions with groupings.
-        // use the regexp to determine the input format and extract the date fields.
-        parseInfo = getParseRegExp(cal, format),
-        match = new RegExp(parseInfo.regExp).exec(value);
-    if (match === null) {
-        return null;
-    }
-    // found a date format that matches the input.
-    var groups = parseInfo.groups,
-        era = null, year = null, month = null, date = null, weekDay = null,
-        hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null,
-        pmHour = false;
-    // iterate the format groups to extract and set the date fields.
-    for ( var j = 0, jl = groups.length; j < jl; j++ ) {
-        var matchGroup = match[ j + 1 ];
-        if ( matchGroup ) {
-            var current = groups[ j ],
-                clength = current.length,
-                matchInt = parseInt( matchGroup, 10 );
-            switch ( current ) {
-                case 'dd': case 'd':
-                    // Day of month.
-                    date = matchInt;
-                    // check that date is generally in valid range, also checking overflow below.
-                    if ( outOfRange( date, 1, 31 ) ) return null;
-                    break;
-                case 'MMM':
-                case 'MMMM':
-                    month = getMonthIndex( cal, matchGroup, clength === 3 );
-                    if ( outOfRange( month, 0, 11 ) ) return null;
-                    break;
-                case 'M': case 'MM':
-                    // Month.
-                    month = matchInt - 1;
-                    if ( outOfRange( month, 0, 11 ) ) return null;
-                    break;
-                case 'y': case 'yy':
-                case 'yyyy':
-                    year = clength < 4 ? expandYear( cal, matchInt ) : matchInt;
-                    if ( outOfRange( year, 0, 9999 ) ) return null;
-                    break;
-                case 'h': case 'hh':
-                    // Hours (12-hour clock).
-                    hour = matchInt;
-                    if ( hour === 12 ) hour = 0;
-                    if ( outOfRange( hour, 0, 11 ) ) return null;
-                    break;
-                case 'H': case 'HH':
-                    // Hours (24-hour clock).
-                    hour = matchInt;
-                    if ( outOfRange( hour, 0, 23 ) ) return null;
-                    break;
-                case 'm': case 'mm':
-                    // Minutes.
-                    min = matchInt;
-                    if ( outOfRange( min, 0, 59 ) ) return null;
-                    break;
-                case 's': case 'ss':
-                    // Seconds.
-                    sec = matchInt;
-                    if ( outOfRange( sec, 0, 59 ) ) return null;
-                    break;
-                case 'tt': case 't':
-                    // AM/PM designator.
-                    // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of
-                    // the AM tokens. If not, fail the parse for this format.
-                    pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] );
-                    if ( !pmHour && ( !cal.AM || (matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2]) ) ) return null;
-                    break;
-                case 'f':
-                    // Deciseconds.
-                case 'ff':
-                    // Centiseconds.
-                case 'fff':
-                    // Milliseconds.
-                    msec = matchInt * Math.pow( 10, 3-clength );
-                    if ( outOfRange( msec, 0, 999 ) ) return null;
-                    break;
-                case 'ddd':
-                    // Day of week.
-                case 'dddd':
-                    // Day of week.
-                    weekDay = getDayIndex( cal, matchGroup, clength === 3 );
-                    if ( outOfRange( weekDay, 0, 6 ) ) return null;
-                    break;
-                case 'zzz':
-                    // Time zone offset in +/- hours:min.
-                    var offsets = matchGroup.split( /:/ );
-                    if ( offsets.length !== 2 ) return null;
-                    hourOffset = parseInt( offsets[ 0 ], 10 );
-                    if ( outOfRange( hourOffset, -12, 13 ) ) return null;
-                    var minOffset = parseInt( offsets[ 1 ], 10 );
-                    if ( outOfRange( minOffset, 0, 59 ) ) return null;
-                    tzMinOffset = (hourOffset * 60) + (startsWith( matchGroup, '-' ) ? -minOffset : minOffset);
-                    break;
-                case 'z': case 'zz':
-                    // Time zone offset in +/- hours.
-                    hourOffset = matchInt;
-                    if ( outOfRange( hourOffset, -12, 13 ) ) return null;
-                    tzMinOffset = hourOffset * 60;
-                    break;
-                case 'g': case 'gg':
-                    var eraName = matchGroup;
-                    if ( !eraName || !cal.eras ) return null;
-                    eraName = trim( eraName.toLowerCase() );
-                    for ( var i = 0, l = cal.eras.length; i < l; i++ ) {
-                        if ( eraName === cal.eras[ i ].name.toLowerCase() ) {
-                            era = i;
-                            break;
-                        }
-                    }
-                    // could not find an era with that name
-                    if ( era === null ) return null;
-                    break;
-            }
-        }
-    }
-    var result = new Date(), defaultYear, convert = cal.convert;
-    defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear();
-    if ( year === null ) {
-        year = defaultYear;
-    }
-    else if ( cal.eras ) {
-        // year must be shifted to normal gregorian year
-        // but not if year was not specified, its already normal gregorian
-        // per the main if clause above.
-        year += cal.eras[ (era || 0) ].offset;
-    }
-    // set default day and month to 1 and January, so if unspecified, these are the defaults
-    // instead of the current day/month.
-    if ( month === null ) {
-        month = 0;
-    }
-    if ( date === null ) {
-        date = 1;
-    }
-    // now have year, month, and date, but in the culture's calendar.
-    // convert to gregorian if necessary
-    if ( convert ) {
-        result = convert.toGregorian( year, month, date );
-        // conversion failed, must be an invalid match
-        if ( result === null ) return null;
-    }
-    else {
-        // have to set year, month and date together to avoid overflow based on current date.
-        result.setFullYear( year, month, date );
-        // check to see if date overflowed for specified month (only checked 1-31 above).
-        if ( result.getDate() !== date ) return null;
-        // invalid day of week.
-        if ( weekDay !== null && result.getDay() !== weekDay ) {
-            return null;
-        }
-    }
-    // if pm designator token was found make sure the hours fit the 24-hour clock.
-    if ( pmHour && hour < 12 ) {
-        hour += 12;
-    }
-    result.setHours( hour, min, sec, msec );
-    if ( tzMinOffset !== null ) {
-        // adjust timezone to utc before applying local offset.
-        var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() );
-        // Safari limits hours and minutes to the range of -127 to 127.  We need to use setHours
-        // to ensure both these fields will not exceed this range.  adjustedMin will range
-        // somewhere between -1440 and 1500, so we only need to split this into hours.
-        result.setHours( result.getHours() + parseInt( adjustedMin / 60, 10 ), adjustedMin % 60 );
-    }
-    return result;
-}
-
-function formatDate(value, format, culture) {
-    var cal = culture.calendar,
-        convert = cal.convert;
-    if ( !format || !format.length || format === 'i' ) {
-        var ret;
-        if ( culture && culture.name.length ) {
-            if ( convert ) {
-                // non-gregorian calendar, so we cannot use built-in toLocaleString()
-                ret = formatDate( value, cal.patterns.F, culture );
-            }
-            else {
-                var eraDate = new Date( value.getTime() ),
-                    era = getEra( value, cal.eras );
-                eraDate.setFullYear( getEraYear( value, cal, era ) );
-                ret = eraDate.toLocaleString();
-            }
-        }
-        else {
-            ret = value.toString();
-        }
-        return ret;
-    }
-
-    var eras = cal.eras,
-        sortable = format === "s";
-    format = expandFormat( cal, format );
-
-    // Start with an empty string
-    ret = [];
-    var hour,
-        zeros = ['0','00','000'],
-        foundDay,
-        checkedDay,
-        dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g,
-        quoteCount = 0,
-        tokenRegExp = getTokenRegExp(),
-        converted;
-
-    function padZeros(num, c) {
-        var r, s = num+'';
-        if ( c > 1 && s.length < c ) {
-            r = ( zeros[ c - 2 ] + s);
-            return r.substr( r.length - c, c );
-        }
-        else {
-            r = s;
-        }
-        return r;
-    }
-
-    function hasDay() {
-        if ( foundDay || checkedDay ) {
-            return foundDay;
-        }
-        foundDay = dayPartRegExp.test( format );
-        checkedDay = true;
-        return foundDay;
-    }
-
-    function getPart( date, part ) {
-        if ( converted ) {
-            return converted[ part ];
-        }
-        switch ( part ) {
-            case 0: return date.getFullYear();
-            case 1: return date.getMonth();
-            case 2: return date.getDate();
-        }
-    }
-
-    if ( !sortable && convert ) {
-        converted = convert.fromGregorian( value );
-    }
-
-    for (;;) {
-        // Save the current index
-        var index = tokenRegExp.lastIndex,
-            // Look for the next pattern
-            ar = tokenRegExp.exec( format );
-
-        // Append the text before the pattern (or the end of the string if not found)
-        var preMatch = format.slice( index, ar ? ar.index : format.length );
-        quoteCount += appendPreOrPostMatch( preMatch, ret );
-
-        if ( !ar ) {
-            break;
-        }
-
-        // do not replace any matches that occur inside a string literal.
-        if ( quoteCount % 2 ) {
-            ret.push( ar[ 0 ] );
-            continue;
-        }
-
-        var current = ar[ 0 ],
-            clength = current.length;
-
-        switch ( current ) {
-            case "ddd":
-                //Day of the week, as a three-letter abbreviation
-            case "dddd":
-                // Day of the week, using the full name
-                names = (clength === 3) ? cal.days.namesAbbr : cal.days.names;
-                ret.push( names[ value.getDay() ] );
-                break;
-            case "d":
-                // Day of month, without leading zero for single-digit days
-            case "dd":
-                // Day of month, with leading zero for single-digit days
-                foundDay = true;
-                ret.push( padZeros( getPart( value, 2 ), clength ) );
-                break;
-            case "MMM":
-                // Month, as a three-letter abbreviation
-            case "MMMM":
-                // Month, using the full name
-                var part = getPart( value, 1 );
-                ret.push( (cal.monthsGenitive && hasDay())
-                    ? cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ]
-                    : cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] );
-                break;
-            case "M":
-                // Month, as digits, with no leading zero for single-digit months
-            case "MM":
-                // Month, as digits, with leading zero for single-digit months
-                ret.push( padZeros( getPart( value, 1 ) + 1, clength ) );
-                break;
-            case "y":
-                // Year, as two digits, but with no leading zero for years less than 10
-            case "yy":
-                // Year, as two digits, with leading zero for years less than 10
-            case "yyyy":
-                // Year represented by four full digits
-                part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra( value, eras ), sortable );
-                if ( clength < 4 ) {
-                    part = part % 100;
-                }
-                ret.push( padZeros( part, clength ) );
-                break;
-            case "h":
-                // Hours with no leading zero for single-digit hours, using 12-hour clock
-            case "hh":
-                // Hours with leading zero for single-digit hours, using 12-hour clock
-                hour = value.getHours() % 12;
-                if ( hour === 0 ) hour = 12;
-                ret.push( padZeros( hour, clength ) );
-                break;
-            case "H":
-                // Hours with no leading zero for single-digit hours, using 24-hour clock
-            case "HH":
-                // Hours with leading zero for single-digit hours, using 24-hour clock
-                ret.push( padZeros( value.getHours(), clength ) );
-                break;
-            case "m":
-                // Minutes with no leading zero  for single-digit minutes
-            case "mm":
-                // Minutes with leading zero  for single-digit minutes
-                ret.push( padZeros( value.getMinutes(), clength ) );
-                break;
-            case "s":
-                // Seconds with no leading zero for single-digit seconds
-            case "ss":
-                // Seconds with leading zero for single-digit seconds
-                ret.push( padZeros(value .getSeconds(), clength ) );
-                break;
-            case "t":
-                // One character am/pm indicator ("a" or "p")
-            case "tt":
-                // Multicharacter am/pm indicator
-                part = value.getHours() < 12 ? (cal.AM ? cal.AM[0] : " ") : (cal.PM ? cal.PM[0] : " ");
-                ret.push( clength === 1 ? part.charAt( 0 ) : part );
-                break;
-            case "f":
-                // Deciseconds
-            case "ff":
-                // Centiseconds
-            case "fff":
-                // Milliseconds
-                ret.push( padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) );
-                break;
-            case "z":
-                // Time zone offset, no leading zero
-            case "zz":
-                // Time zone offset with leading zero
-                hour = value.getTimezoneOffset() / 60;
-                ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), clength ) );
-                break;
-            case "zzz":
-                // Time zone offset with leading zero
-                hour = value.getTimezoneOffset() / 60;
-                ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), 2 ) +
-                    // Hard coded ":" separator, rather than using cal.TimeSeparator
-                    // Repeated here for consistency, plus ":" was already assumed in date parsing.
-                    ":" + padZeros( Math.abs( value.getTimezoneOffset() % 60 ), 2 ) );
-                break;
-            case "g":
-            case "gg":
-                if ( cal.eras ) {
-                    ret.push( cal.eras[ getEra(value, eras) ].name );
-                }
-                break;
-        case "/":
-            ret.push( cal["/"] );
-            break;
-        default:
-            throw "Invalid date format pattern '" + current + "'.";
-            break;
-        }
-    }
-    return ret.join( '' );
-}
-
-// EXPORTS
-jQuery.global = Globalization;
-
-})();
-
index 4bbc1adf490b1888ba332571d102f7abaa678f1e..7c699ef75d41a3cf12affab3e4412c898cf5e6cc 100644 (file)
@@ -240,7 +240,7 @@ $.widget( "ui.spinner", {
 
                var newVal = this.value() + step * this._increment( this.counter );
 
-               // clamp the new value 
+               // clamp the new value
                newVal = this._trimValue( newVal );
 
                if ( !this.spinning || this._trigger( "spin", event, { value: newVal } ) !== false) {
@@ -308,14 +308,14 @@ $.widget( "ui.spinner", {
 
        _parse: function( val ) {
                if ( typeof val === "string" ) {
-                       val = $.global && this.options.numberFormat ? $.global.parseFloat( val ) : +val;
+                       val = window.Globalize && this.options.numberFormat ? Globalize.parseFloat( val ) : +val;
                }
                return isNaN( val ) ? null : val;
        },
 
        _format: function() {
                var num = this.options.value;
-               return $.global && this.options.numberFormat ? $.global.format( num, this.options.numberFormat ) : num;
+               return window.Globalize && this.options.numberFormat ? Globalize.format( num, this.options.numberFormat ) : num;
        },
 
        _refresh: function() {