aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gruntfile.js17
-rw-r--r--bower.json1
-rw-r--r--build/tasks/testswarm.js1
-rw-r--r--demos/bootstrap.js9
-rw-r--r--demos/calendar/buttonbar.html27
-rw-r--r--demos/calendar/default.html (renamed from demos/datepicker/inline.html)8
-rw-r--r--demos/calendar/dropdown-month-year.html (renamed from demos/datepicker/dropdown-month-year.html)6
-rw-r--r--demos/calendar/index.html22
-rw-r--r--demos/calendar/localization.html41
-rw-r--r--demos/calendar/min-max.html28
-rw-r--r--demos/calendar/multiple-months.html (renamed from demos/datepicker/multiple-calendars.html)11
-rw-r--r--demos/calendar/other-months.html (renamed from demos/datepicker/other-months.html)17
-rw-r--r--demos/calendar/show-week.html25
-rw-r--r--demos/datepicker/alt-field.html24
-rw-r--r--demos/datepicker/animation.html13
-rw-r--r--demos/datepicker/buttonbar.html23
-rw-r--r--demos/datepicker/date-formats.html21
-rw-r--r--demos/datepicker/date-range.html52
-rw-r--r--demos/datepicker/icon-trigger.html22
-rw-r--r--demos/datepicker/index.html13
-rw-r--r--demos/datepicker/localization.html30
-rw-r--r--demos/datepicker/min-max.html21
-rw-r--r--demos/datepicker/show-week.html27
-rw-r--r--demos/index.html1
-rw-r--r--demos/spinner/currency.html7
-rw-r--r--demos/spinner/decimal.html7
-rw-r--r--demos/spinner/time.html6
-rw-r--r--external/cldrjs/LICENSE-MIT/LICENSE-MIT22
-rw-r--r--external/cldrjs/cldr.js667
-rw-r--r--external/cldrjs/cldr/event.js585
-rw-r--r--external/cldrjs/cldr/supplemental.js101
-rw-r--r--external/date.js242
-rw-r--r--external/globalize-old/LICENSE (renamed from external/globalize/LICENSE)0
-rw-r--r--external/globalize-old/globalize.culture.de-DE.js (renamed from external/globalize/globalize.culture.de-DE.js)0
-rw-r--r--external/globalize-old/globalize.culture.ja-JP.js (renamed from external/globalize/globalize.culture.ja-JP.js)0
-rw-r--r--external/globalize-old/globalize.js1585
-rw-r--r--external/globalize/LICENSE.txt43
-rw-r--r--external/globalize/globalize.js1726
-rw-r--r--external/globalize/globalize/date.js1845
-rw-r--r--external/globalize/globalize/number.js1266
-rw-r--r--external/localization.js5357
-rw-r--r--tests/lib/bootstrap.js9
-rw-r--r--tests/unit/all.html1
-rw-r--r--tests/unit/calendar/all.html26
-rw-r--r--tests/unit/calendar/calendar.html21
-rw-r--r--tests/unit/calendar/common.js33
-rw-r--r--tests/unit/calendar/core.js392
-rw-r--r--tests/unit/calendar/events.js0
-rw-r--r--tests/unit/calendar/helper.js31
-rw-r--r--tests/unit/calendar/methods.js145
-rw-r--r--tests/unit/calendar/options.js323
-rw-r--r--tests/unit/date/all.html26
-rw-r--r--tests/unit/date/core.js197
-rw-r--r--tests/unit/date/date.html19
-rw-r--r--tests/unit/datepicker/common.js43
-rw-r--r--tests/unit/datepicker/core.js629
-rw-r--r--tests/unit/datepicker/datepicker.html6
-rw-r--r--tests/unit/datepicker/events.js270
-rw-r--r--tests/unit/datepicker/helper.js36
-rw-r--r--tests/unit/datepicker/methods.js232
-rw-r--r--tests/unit/datepicker/options.js1212
-rw-r--r--tests/unit/index.html1
-rw-r--r--tests/unit/spinner/options.js4
-rw-r--r--tests/visual/compound/datepicker_dialog.html4
-rw-r--r--tests/visual/compound/dialog_widgets.html4
-rw-r--r--tests/visual/dialog/complex-dialogs.html4
-rw-r--r--themes/base/base.css1
-rw-r--r--themes/base/calendar.css158
-rw-r--r--themes/base/datepicker.css160
-rw-r--r--ui/i18n/datepicker-af.js37
-rw-r--r--ui/i18n/datepicker-ar-DZ.js37
-rw-r--r--ui/i18n/datepicker-ar.js38
-rw-r--r--ui/i18n/datepicker-az.js37
-rw-r--r--ui/i18n/datepicker-be.js37
-rw-r--r--ui/i18n/datepicker-bg.js38
-rw-r--r--ui/i18n/datepicker-bs.js37
-rw-r--r--ui/i18n/datepicker-ca.js37
-rw-r--r--ui/i18n/datepicker-cs.js37
-rw-r--r--ui/i18n/datepicker-cy-GB.js37
-rw-r--r--ui/i18n/datepicker-da.js37
-rw-r--r--ui/i18n/datepicker-de.js37
-rw-r--r--ui/i18n/datepicker-el.js37
-rw-r--r--ui/i18n/datepicker-en-AU.js37
-rw-r--r--ui/i18n/datepicker-en-GB.js37
-rw-r--r--ui/i18n/datepicker-en-NZ.js37
-rw-r--r--ui/i18n/datepicker-eo.js37
-rw-r--r--ui/i18n/datepicker-es.js37
-rw-r--r--ui/i18n/datepicker-et.js37
-rw-r--r--ui/i18n/datepicker-eu.js36
-rw-r--r--ui/i18n/datepicker-fa.js73
-rw-r--r--ui/i18n/datepicker-fi.js37
-rw-r--r--ui/i18n/datepicker-fo.js37
-rw-r--r--ui/i18n/datepicker-fr-CA.js37
-rw-r--r--ui/i18n/datepicker-fr-CH.js37
-rw-r--r--ui/i18n/datepicker-fr.js39
-rw-r--r--ui/i18n/datepicker-gl.js37
-rw-r--r--ui/i18n/datepicker-he.js37
-rw-r--r--ui/i18n/datepicker-hi.js37
-rw-r--r--ui/i18n/datepicker-hr.js37
-rw-r--r--ui/i18n/datepicker-hu.js36
-rw-r--r--ui/i18n/datepicker-hy.js37
-rw-r--r--ui/i18n/datepicker-id.js37
-rw-r--r--ui/i18n/datepicker-is.js37
-rw-r--r--ui/i18n/datepicker-it-CH.js37
-rw-r--r--ui/i18n/datepicker-it.js37
-rw-r--r--ui/i18n/datepicker-ja.js37
-rw-r--r--ui/i18n/datepicker-ka.js35
-rw-r--r--ui/i18n/datepicker-kk.js37
-rw-r--r--ui/i18n/datepicker-km.js37
-rw-r--r--ui/i18n/datepicker-ko.js37
-rw-r--r--ui/i18n/datepicker-ky.js38
-rw-r--r--ui/i18n/datepicker-lb.js37
-rw-r--r--ui/i18n/datepicker-lt.js37
-rw-r--r--ui/i18n/datepicker-lv.js37
-rw-r--r--ui/i18n/datepicker-mk.js37
-rw-r--r--ui/i18n/datepicker-ml.js37
-rw-r--r--ui/i18n/datepicker-ms.js37
-rw-r--r--ui/i18n/datepicker-nb.js36
-rw-r--r--ui/i18n/datepicker-nl-BE.js37
-rw-r--r--ui/i18n/datepicker-nl.js37
-rw-r--r--ui/i18n/datepicker-nn.js36
-rw-r--r--ui/i18n/datepicker-no.js37
-rw-r--r--ui/i18n/datepicker-pl.js37
-rw-r--r--ui/i18n/datepicker-pt-BR.js37
-rw-r--r--ui/i18n/datepicker-pt.js36
-rw-r--r--ui/i18n/datepicker-rm.js35
-rw-r--r--ui/i18n/datepicker-ro.js40
-rw-r--r--ui/i18n/datepicker-ru.js37
-rw-r--r--ui/i18n/datepicker-sk.js37
-rw-r--r--ui/i18n/datepicker-sl.js38
-rw-r--r--ui/i18n/datepicker-sq.js37
-rw-r--r--ui/i18n/datepicker-sr-SR.js37
-rw-r--r--ui/i18n/datepicker-sr.js37
-rw-r--r--ui/i18n/datepicker-sv.js37
-rw-r--r--ui/i18n/datepicker-ta.js37
-rw-r--r--ui/i18n/datepicker-th.js37
-rw-r--r--ui/i18n/datepicker-tj.js37
-rw-r--r--ui/i18n/datepicker-tr.js37
-rw-r--r--ui/i18n/datepicker-uk.js38
-rw-r--r--ui/i18n/datepicker-vi.js37
-rw-r--r--ui/i18n/datepicker-zh-CN.js37
-rw-r--r--ui/i18n/datepicker-zh-HK.js37
-rw-r--r--ui/i18n/datepicker-zh-TW.js37
-rw-r--r--ui/widgets/calendar.js657
-rw-r--r--ui/widgets/datepicker.js2193
145 files changed, 15062 insertions, 8469 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index 41961061b..85dfb42be 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -139,7 +139,12 @@ grunt.initConfig({
findNestedDependencies: true,
skipModuleInsertion: true,
exclude: [ "jquery" ],
- include: expandFiles( [ "ui/**/*.js", "!ui/i18n/*" ] ),
+ include: expandFiles( [
+ "ui/**/*.js",
+ "!ui/widgets/calendar.js",
+ "!ui/widgets/datepicker.js",
+ "!ui/i18n/*"
+ ] ),
out: "dist/jquery-ui.js",
wrap: {
start: createBanner( uiFiles ),
@@ -263,6 +268,16 @@ grunt.initConfig({
destPrefix: "external"
},
files: {
+ "cldrjs/cldr.js": "cldrjs/dist/cldr.js",
+ "cldrjs/cldr/event.js": "cldrjs/dist/cldr/event.js",
+ "cldrjs/cldr/supplemental.js": "cldrjs/dist/cldr/supplemental.js",
+ "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT",
+
+ "globalize/globalize.js": "globalize/dist/globalize.js",
+ "globalize/globalize/number.js": "globalize/dist/globalize/number.js",
+ "globalize/globalize/date.js": "globalize/dist/globalize/date.js",
+ "globalize/LICENSE.txt": "globalize/LICENSE.txt",
+
"qunit/qunit.js": "qunit/qunit/qunit.js",
"qunit/qunit.css": "qunit/qunit/qunit.css",
"qunit/LICENSE.txt": "qunit/LICENSE.txt",
diff --git a/bower.json b/bower.json
index 2c8b5a6ba..614e4f78a 100644
--- a/bower.json
+++ b/bower.json
@@ -19,6 +19,7 @@
"qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1",
"qunit-composite": "JamesMGreene/qunit-composite#v1.1.0",
"requirejs": "2.1.14",
+ "globalize": "1.0.0",
"jquery-1.7.0": "jquery#1.7.0",
"jquery-1.7.1": "jquery#1.7.1",
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js
index 3aca0e7b2..b889c6c36 100644
--- a/build/tasks/testswarm.js
+++ b/build/tasks/testswarm.js
@@ -14,6 +14,7 @@ var versions = {
"Accordion": "accordion/accordion.html",
"Autocomplete": "autocomplete/autocomplete.html",
"Button": "button/button.html",
+ "Calendar": "calendar/calendar.html",
"Core": "core/core.html",
"Datepicker": "datepicker/datepicker.html",
"Dialog": "dialog/dialog.html",
diff --git a/demos/bootstrap.js b/demos/bootstrap.js
index 1b28a4dc6..2f2b3209a 100644
--- a/demos/bootstrap.js
+++ b/demos/bootstrap.js
@@ -28,6 +28,7 @@ var widgets = [
"accordion",
"autocomplete",
"button",
+ "calendar",
"datepicker",
"dialog",
"draggable",
@@ -71,12 +72,16 @@ document.documentElement.className = "demo-loading";
require.config( {
baseUrl: "../../ui",
paths: {
+ cldr: "../external/cldrjs/cldr",
+ date: "../external/date",
+ globalize: "../external/globalize/globalize",
+ "globalize-locales": "../external/localization",
jquery: "../external/jquery/jquery",
external: "../external/"
},
shim: {
- "external/globalize/globalize.culture.de-DE": [ "external/globalize/globalize" ],
- "external/globalize/globalize.culture.ja-JP": [ "external/globalize/globalize" ]
+ "external/globalize-old/globalize.culture.de-DE": [ "external/globalize-old/globalize" ],
+ "external/globalize-old/globalize.culture.ja-JP": [ "external/globalize-old/globalize" ]
}
} );
diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html
new file mode 100644
index 000000000..9acd89bdd
--- /dev/null
+++ b/demos/calendar/buttonbar.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar - Display button bar</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "#calendar" ).calendar({
+ buttons: {
+ Today: function() {
+ $( this ).calendar( "valueAsDate", new Date() );
+ }
+ }
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>Display a button for selecting Today's date with the <code>buttons</code> option.</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/inline.html b/demos/calendar/default.html
index 10ad15606..9be0f1988 100644
--- a/demos/datepicker/inline.html
+++ b/demos/calendar/default.html
@@ -2,20 +2,20 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Datepicker - Display inline</title>
+ <title>jQuery UI Calendar - Default functionality</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker();
+ $( "#calendar" ).calendar();
</script>
</head>
<body>
-Date: <div id="datepicker"></div>
+<div id="calendar"></div>
<div class="demo-description">
-<p>Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.</p>
+<p>The calendar is a widget for selecting a date using a visual calendar representation.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html
index 287018866..3aacaef47 100644
--- a/demos/datepicker/dropdown-month-year.html
+++ b/demos/calendar/dropdown-month-year.html
@@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Datepicker - Display month &amp; year menus</title>
+ <title>jQuery UI Calendar - Display month &amp; year menus</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
+ $( "#calendar" ).calendar({
changeMonth: true,
changeYear: true
});
@@ -15,7 +15,7 @@
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
<p>Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean <code>changeMonth</code> and <code>changeYear</code> options.</p>
diff --git a/demos/calendar/index.html b/demos/calendar/index.html
new file mode 100644
index 000000000..751301a00
--- /dev/null
+++ b/demos/calendar/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Calendar Demos</title>
+</head>
+<body>
+
+<ul>
+ <li><a href="default.html">Default functionality</a></li>
+ <li><a href="buttonbar.html">Display button bar</a></li>
+ <li><a href="dropdown-month-year.html">Display month &amp; year menus</a></li>
+ <li><a href="localization.html">Localize calendar</a></li>
+ <li><a href="min-max.html">Restrict date range</a></li>
+ <li><a href="multiple-months.html">Display multiple months</a></li>
+ <li><a href="other-months.html">Dates in other months</a></li>
+ <li><a href="show-week.html">Show week of the year</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html
new file mode 100644
index 000000000..df50ca2c9
--- /dev/null
+++ b/demos/calendar/localization.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar - Localize calendar</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="external/localization">
+ var calendar = $( "#calendar" ),
+ select = $( "#locale" );
+
+ calendar.calendar({
+ locale: select.val()
+ });
+
+ select.change( function() {
+ calendar.calendar( "option", {
+ locale: select.val()
+ });
+ calendar.calendar( "valueAsDate", calendar.calendar( "valueAsDate" ) );
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+<select id="locale">
+ <option value="ar">Arabic</option>
+ <option value="de" selected>German</option>
+ <option value="en">English</option>
+ <option value="es">Spanish</option>
+ <option value="zh">Chinese Simplified</option>
+</select>
+
+<div class="demo-description">
+<p>Localize the calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
+</div>
+</body>
+</html>
diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html
new file mode 100644
index 000000000..36535b875
--- /dev/null
+++ b/demos/calendar/min-max.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar - Restrict date range</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ var now = new Date(),
+ dateMin = new Date( now.getFullYear(), now.getMonth(), now.getDay() + 1 ),
+ dateMax = new Date( now.getFullYear(), now.getMonth(), now.getDay() + 8 );
+
+ $( "#calendar" ).calendar({
+ min: dateMin,
+ max: dateMax
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>Restrict the range of selectable dates with the <code>min</code> and <code>max</code> options. Set the beginning and end dates as actual dates (<code>new Date(2009, 1 - 1, 26)</code>).</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/multiple-calendars.html b/demos/calendar/multiple-months.html
index fa7078e16..3bde416c0 100644
--- a/demos/datepicker/multiple-calendars.html
+++ b/demos/calendar/multiple-months.html
@@ -2,23 +2,22 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Datepicker - Display multiple months</title>
+ <title>jQuery UI Calendar - Display multiple months</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- numberOfMonths: 3,
- showButtonPanel: true
+ $( "#calendar" ).calendar({
+ numberOfMonths: 3
});
</script>
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
-<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single datepicker.</p>
+<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single calendar.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/other-months.html b/demos/calendar/other-months.html
index ecde4edeb..ac8df8d3a 100644
--- a/demos/datepicker/other-months.html
+++ b/demos/calendar/other-months.html
@@ -2,23 +2,28 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Datepicker - Dates in other months</title>
+ <title>jQuery UI Calendar - Dates in other months</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showOtherMonths: true,
- selectOtherMonths: true
+ $( "#calendar" ).calendar({
+ eachDay: function( day ) {
+ if ( day.lead ) {
+ day.render = true;
+ day.selectable = true;
+ day.extraClasses = "ui-priority-secondary";
+ }
+ }
});
</script>
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
-<p>The datepicker can show dates that come from other than the main month
+<p>The calendar can show dates that come from other than the main month
being displayed. These other dates can also be made selectable.</p>
</div>
</body>
diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html
new file mode 100644
index 000000000..96f3c7da2
--- /dev/null
+++ b/demos/calendar/show-week.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar - Show week of the year</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "#calendar" ).calendar({
+ showWeek: true
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>The calendar can show the week of the year. The calculation follows
+ <a href="http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table">Unicode CLDR specification</a>.
+ This means that some days from one year may be placed into weeks 'belonging' to another year.</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html
deleted file mode 100644
index 7a9f4997f..000000000
--- a/demos/datepicker/alt-field.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Datepicker - Populate alternate field</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- altField: "#alternate",
- altFormat: "DD, d MM, yy"
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker">&nbsp;<input type="text" id="alternate" size="30"/></p>
-
-<div class="demo-description">
-<p>Populate an alternate field with its own date format whenever a date is selected using the <code>altField</code> and <code>altFormat</code> options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html
index 0c43b7011..95d18e81b 100644
--- a/demos/datepicker/animation.html
+++ b/demos/datepicker/animation.html
@@ -9,7 +9,11 @@
<script src="../bootstrap.js" data-modules="effect effect-bounce effect-blind effect-bounce effect-clip effect-drop effect-fold effect-slide">
$( "#datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
+ var value = $( this ).val(),
+ hideValue = $( this ).find( "option:selected" ).data( "hide" );
+ $( "#datepicker" )
+ .datepicker( "option", "show", value )
+ .datepicker( "option", "hide", hideValue || value );
});
</script>
</head>
@@ -19,16 +23,15 @@
<p>Animations:<br />
<select id="anim">
- <option value="show">Show (default)</option>
- <option value="slideDown">Slide down</option>
- <option value="fadeIn">Fade in</option>
+ <option value="show">Fade in/out (default)</option>
+ <option value="slideDown" data-hide="slideUp">Slide down/up</option>
<option value="blind">Blind (UI Effect)</option>
<option value="bounce">Bounce (UI Effect)</option>
<option value="clip">Clip (UI Effect)</option>
<option value="drop">Drop (UI Effect)</option>
<option value="fold">Fold (UI Effect)</option>
<option value="slide">Slide (UI Effect)</option>
- <option value="">None</option>
+ <option value="false">None</option>
</select>
</p>
diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html
deleted file mode 100644
index 965a1860a..000000000
--- a/demos/datepicker/buttonbar.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Datepicker - Display button bar</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showButtonPanel: true
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>Display a button for selecting Today's date and a Done button for closing the calendar with the boolean <code>showButtonPanel</code> option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html
index a07d7e336..87f4b0b44 100644
--- a/demos/datepicker/date-formats.html
+++ b/demos/datepicker/date-formats.html
@@ -7,9 +7,17 @@
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker();
+ var value,
+ datepicker = $( "#datepicker" ).datepicker();
+
$( "#format" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option", "dateFormat", $( this ).val() );
+ value = $( this ).val();
+
+ if ( value === "iso" ) {
+ datepicker.datepicker( "option", "dateFormat", { pattern: "yyyy-MM-dd" } );
+ } else {
+ datepicker.datepicker( "option", "dateFormat", { date: value } );
+ }
});
</script>
</head>
@@ -19,12 +27,9 @@
<p>Format options:<br />
<select id="format">
- <option value="mm/dd/yy">Default - mm/dd/yy</option>
- <option value="yy-mm-dd">ISO 8601 - yy-mm-dd</option>
- <option value="d M, y">Short - d M, y</option>
- <option value="d MM, y">Medium - d MM, y</option>
- <option value="DD, d MM, yy">Full - DD, d MM, yy</option>
- <option value="'day' d 'of' MM 'in the year' yy">With text - 'day' d 'of' MM 'in the year' yy</option>
+ <option value="short">Short - M/d/yy in "en" locale</option>
+ <option value="long">Long - MMMM d, y in "en" locale</option>
+ <option value="iso">ISO 8601 - yyyy-MM-dd</option>
</select>
</p>
diff --git a/demos/datepicker/date-range.html b/demos/datepicker/date-range.html
deleted file mode 100644
index b7bc82053..000000000
--- a/demos/datepicker/date-range.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Datepicker - Select a Date Range</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- var dateFormat = "mm/dd/yy",
- from = $( "#from" )
- .datepicker({
- defaultDate: "+1w",
- changeMonth: true,
- numberOfMonths: 3
- })
- .on( "change", function() {
- to.datepicker( "option", "minDate", getDate( this ) );
- }),
- to = $( "#to" ).datepicker({
- defaultDate: "+1w",
- changeMonth: true,
- numberOfMonths: 3
- })
- .on( "change", function() {
- from.datepicker( "option", "maxDate", getDate( this ) );
- });
-
- function getDate( element ) {
- var date;
- try {
- date = $.datepicker.parseDate( dateFormat, element.value );
- } catch( error ) {
- date = null;
- }
-
- return date;
- }
- </script>
-</head>
-<body>
-
-<label for="from">From</label>
-<input type="text" id="from" name="from"/>
-<label for="to">to</label>
-<input type="text" id="to" name="to"/>
-
-<div class="demo-description">
-<p>Select the date range to search for.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html
index 3ea699409..2ab3c2e23 100644
--- a/demos/datepicker/icon-trigger.html
+++ b/demos/datepicker/icon-trigger.html
@@ -7,12 +7,22 @@
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showOn: "button",
- buttonImage: "images/calendar.gif",
- buttonImageOnly: true,
- buttonText: "Select date"
- });
+ var allowOpen = false,
+ datepicker = $( "#datepicker" ).datepicker({
+ beforeOpen: function() {
+ return allowOpen;
+ },
+ open: function() {
+ allowOpen = false;
+ }
+ });
+
+ $( "<img src='images/calendar.gif' alt='Open Datepicker'>")
+ .insertAfter( datepicker )
+ .on( "click", function() {
+ allowOpen = true;
+ datepicker.focus();
+ });
</script>
</head>
<body>
diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html
index d9c8dfc10..a56df7bd6 100644
--- a/demos/datepicker/index.html
+++ b/demos/datepicker/index.html
@@ -9,19 +9,10 @@
<ul>
<li><a href="default.html">Default functionality</a></li>
+ <li><a href="animation.html">Animations</a></li>
<li><a href="date-formats.html">Format date</a></li>
- <li><a href="min-max.html">Restrict date range</a></li>
- <li><a href="localization.html">Localize calendar</a></li>
- <li><a href="alt-field.html">Populate alternate field</a></li>
- <li><a href="inline.html">Display inline</a></li>
- <li><a href="buttonbar.html">Display button bar</a></li>
- <li><a href="dropdown-month-year.html">Display month &amp; year menus</a></li>
- <li><a href="other-months.html">Dates in other months</a></li>
- <li><a href="show-week.html">Show week of the year</a></li>
- <li><a href="multiple-calendars.html">Display multiple months</a></li>
<li><a href="icon-trigger.html">Icon trigger</a></li>
- <li><a href="animation.html">Animations</a></li>
- <li><a href="date-range.html">Date Range</a></li>
+ <li><a href="localization.html">Localize calendar</a></li>
</ul>
</body>
diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html
index 351b2c9e1..4bede0e6a 100644
--- a/demos/datepicker/localization.html
+++ b/demos/datepicker/localization.html
@@ -6,11 +6,19 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="i18n/datepicker-ar i18n/datepicker-fr i18n/datepicker-he i18n/datepicker-zh-TW">
- $( "#datepicker" ).datepicker( $.datepicker.regional[ "fr" ] );
- $( "#locale" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option",
- $.datepicker.regional[ $( this ).val() ] );
+ <script src="../bootstrap.js" data-modules="external/localization">
+ var datepicker = $( "#datepicker" ),
+ select = $( "#locale" );
+
+ datepicker.datepicker({
+ locale: select.val()
+ });
+
+ select.on( "change", function() {
+ datepicker.datepicker( "option", {
+ locale: select.val()
+ });
+ datepicker.datepicker( "valueAsDate", datepicker.datepicker( "valueAsDate" ) );
});
</script>
</head>
@@ -18,15 +26,15 @@
<p>Date: <input type="text" id="datepicker"/>&nbsp;
<select id="locale">
- <option value="ar">Arabic (&#8235;(&#1575;&#1604;&#1593;&#1585;&#1576;&#1610;&#1577;</option>
- <option value="zh-TW">Chinese Traditional (&#32321;&#39636;&#20013;&#25991;)</option>
- <option value="">English</option>
- <option value="fr" selected="selected">French (Fran&ccedil;ais)</option>
- <option value="he">Hebrew (&#8235;(&#1506;&#1489;&#1512;&#1497;&#1514;</option>
+ <option value="ar">Arabic</option>
+ <option value="de" selected>German</option>
+ <option value="en">English</option>
+ <option value="es">Spanish</option>
+ <option value="zh">Chinese Simplified</option>
</select></p>
<div class="demo-description">
-<p>Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
+<p>Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html
deleted file mode 100644
index e28758a3f..000000000
--- a/demos/datepicker/min-max.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Datepicker - Restrict date range</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({ minDate: -20, maxDate: "+1M +10D" });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>Restrict the range of selectable dates with the <code>minDate</code> and <code>maxDate</code> options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html
deleted file mode 100644
index c5a306f70..000000000
--- a/demos/datepicker/show-week.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Datepicker - Show week of the year</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showWeek: true,
- firstDay: 1
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>The datepicker can show the week of the year. The default calculation follows
- the ISO 8601 definition: the week starts on Monday, the first week of the year
- contains the first Thursday of the year. This means that some days from one
- year may be placed into weeks 'belonging' to another year.</p>
-</div>
-</body>
-</html>
diff --git a/demos/index.html b/demos/index.html
index f37874a44..c4a0fdf95 100644
--- a/demos/index.html
+++ b/demos/index.html
@@ -11,6 +11,7 @@
<li><a href="accordion/">accordion</a></li>
<li><a href="autocomplete/">autocomplete</a></li>
<li><a href="button/">button</a></li>
+ <li><a href="calendar/">calendar</a></li>
<li><a href="datepicker/">datepicker</a></li>
<li><a href="dialog/">dialog</a></li>
<li><a href="draggable/">draggable</a></li>
diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html
index c19a1b816..ecf193b09 100644
--- a/demos/spinner/currency.html
+++ b/demos/spinner/currency.html
@@ -6,7 +6,12 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/globalize/globalize.culture.ja-JP external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/globalize-old/globalize.culture.ja-JP
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$( "#currency" ).on( "change", function() {
$( "#spinner" ).spinner( "option", "culture", $( this ).val() );
});
diff --git a/demos/spinner/decimal.html b/demos/spinner/decimal.html
index 680d7b3d3..cb7e2b8a0 100644
--- a/demos/spinner/decimal.html
+++ b/demos/spinner/decimal.html
@@ -6,7 +6,12 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/globalize/globalize.culture.ja-JP external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/globalize-old/globalize.culture.ja-JP
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$( "#spinner" ).spinner({
step: 0.01,
numberFormat: "n"
diff --git a/demos/spinner/time.html b/demos/spinner/time.html
index ff27b1b75..5e8638b1c 100644
--- a/demos/spinner/time.html
+++ b/demos/spinner/time.html
@@ -6,7 +6,11 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$.widget( "ui.timespinner", $.ui.spinner, {
options: {
// seconds
diff --git a/external/cldrjs/LICENSE-MIT/LICENSE-MIT b/external/cldrjs/LICENSE-MIT/LICENSE-MIT
new file mode 100644
index 000000000..6123defa8
--- /dev/null
+++ b/external/cldrjs/LICENSE-MIT/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) Rafael Xavier de Souza http://rafael.xavier.blog.br
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/external/cldrjs/cldr.js b/external/cldrjs/cldr.js
new file mode 100644
index 000000000..5b3c637a8
--- /dev/null
+++ b/external/cldrjs/cldr.js
@@ -0,0 +1,667 @@
+/**
+ * CLDR JavaScript Library v0.4.1
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-02-25T13:51Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( root, factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory();
+ } else {
+ // Global
+ root.Cldr = factory();
+ }
+
+}( this, function() {
+
+
+ var arrayIsArray = Array.isArray || function( obj ) {
+ return Object.prototype.toString.call( obj ) === "[object Array]";
+ };
+
+
+
+
+ var pathNormalize = function( path, attributes ) {
+ if ( arrayIsArray( path ) ) {
+ path = path.join( "/" );
+ }
+ if ( typeof path !== "string" ) {
+ throw new Error( "invalid path \"" + path + "\"" );
+ }
+ // 1: Ignore leading slash `/`
+ // 2: Ignore leading `cldr/`
+ path = path
+ .replace( /^\// , "" ) /* 1 */
+ .replace( /^cldr\// , "" ); /* 2 */
+
+ // Replace {attribute}'s
+ path = path.replace( /{[a-zA-Z]+}/g, function( name ) {
+ name = name.replace( /^{([^}]*)}$/, "$1" );
+ return attributes[ name ];
+ });
+
+ return path.split( "/" );
+ };
+
+
+
+
+ var arraySome = function( array, callback ) {
+ var i, length;
+ if ( array.some ) {
+ return array.some( callback );
+ }
+ for ( i = 0, length = array.length; i < length; i++ ) {
+ if ( callback( array[ i ], i, array ) ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+
+
+
+ /**
+ * Return the maximized language id as defined in
+ * http://www.unicode.org/reports/tr35/#Likely_Subtags
+ * 1. Canonicalize.
+ * 1.1 Make sure the input locale is in canonical form: uses the right
+ * separator, and has the right casing.
+ * TODO Right casing? What df? It seems languages are lowercase, scripts are
+ * Capitalized, territory is uppercase. I am leaving this as an exercise to
+ * the user.
+ *
+ * 1.2 Replace any deprecated subtags with their canonical values using the
+ * <alias> data in supplemental metadata. Use the first value in the
+ * replacement list, if it exists. Language tag replacements may have multiple
+ * parts, such as "sh" ➞ "sr_Latn" or mo" ➞ "ro_MD". In such a case, the
+ * original script and/or region are retained if there is one. Thus
+ * "sh_Arab_AQ" ➞ "sr_Arab_AQ", not "sr_Latn_AQ".
+ * TODO What <alias> data?
+ *
+ * 1.3 If the tag is grandfathered (see <variable id="$grandfathered"
+ * type="choice"> in the supplemental data), then return it.
+ * TODO grandfathered?
+ *
+ * 1.4 Remove the script code 'Zzzz' and the region code 'ZZ' if they occur.
+ * 1.5 Get the components of the cleaned-up source tag (languages, scripts,
+ * and regions), plus any variants and extensions.
+ * 2. Lookup. Lookup each of the following in order, and stop on the first
+ * match:
+ * 2.1 languages_scripts_regions
+ * 2.2 languages_regions
+ * 2.3 languages_scripts
+ * 2.4 languages
+ * 2.5 und_scripts
+ * 3. Return
+ * 3.1 If there is no match, either return an error value, or the match for
+ * "und" (in APIs where a valid language tag is required).
+ * 3.2 Otherwise there is a match = languagem_scriptm_regionm
+ * 3.3 Let xr = xs if xs is not empty, and xm otherwise.
+ * 3.4 Return the language tag composed of languager _ scriptr _ regionr +
+ * variants + extensions.
+ *
+ * @subtags [Array] normalized language id subtags tuple (see init.js).
+ */
+ var coreLikelySubtags = function( Cldr, cldr, subtags, options ) {
+ var match, matchFound,
+ language = subtags[ 0 ],
+ script = subtags[ 1 ],
+ sep = Cldr.localeSep,
+ territory = subtags[ 2 ];
+ options = options || {};
+
+ // Skip if (language, script, territory) is not empty [3.3]
+ if ( language !== "und" && script !== "Zzzz" && territory !== "ZZ" ) {
+ return [ language, script, territory ];
+ }
+
+ // Skip if no supplemental likelySubtags data is present
+ if ( typeof cldr.get( "supplemental/likelySubtags" ) === "undefined" ) {
+ return;
+ }
+
+ // [2]
+ matchFound = arraySome([
+ [ language, script, territory ],
+ [ language, territory ],
+ [ language, script ],
+ [ language ],
+ [ "und", script ]
+ ], function( test ) {
+ return match = !(/\b(Zzzz|ZZ)\b/).test( test.join( sep ) ) /* [1.4] */ && cldr.get( [ "supplemental/likelySubtags", test.join( sep ) ] );
+ });
+
+ // [3]
+ if ( matchFound ) {
+ // [3.2 .. 3.4]
+ match = match.split( sep );
+ return [
+ language !== "und" ? language : match[ 0 ],
+ script !== "Zzzz" ? script : match[ 1 ],
+ territory !== "ZZ" ? territory : match[ 2 ]
+ ];
+ } else if ( options.force ) {
+ // [3.1.2]
+ return cldr.get( "supplemental/likelySubtags/und" ).split( sep );
+ } else {
+ // [3.1.1]
+ return;
+ }
+ };
+
+
+
+ /**
+ * Given a locale, remove any fields that Add Likely Subtags would add.
+ * http://www.unicode.org/reports/tr35/#Likely_Subtags
+ * 1. First get max = AddLikelySubtags(inputLocale). If an error is signaled,
+ * return it.
+ * 2. Remove the variants from max.
+ * 3. Then for trial in {language, language _ region, language _ script}. If
+ * AddLikelySubtags(trial) = max, then return trial + variants.
+ * 4. If you do not get a match, return max + variants.
+ *
+ * @maxLanguageId [Array] maxLanguageId tuple (see init.js).
+ */
+ var coreRemoveLikelySubtags = function( Cldr, cldr, maxLanguageId ) {
+ var match, matchFound,
+ language = maxLanguageId[ 0 ],
+ script = maxLanguageId[ 1 ],
+ territory = maxLanguageId[ 2 ];
+
+ // [3]
+ matchFound = arraySome([
+ [ [ language, "Zzzz", "ZZ" ], [ language ] ],
+ [ [ language, "Zzzz", territory ], [ language, territory ] ],
+ [ [ language, script, "ZZ" ], [ language, script ] ]
+ ], function( test ) {
+ var result = coreLikelySubtags( Cldr, cldr, test[ 0 ] );
+ match = test[ 1 ];
+ return result && result[ 0 ] === maxLanguageId[ 0 ] &&
+ result[ 1 ] === maxLanguageId[ 1 ] &&
+ result[ 2 ] === maxLanguageId[ 2 ];
+ });
+
+ // [4]
+ return matchFound ? match : maxLanguageId;
+ };
+
+
+
+
+ /**
+ * subtags( locale )
+ *
+ * @locale [String]
+ */
+ var coreSubtags = function( locale ) {
+ var aux, unicodeLanguageId,
+ subtags = [];
+
+ locale = locale.replace( /_/, "-" );
+
+ // Unicode locale extensions.
+ aux = locale.split( "-u-" );
+ if ( aux[ 1 ] ) {
+ aux[ 1 ] = aux[ 1 ].split( "-t-" );
+ locale = aux[ 0 ] + ( aux[ 1 ][ 1 ] ? "-t-" + aux[ 1 ][ 1 ] : "");
+ subtags[ 4 /* unicodeLocaleExtensions */ ] = aux[ 1 ][ 0 ];
+ }
+
+ // TODO normalize transformed extensions. Currently, skipped.
+ // subtags[ x ] = locale.split( "-t-" )[ 1 ];
+ unicodeLanguageId = locale.split( "-t-" )[ 0 ];
+
+ // unicode_language_id = "root"
+ // | unicode_language_subtag
+ // (sep unicode_script_subtag)?
+ // (sep unicode_region_subtag)?
+ // (sep unicode_variant_subtag)* ;
+ //
+ // Although unicode_language_subtag = alpha{2,8}, I'm using alpha{2,3}. Because, there's no language on CLDR lengthier than 3.
+ aux = unicodeLanguageId.match( /^(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)(-[a-zA-Z0-9]{5,8}|[0-9][a-zA-Z0-9]{3})*$|^(root)$/ );
+ if ( aux === null ) {
+ return [ "und", "Zzzz", "ZZ" ];
+ }
+ subtags[ 0 /* language */ ] = aux[ 9 ] /* root */ || aux[ 2 ] || "und";
+ subtags[ 1 /* script */ ] = aux[ 4 ] || "Zzzz";
+ subtags[ 2 /* territory */ ] = aux[ 6 ] || "ZZ";
+ subtags[ 3 /* variant */ ] = aux[ 7 ];
+
+ // 0: language
+ // 1: script
+ // 2: territory (aka region)
+ // 3: variant
+ // 4: unicodeLocaleExtensions
+ return subtags;
+ };
+
+
+
+
+ var arrayForEach = function( array, callback ) {
+ var i, length;
+ if ( array.forEach ) {
+ return array.forEach( callback );
+ }
+ for ( i = 0, length = array.length; i < length; i++ ) {
+ callback( array[ i ], i, array );
+ }
+ };
+
+
+
+
+ /**
+ * bundleLookup( minLanguageId )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @cldr [Cldr instance]
+ *
+ * @minLanguageId [String] requested languageId after applied remove likely subtags.
+ */
+ var bundleLookup = function( Cldr, cldr, minLanguageId ) {
+ var availableBundleMap = Cldr._availableBundleMap,
+ availableBundleMapQueue = Cldr._availableBundleMapQueue;
+
+ if ( availableBundleMapQueue.length ) {
+ arrayForEach( availableBundleMapQueue, function( bundle ) {
+ var existing, maxBundle, minBundle, subtags;
+ subtags = coreSubtags( bundle );
+ maxBundle = coreLikelySubtags( Cldr, cldr, subtags, { force: true } ) || subtags;
+ minBundle = coreRemoveLikelySubtags( Cldr, cldr, maxBundle );
+ minBundle = minBundle.join( Cldr.localeSep );
+ existing = availableBundleMapQueue[ minBundle ];
+ if ( existing && existing.length < bundle.length ) {
+ return;
+ }
+ availableBundleMap[ minBundle ] = bundle;
+ });
+ Cldr._availableBundleMapQueue = [];
+ }
+
+ return availableBundleMap[ minLanguageId ] || null;
+ };
+
+
+
+
+ var objectKeys = function( object ) {
+ var i,
+ result = [];
+
+ if ( Object.keys ) {
+ return Object.keys( object );
+ }
+
+ for ( i in object ) {
+ result.push( i );
+ }
+
+ return result;
+ };
+
+
+
+
+ var createError = function( code, attributes ) {
+ var error, message;
+
+ message = code + ( attributes && JSON ? ": " + JSON.stringify( attributes ) : "" );
+ error = new Error( message );
+ error.code = code;
+
+ // extend( error, attributes );
+ arrayForEach( objectKeys( attributes ), function( attribute ) {
+ error[ attribute ] = attributes[ attribute ];
+ });
+
+ return error;
+ };
+
+
+
+
+ var validate = function( code, check, attributes ) {
+ if ( !check ) {
+ throw createError( code, attributes );
+ }
+ };
+
+
+
+
+ var validatePresence = function( value, name ) {
+ validate( "E_MISSING_PARAMETER", typeof value !== "undefined", {
+ name: name
+ });
+ };
+
+
+
+
+ var validateType = function( value, name, check, expected ) {
+ validate( "E_INVALID_PAR_TYPE", check, {
+ expected: expected,
+ name: name,
+ value: value
+ });
+ };
+
+
+
+
+ var validateTypePath = function( value, name ) {
+ validateType( value, name, typeof value === "string" || arrayIsArray( value ), "String or Array" );
+ };
+
+
+
+
+ /**
+ * Function inspired by jQuery Core, but reduced to our use case.
+ */
+ var isPlainObject = function( obj ) {
+ return obj !== null && "" + obj === "[object Object]";
+ };
+
+
+
+
+ var validateTypePlainObject = function( value, name ) {
+ validateType( value, name, typeof value === "undefined" || isPlainObject( value ), "Plain Object" );
+ };
+
+
+
+
+ var validateTypeString = function( value, name ) {
+ validateType( value, name, typeof value === "string", "a string" );
+ };
+
+
+
+
+ // @path: normalized path
+ var resourceGet = function( data, path ) {
+ var i,
+ node = data,
+ length = path.length;
+
+ for ( i = 0; i < length - 1; i++ ) {
+ node = node[ path[ i ] ];
+ if ( !node ) {
+ return undefined;
+ }
+ }
+ return node[ path[ i ] ];
+ };
+
+
+
+
+ /**
+ * setAvailableBundles( Cldr, json )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @json resolved/unresolved cldr data.
+ *
+ * Set available bundles queue based on passed json CLDR data. Considers a bundle as any String at /main/{bundle}.
+ */
+ var coreSetAvailableBundles = function( Cldr, json ) {
+ var bundle,
+ availableBundleMapQueue = Cldr._availableBundleMapQueue,
+ main = resourceGet( json, [ "main" ] );
+
+ if ( main ) {
+ for ( bundle in main ) {
+ if ( main.hasOwnProperty( bundle ) && bundle !== "root" ) {
+ availableBundleMapQueue.push( bundle );
+ }
+ }
+ }
+ };
+
+
+
+ var alwaysArray = function( somethingOrArray ) {
+ return arrayIsArray( somethingOrArray ) ? somethingOrArray : [ somethingOrArray ];
+ };
+
+
+ var jsonMerge = (function() {
+
+ // Returns new deeply merged JSON.
+ //
+ // Eg.
+ // merge( { a: { b: 1, c: 2 } }, { a: { b: 3, d: 4 } } )
+ // -> { a: { b: 3, c: 2, d: 4 } }
+ //
+ // @arguments JSON's
+ //
+ var merge = function() {
+ var destination = {},
+ sources = [].slice.call( arguments, 0 );
+ arrayForEach( sources, function( source ) {
+ var prop;
+ for ( prop in source ) {
+ if ( prop in destination && arrayIsArray( destination[ prop ] ) ) {
+
+ // Concat Arrays
+ destination[ prop ] = destination[ prop ].concat( source[ prop ] );
+
+ } else if ( prop in destination && typeof destination[ prop ] === "object" ) {
+
+ // Merge Objects
+ destination[ prop ] = merge( destination[ prop ], source[ prop ] );
+
+ } else {
+
+ // Set new values
+ destination[ prop ] = source[ prop ];
+
+ }
+ }
+ });
+ return destination;
+ };
+
+ return merge;
+
+}());
+
+
+ /**
+ * load( Cldr, source, jsons )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @source [Object]
+ *
+ * @jsons [arguments]
+ */
+ var coreLoad = function( Cldr, source, jsons ) {
+ var i, j, json;
+
+ validatePresence( jsons[ 0 ], "json" );
+
+ // Support arbitrary parameters, e.g., `Cldr.load({...}, {...})`.
+ for ( i = 0; i < jsons.length; i++ ) {
+
+ // Support array parameters, e.g., `Cldr.load([{...}, {...}])`.
+ json = alwaysArray( jsons[ i ] );
+
+ for ( j = 0; j < json.length; j++ ) {
+ validateTypePlainObject( json[ j ], "json" );
+ source = jsonMerge( source, json[ j ] );
+ coreSetAvailableBundles( Cldr, json[ j ] );
+ }
+ }
+
+ return source;
+ };
+
+
+
+ var itemGetResolved = function( Cldr, path, attributes ) {
+ // Resolve path
+ var normalizedPath = pathNormalize( path, attributes );
+
+ return resourceGet( Cldr._resolved, normalizedPath );
+ };
+
+
+
+
+ /**
+ * new Cldr()
+ */
+ var Cldr = function( locale ) {
+ this.init( locale );
+ };
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ Cldr._alwaysArray = alwaysArray;
+ Cldr._coreLoad = coreLoad;
+ Cldr._createError = createError;
+ Cldr._itemGetResolved = itemGetResolved;
+ Cldr._jsonMerge = jsonMerge;
+ Cldr._pathNormalize = pathNormalize;
+ Cldr._resourceGet = resourceGet;
+ Cldr._validatePresence = validatePresence;
+ Cldr._validateType = validateType;
+ Cldr._validateTypePath = validateTypePath;
+ Cldr._validateTypePlainObject = validateTypePlainObject;
+
+ Cldr._availableBundleMap = {};
+ Cldr._availableBundleMapQueue = [];
+ Cldr._resolved = {};
+
+ // Allow user to override locale separator "-" (default) | "_". According to http://www.unicode.org/reports/tr35/#Unicode_language_identifier, both "-" and "_" are valid locale separators (eg. "en_GB", "en-GB"). According to http://unicode.org/cldr/trac/ticket/6786 its usage must be consistent throughout the data set.
+ Cldr.localeSep = "-";
+
+ /**
+ * Cldr.load( json [, json, ...] )
+ *
+ * @json [JSON] CLDR data or [Array] Array of @json's.
+ *
+ * Load resolved cldr data.
+ */
+ Cldr.load = function() {
+ Cldr._resolved = coreLoad( Cldr, Cldr._resolved, arguments );
+ };
+
+ /**
+ * .init() automatically run on instantiation/construction.
+ */
+ Cldr.prototype.init = function( locale ) {
+ var attributes, language, maxLanguageId, minLanguageId, script, subtags, territory, unicodeLocaleExtensions, variant,
+ sep = Cldr.localeSep;
+
+ validatePresence( locale, "locale" );
+ validateTypeString( locale, "locale" );
+
+ subtags = coreSubtags( locale );
+
+ unicodeLocaleExtensions = subtags[ 4 ];
+ variant = subtags[ 3 ];
+
+ // Normalize locale code.
+ // Get (or deduce) the "triple subtags": language, territory (also aliased as region), and script subtags.
+ // Get the variant subtags (calendar, collation, currency, etc).
+ // refs:
+ // - http://www.unicode.org/reports/tr35/#Field_Definitions
+ // - http://www.unicode.org/reports/tr35/#Language_and_Locale_IDs
+ // - http://www.unicode.org/reports/tr35/#Unicode_locale_identifier
+
+ // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags.
+ maxLanguageId = coreLikelySubtags( Cldr, this, subtags, { force: true } ) || subtags;
+ language = maxLanguageId[ 0 ];
+ script = maxLanguageId[ 1 ];
+ territory = maxLanguageId[ 2 ];
+
+ minLanguageId = coreRemoveLikelySubtags( Cldr, this, maxLanguageId ).join( sep );
+
+ // Set attributes
+ this.attributes = attributes = {
+ bundle: bundleLookup( Cldr, this, minLanguageId ),
+
+ // Unicode Language Id
+ minlanguageId: minLanguageId,
+ maxLanguageId: maxLanguageId.join( sep ),
+
+ // Unicode Language Id Subtabs
+ language: language,
+ script: script,
+ territory: territory,
+ region: territory, /* alias */
+ variant: variant
+ };
+
+ // Unicode locale extensions.
+ unicodeLocaleExtensions && ( "-" + unicodeLocaleExtensions ).replace( /-[a-z]{3,8}|(-[a-z]{2})-([a-z]{3,8})/g, function( attribute, key, type ) {
+
+ if ( key ) {
+
+ // Extension is in the `keyword` form.
+ attributes[ "u" + key ] = type;
+ } else {
+
+ // Extension is in the `attribute` form.
+ attributes[ "u" + attribute ] = true;
+ }
+ });
+
+ this.locale = locale;
+ };
+
+ /**
+ * .get()
+ */
+ Cldr.prototype.get = function( path ) {
+
+ validatePresence( path, "path" );
+ validateTypePath( path, "path" );
+
+ return itemGetResolved( Cldr, path, this.attributes );
+ };
+
+ /**
+ * .main()
+ */
+ Cldr.prototype.main = function( path ) {
+ validatePresence( path, "path" );
+ validateTypePath( path, "path" );
+
+ validate( "E_MISSING_BUNDLE", this.attributes.bundle !== null, {
+ locale: this.locale
+ });
+
+ path = alwaysArray( path );
+ return this.get( [ "main/{bundle}" ].concat( path ) );
+ };
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/cldrjs/cldr/event.js b/external/cldrjs/cldr/event.js
new file mode 100644
index 000000000..f9eaa368b
--- /dev/null
+++ b/external/cldrjs/cldr/event.js
@@ -0,0 +1,585 @@
+/**
+ * CLDR JavaScript Library v0.4.1
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-02-25T13:51Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( [ "../cldr" ], factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
+ // Global
+ factory( Cldr );
+ }
+
+}(function( Cldr ) {
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ var pathNormalize = Cldr._pathNormalize,
+ validatePresence = Cldr._validatePresence,
+ validateType = Cldr._validateType;
+
+/*!
+ * EventEmitter v4.2.7 - git.io/ee
+ * Oliver Caldwell
+ * MIT license
+ * @preserve
+ */
+
+var EventEmitter;
+/* jshint ignore:start */
+EventEmitter = (function () {
+
+
+ /**
+ * Class for managing events.
+ * Can be extended to provide event functionality in other classes.
+ *
+ * @class EventEmitter Manages event registering and emitting.
+ */
+ function EventEmitter() {}
+
+ // Shortcuts to improve speed and size
+ var proto = EventEmitter.prototype;
+ var exports = this;
+ var originalGlobalValue = exports.EventEmitter;
+
+ /**
+ * Finds the index of the listener for the event in it's storage array.
+ *
+ * @param {Function[]} listeners Array of listeners to search through.
+ * @param {Function} listener Method to look for.
+ * @return {Number} Index of the specified listener, -1 if not found
+ * @api private
+ */
+ function indexOfListener(listeners, listener) {
+ var i = listeners.length;
+ while (i--) {
+ if (listeners[i].listener === listener) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Alias a method while keeping the context correct, to allow for overwriting of target method.
+ *
+ * @param {String} name The name of the target method.
+ * @return {Function} The aliased method
+ * @api private
+ */
+ function alias(name) {
+ return function aliasClosure() {
+ return this[name].apply(this, arguments);
+ };
+ }
+
+ /**
+ * Returns the listener array for the specified event.
+ * Will initialise the event object and listener arrays if required.
+ * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
+ * Each property in the object response is an array of listener functions.
+ *
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
+ * @return {Function[]|Object} All listener functions for the event.
+ */
+ proto.getListeners = function getListeners(evt) {
+ var events = this._getEvents();
+ var response;
+ var key;
+
+ // Return a concatenated array of all matching events if
+ // the selector is a regular expression.
+ if (evt instanceof RegExp) {
+ response = {};
+ for (key in events) {
+ if (events.hasOwnProperty(key) && evt.test(key)) {
+ response[key] = events[key];
+ }
+ }
+ }
+ else {
+ response = events[evt] || (events[evt] = []);
+ }
+
+ return response;
+ };
+
+ /**
+ * Takes a list of listener objects and flattens it into a list of listener functions.
+ *
+ * @param {Object[]} listeners Raw listener objects.
+ * @return {Function[]} Just the listener functions.
+ */
+ proto.flattenListeners = function flattenListeners(listeners) {
+ var flatListeners = [];
+ var i;
+
+ for (i = 0; i < listeners.length; i += 1) {
+ flatListeners.push(listeners[i].listener);
+ }
+
+ return flatListeners;
+ };
+
+ /**
+ * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
+ *
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
+ * @return {Object} All listener functions for an event in an object.
+ */
+ proto.getListenersAsObject = function getListenersAsObject(evt) {
+ var listeners = this.getListeners(evt);
+ var response;
+
+ if (listeners instanceof Array) {
+ response = {};
+ response[evt] = listeners;
+ }
+
+ return response || listeners;
+ };
+
+ /**
+ * Adds a listener function to the specified event.
+ * The listener will not be added if it is a duplicate.
+ * If the listener returns true then it will be removed after it is called.
+ * If you pass a regular expression as the event name then the listener will be added to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addListener = function addListener(evt, listener) {
+ var listeners = this.getListenersAsObject(evt);
+ var listenerIsWrapped = typeof listener === 'object';
+ var key;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
+ listeners[key].push(listenerIsWrapped ? listener : {
+ listener: listener,
+ once: false
+ });
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of addListener
+ */
+ proto.on = alias('addListener');
+
+ /**
+ * Semi-alias of addListener. It will add a listener that will be
+ * automatically removed after it's first execution.
+ *
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addOnceListener = function addOnceListener(evt, listener) {
+ return this.addListener(evt, {
+ listener: listener,
+ once: true
+ });
+ };
+
+ /**
+ * Alias of addOnceListener.
+ */
+ proto.once = alias('addOnceListener');
+
+ /**
+ * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
+ * You need to tell it what event names should be matched by a regex.
+ *
+ * @param {String} evt Name of the event to create.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.defineEvent = function defineEvent(evt) {
+ this.getListeners(evt);
+ return this;
+ };
+
+ /**
+ * Uses defineEvent to define multiple events.
+ *
+ * @param {String[]} evts An array of event names to define.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.defineEvents = function defineEvents(evts) {
+ for (var i = 0; i < evts.length; i += 1) {
+ this.defineEvent(evts[i]);
+ }
+ return this;
+ };
+
+ /**
+ * Removes a listener function from the specified event.
+ * When passed a regular expression as the event name, it will remove the listener from all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to remove the listener from.
+ * @param {Function} listener Method to remove from the event.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeListener = function removeListener(evt, listener) {
+ var listeners = this.getListenersAsObject(evt);
+ var index;
+ var key;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key)) {
+ index = indexOfListener(listeners[key], listener);
+
+ if (index !== -1) {
+ listeners[key].splice(index, 1);
+ }
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of removeListener
+ */
+ proto.off = alias('removeListener');
+
+ /**
+ * Adds listeners in bulk using the manipulateListeners method.
+ * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
+ * You can also pass it a regular expression to add the array of listeners to all events that match it.
+ * Yeah, this function does quite a bit. That's probably a bad thing.
+ *
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to add.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addListeners = function addListeners(evt, listeners) {
+ // Pass through to manipulateListeners
+ return this.manipulateListeners(false, evt, listeners);
+ };
+
+ /**
+ * Removes listeners in bulk using the manipulateListeners method.
+ * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
+ * You can also pass it an event name and an array of listeners to be removed.
+ * You can also pass it a regular expression to remove the listeners from all events that match it.
+ *
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to remove.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeListeners = function removeListeners(evt, listeners) {
+ // Pass through to manipulateListeners
+ return this.manipulateListeners(true, evt, listeners);
+ };
+
+ /**
+ * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
+ * The first argument will determine if the listeners are removed (true) or added (false).
+ * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
+ * You can also pass it an event name and an array of listeners to be added/removed.
+ * You can also pass it a regular expression to manipulate the listeners of all events that match it.
+ *
+ * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
+ var i;
+ var value;
+ var single = remove ? this.removeListener : this.addListener;
+ var multiple = remove ? this.removeListeners : this.addListeners;
+
+ // If evt is an object then pass each of it's properties to this method
+ if (typeof evt === 'object' && !(evt instanceof RegExp)) {
+ for (i in evt) {
+ if (evt.hasOwnProperty(i) && (value = evt[i])) {
+ // Pass the single listener straight through to the singular method
+ if (typeof value === 'function') {
+ single.call(this, i, value);
+ }
+ else {
+ // Otherwise pass back to the multiple function
+ multiple.call(this, i, value);
+ }
+ }
+ }
+ }
+ else {
+ // So evt must be a string
+ // And listeners must be an array of listeners
+ // Loop over it and pass each one to the multiple method
+ i = listeners.length;
+ while (i--) {
+ single.call(this, evt, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Removes all listeners from a specified event.
+ * If you do not specify an event then all listeners will be removed.
+ * That means every event will be emptied.
+ * You can also pass a regex to remove all events that match it.
+ *
+ * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeEvent = function removeEvent(evt) {
+ var type = typeof evt;
+ var events = this._getEvents();
+ var key;
+
+ // Remove different things depending on the state of evt
+ if (type === 'string') {
+ // Remove all listeners for the specified event
+ delete events[evt];
+ }
+ else if (evt instanceof RegExp) {
+ // Remove all events matching the regex.
+ for (key in events) {
+ if (events.hasOwnProperty(key) && evt.test(key)) {
+ delete events[key];
+ }
+ }
+ }
+ else {
+ // Remove all listeners in all events
+ delete this._events;
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of removeEvent.
+ *
+ * Added to mirror the node API.
+ */
+ proto.removeAllListeners = alias('removeEvent');
+
+ /**
+ * Emits an event of your choice.
+ * When emitted, every listener attached to that event will be executed.
+ * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
+ * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
+ * So they will not arrive within the array on the other side, they will be separate.
+ * You can also pass a regular expression to emit to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
+ * @param {Array} [args] Optional array of arguments to be passed to each listener.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.emitEvent = function emitEvent(evt, args) {
+ var listeners = this.getListenersAsObject(evt);
+ var listener;
+ var i;
+ var key;
+ var response;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key)) {
+ i = listeners[key].length;
+
+ while (i--) {
+ // If the listener returns true then it shall be removed from the event
+ // The function is executed either with a basic call or an apply if there is an args array
+ listener = listeners[key][i];
+
+ if (listener.once === true) {
+ this.removeListener(evt, listener.listener);
+ }
+
+ response = listener.listener.apply(this, args || []);
+
+ if (response === this._getOnceReturnValue()) {
+ this.removeListener(evt, listener.listener);
+ }
+ }
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of emitEvent
+ */
+ proto.trigger = alias('emitEvent');
+
+ /**
+ * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
+ * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
+ * @param {...*} Optional additional arguments to be passed to each listener.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.emit = function emit(evt) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return this.emitEvent(evt, args);
+ };
+
+ /**
+ * Sets the current value to check against when executing listeners. If a
+ * listeners return value matches the one set here then it will be removed
+ * after execution. This value defaults to true.
+ *
+ * @param {*} value The new value to check for when executing listeners.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.setOnceReturnValue = function setOnceReturnValue(value) {
+ this._onceReturnValue = value;
+ return this;
+ };
+
+ /**
+ * Fetches the current value to check against when executing listeners. If
+ * the listeners return value matches this one then it should be removed
+ * automatically. It will return true by default.
+ *
+ * @return {*|Boolean} The current value to check for or the default, true.
+ * @api private
+ */
+ proto._getOnceReturnValue = function _getOnceReturnValue() {
+ if (this.hasOwnProperty('_onceReturnValue')) {
+ return this._onceReturnValue;
+ }
+ else {
+ return true;
+ }
+ };
+
+ /**
+ * Fetches the events object and creates one if required.
+ *
+ * @return {Object} The events storage object.
+ * @api private
+ */
+ proto._getEvents = function _getEvents() {
+ return this._events || (this._events = {});
+ };
+
+ /**
+ * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
+ *
+ * @return {Function} Non conflicting EventEmitter class.
+ */
+ EventEmitter.noConflict = function noConflict() {
+ exports.EventEmitter = originalGlobalValue;
+ return EventEmitter;
+ };
+
+ return EventEmitter;
+}());
+/* jshint ignore:end */
+
+
+
+ var validateTypeFunction = function( value, name ) {
+ validateType( value, name, typeof value === "undefined" || typeof value === "function", "Function" );
+ };
+
+
+
+
+ var superGet, superInit,
+ globalEe = new EventEmitter();
+
+ function validateTypeEvent( value, name ) {
+ validateType( value, name, typeof value === "string" || value instanceof RegExp, "String or RegExp" );
+ }
+
+ function validateThenCall( method, self ) {
+ return function( event, listener ) {
+ validatePresence( event, "event" );
+ validateTypeEvent( event, "event" );
+
+ validatePresence( listener, "listener" );
+ validateTypeFunction( listener, "listener" );
+
+ return self[ method ].apply( self, arguments );
+ };
+ }
+
+ function off( self ) {
+ return validateThenCall( "off", self );
+ }
+
+ function on( self ) {
+ return validateThenCall( "on", self );
+ }
+
+ function once( self ) {
+ return validateThenCall( "once", self );
+ }
+
+ Cldr.off = off( globalEe );
+ Cldr.on = on( globalEe );
+ Cldr.once = once( globalEe );
+
+ /**
+ * Overload Cldr.prototype.init().
+ */
+ superInit = Cldr.prototype.init;
+ Cldr.prototype.init = function() {
+ var ee;
+ this.ee = ee = new EventEmitter();
+ this.off = off( ee );
+ this.on = on( ee );
+ this.once = once( ee );
+ superInit.apply( this, arguments );
+ };
+
+ /**
+ * getOverload is encapsulated, because of cldr/unresolved. If it's loaded
+ * after cldr/event (and note it overwrites .get), it can trigger this
+ * overload again.
+ */
+ function getOverload() {
+
+ /**
+ * Overload Cldr.prototype.get().
+ */
+ superGet = Cldr.prototype.get;
+ Cldr.prototype.get = function( path ) {
+ var value = superGet.apply( this, arguments );
+ path = pathNormalize( path, this.attributes ).join( "/" );
+ globalEe.trigger( "get", [ path, value ] );
+ this.ee.trigger( "get", [ path, value ] );
+ return value;
+ };
+ }
+
+ Cldr._eventInit = getOverload;
+ getOverload();
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/cldrjs/cldr/supplemental.js b/external/cldrjs/cldr/supplemental.js
new file mode 100644
index 000000000..87153683c
--- /dev/null
+++ b/external/cldrjs/cldr/supplemental.js
@@ -0,0 +1,101 @@
+/**
+ * CLDR JavaScript Library v0.4.1
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-02-25T13:51Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( [ "../cldr" ], factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
+ // Global
+ factory( Cldr );
+ }
+
+}(function( Cldr ) {
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ var alwaysArray = Cldr._alwaysArray;
+
+
+
+ var supplementalMain = function( cldr ) {
+
+ var prepend, supplemental;
+
+ prepend = function( prepend ) {
+ return function( path ) {
+ path = alwaysArray( path );
+ return cldr.get( [ prepend ].concat( path ) );
+ };
+ };
+
+ supplemental = prepend( "supplemental" );
+
+ // Week Data
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Week_Data
+ supplemental.weekData = prepend( "supplemental/weekData" );
+
+ supplemental.weekData.firstDay = function() {
+ return cldr.get( "supplemental/weekData/firstDay/{territory}" ) ||
+ cldr.get( "supplemental/weekData/firstDay/001" );
+ };
+
+ supplemental.weekData.minDays = function() {
+ var minDays = cldr.get( "supplemental/weekData/minDays/{territory}" ) ||
+ cldr.get( "supplemental/weekData/minDays/001" );
+ return parseInt( minDays, 10 );
+ };
+
+ // Time Data
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ supplemental.timeData = prepend( "supplemental/timeData" );
+
+ supplemental.timeData.allowed = function() {
+ return cldr.get( "supplemental/timeData/{territory}/_allowed" ) ||
+ cldr.get( "supplemental/timeData/001/_allowed" );
+ };
+
+ supplemental.timeData.preferred = function() {
+ return cldr.get( "supplemental/timeData/{territory}/_preferred" ) ||
+ cldr.get( "supplemental/timeData/001/_preferred" );
+ };
+
+ return supplemental;
+
+ };
+
+
+
+
+ var initSuper = Cldr.prototype.init;
+
+ /**
+ * .init() automatically ran on construction.
+ *
+ * Overload .init().
+ */
+ Cldr.prototype.init = function() {
+ initSuper.apply( this, arguments );
+ this.supplemental = supplementalMain( this );
+ };
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/date.js b/external/date.js
new file mode 100644
index 000000000..4cb29ef27
--- /dev/null
+++ b/external/date.js
@@ -0,0 +1,242 @@
+/*
+ * Calendar math built on jquery-global
+ *
+ * Based on Marc Grabanski's jQuery Date Plugin
+ * http://marcgrabanski.com/articles/jquery-date-plugin
+ */
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}( function( $ ) {
+
+$.ui = $.ui || {};
+
+var _Date,
+ weekdaysRev = {
+ "sun": 0,
+ "mon": 1,
+ "tue": 2,
+ "wed": 3,
+ "thu": 4,
+ "fri": 5,
+ "sat": 6
+ };
+
+_Date = function( date, attributes ) {
+ if ( !( this instanceof _Date ) ) {
+ return new _Date( date, attributes );
+ }
+
+ this.setAttributes( attributes );
+
+ if ( typeof date === "string" && date.length ) {
+ this.dateObject = attributes.parse( date );
+ } else if ( $.type( date ) === "date" ) {
+ this.dateObject = date;
+ }
+
+ this.dateObject = this.dateObject || new Date();
+};
+
+$.extend( _Date.prototype, {
+
+ setAttributes: function( attributes ) {
+ this.attributes = attributes;
+ this.firstDay = weekdaysRev[ this.attributes.firstDay ];
+ },
+
+ //TODO: same as the underlying Date object's terminology, but still misleading.
+ //TODO: We can use .setTime() instead of new Date and rename to setTimestamp.
+ setTime: function( time ) {
+ this.dateObject = new Date( time );
+ return this;
+ },
+
+ setDay: function( day ) {
+ var date = this.dateObject;
+ // FIXME: Why not to use .setDate?
+ this.dateObject = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setMonth: function( month ) {
+
+ // Overflow example: Month is October 31 (yeah Halloween) and month is changed to April with 30 days,
+ // the new date will me May 1. We will honor the month the user wants to set and if and overflow
+ // occurs, set to last day of month.
+ var date = this.dateObject,
+ days = date.getDay(), year = date.getFullYear();
+ if ( days > this.daysInMonth( year, month ) ) {
+
+ // Overflow
+ days = this.daysInMonth( year, month );
+ }
+ this.dateObject = new Date( year, month, days, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setYear: function( year ) {
+ var date = this.dateObject,
+ day = date.getDate(),
+ month = date.getMonth();
+
+ // Check if Leap, and February and day is 29th
+ if ( this.isLeapYear( year ) && month == 1 && day == 29 ) {
+
+ // set day to last day of February
+ day = this.daysInMonth( year, month );
+ }
+ this.dateObject = new Date( year, month, day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setFullDate: function( year, month, day ) {
+ this.dateObject = new Date( year, month, day );
+ return this;
+ },
+
+ adjust: function( period, offset ) {
+ var date = this.dateObject,
+ day = period == "D" ? date.getDate() + offset : date.getDate(),
+ month = period == "M" ? date.getMonth() + offset : date.getMonth(),
+ year = period == "Y" ? date.getFullYear() + offset : date.getFullYear();
+
+ // If not day, update the day to the new month and year
+ if ( period != "D" ) {
+ day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) );
+ }
+ this.dateObject = new Date( year, month, day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ daysInMonth: function( year, month ) {
+ var date = this.dateObject;
+ year = year || date.getFullYear();
+ month = month || date.getMonth();
+ return 32 - new Date( year, month, 32 ).getDate();
+ },
+
+ monthName: function() {
+ return this.attributes.formatMonth( this.dateObject );
+ },
+
+ day: function() {
+ return this.dateObject.getDate();
+ },
+
+ month: function() {
+ return this.dateObject.getMonth();
+ },
+
+ year: function() {
+ return this.dateObject.getFullYear();
+ },
+
+ isLeapYear: function( year ) {
+ year = year || this.dateObject.getFullYear();
+ return new Date( year, 1, 29 ).getMonth() == 1;
+ },
+
+ weekdays: function() {
+ var date,
+ firstDay = this.firstDay,
+ result = [];
+
+ // date = firstDay
+ date = new Date( this.dateObject.getTime() );
+ date.setDate( date.getDate() + firstDay - 1 - date.getDay() );
+
+ for ( var dow = 0; dow < 7; dow++ ) {
+ date.setTime( date.getTime() + 86400000 );
+ result.push({
+ shortname: this.attributes.formatWeekdayShort( date ),
+ fullname: this.attributes.formatWeekdayFull( date )
+ });
+ }
+
+ return result;
+ },
+
+ days: function() {
+ var result = [],
+ today = new _Date( new Date(), this.attributes ),
+ date = this.dateObject,
+ firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(),
+ leadDays = ( firstDayOfMonth - this.firstDay + 7 ) % 7,
+ rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ),
+ printDate = new Date( this.year(), date.getMonth(), 1 - leadDays );
+ for ( var row = 0; row < rows; row++ ) {
+ var week = result[ result.length ] = {
+ number: this.attributes.formatWeekOfYear( printDate ),
+ days: []
+ };
+ for ( var dayx = 0; dayx < 7; dayx++ ) {
+ var day = week.days[ week.days.length ] = {
+ lead: printDate.getMonth() !== date.getMonth(),
+ date: printDate.getDate(),
+ month: printDate.getMonth(),
+ year: printDate.getFullYear(),
+ timestamp: printDate.getTime(),
+ today: today.equal( printDate )
+ };
+ day.render = day.selectable = !day.lead;
+ if ( this.eachDay ) {
+ this.eachDay( day );
+ }
+
+ // TODO use adjust("D", 1)?
+ printDate.setDate( printDate.getDate() + 1 );
+ }
+ }
+ return result;
+ },
+
+ // specialized for multi-month template, could be used in general
+ months: function( add ) {
+ var clone,
+ result = [ this ];
+
+ for ( var i = 0; i < add; i++ ) {
+ clone = this.clone();
+ clone.adjust( "M", i + 1 );
+ result.push( clone );
+ }
+ result[ 0 ].first = true;
+ result[ result.length - 1 ].last = true;
+ return result;
+ },
+
+ clone: function() {
+ var date = this.dateObject;
+ return new _Date( new Date( date.getTime() ), this.attributes );
+ },
+
+ // TODO compare year, month, day each for better performance
+ equal: function( other ) {
+ var format = function( date ) {
+ return "" + date.getFullYear() + date.getMonth() + date.getDate();
+ }
+ return format( this.dateObject ) === format( other );
+ },
+
+ date: function() {
+ return this.dateObject;
+ }
+});
+
+return $.ui.calendarDate = _Date;
+
+} ) );
diff --git a/external/globalize/LICENSE b/external/globalize-old/LICENSE
index 9c8b02240..9c8b02240 100644
--- a/external/globalize/LICENSE
+++ b/external/globalize-old/LICENSE
diff --git a/external/globalize/globalize.culture.de-DE.js b/external/globalize-old/globalize.culture.de-DE.js
index 5466bd75e..5466bd75e 100644
--- a/external/globalize/globalize.culture.de-DE.js
+++ b/external/globalize-old/globalize.culture.de-DE.js
diff --git a/external/globalize/globalize.culture.ja-JP.js b/external/globalize-old/globalize.culture.ja-JP.js
index a9469d709..a9469d709 100644
--- a/external/globalize/globalize.culture.ja-JP.js
+++ b/external/globalize-old/globalize.culture.ja-JP.js
diff --git a/external/globalize-old/globalize.js b/external/globalize-old/globalize.js
new file mode 100644
index 000000000..a38a32625
--- /dev/null
+++ b/external/globalize-old/globalize.js
@@ -0,0 +1,1585 @@
+/*!
+ * 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() {
+ 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 ) {
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+ return Math[ value < 0 ? "ceil" : "floor" ]( value );
+};
+
+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,
+ ret;
+
+ if ( !format || !format.length || format === "i" ) {
+ 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();
+ default:
+ throw "Invalid part value " + part;
+ }
+ }
+
+ 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 + "\'.";
+ }
+ }
+ 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 ] : "";
+
+ 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, true );
+ 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;
+ /* falls through */
+ case "C":
+ formatInfo = formatInfo || nf.currency;
+ /* falls 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.
+ if ( year < 100 ) {
+ var now = new Date(),
+ era = getEra( now ),
+ curr = getEraYear( now, cal, era ),
+ twoDigitYearMax = cal.twoDigitYearMax;
+ twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
+ 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 = "(\\/)";
+ break;
+ default:
+ throw "Invalid date format pattern \'" + m + "\'.";
+ }
+ 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;
+ /* falls 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 += " ";
+ /* falls 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.findClosestCulture( 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 ) {
+ if ( a.pri < b.pri ) {
+ return 1;
+ } else if ( a.pri > b.pri ) {
+ return -1;
+ }
+ return 0;
+ });
+ // 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 ) {
+ var 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["."] );
+ }
+
+ //Remove percentage character from number string before parsing
+ if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){
+ value = value.replace( culture.numberFormat.percent.symbol, "" );
+ }
+
+ // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR
+ value = value.replace( / /g, "" );
+
+ // 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.cultures[ "default" ];
+};
+
+}( this )); \ No newline at end of file
diff --git a/external/globalize/LICENSE.txt b/external/globalize/LICENSE.txt
new file mode 100644
index 000000000..0f9f2e51c
--- /dev/null
+++ b/external/globalize/LICENSE.txt
@@ -0,0 +1,43 @@
+Copyright jQuery Foundation and other contributors, https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/jquery/globalize
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code contained within the doc directory.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+All files located in the node_modules and external directories are
+externally maintained libraries used by this software which have their
+own licenses; we recommend you read them, as their terms may differ from
+the terms above.
diff --git a/external/globalize/globalize.js b/external/globalize/globalize.js
index a38a32625..2f744ac64 100644
--- a/external/globalize/globalize.js
+++ b/external/globalize/globalize.js
@@ -1,1585 +1,355 @@
-/*!
- * Globalize
+/**
+ * Globalize v1.0.0
*
* http://github.com/jquery/globalize
*
- * Copyright Software Freedom Conservancy, Inc.
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
* http://jquery.org/license
+ *
+ * Date: 2015-04-23T12:02Z
*/
+/*!
+ * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
-(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;
-}
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
-Globalize.cultures = {};
+ // AMD
+ define([
+ "cldr",
+ "cldr/event"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
-Globalize.prototype = {
- constructor: Globalize,
- init: function( cultureSelector ) {
- this.cultures = Globalize.cultures;
- this.cultureSelector = cultureSelector;
+ // Node, CommonJS
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
- return this;
+ // Global
+ root.Globalize = factory( root.Cldr );
}
-};
-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: {}
-};
+}( this, function( Cldr ) {
-Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard;
-Globalize.cultures.en = Globalize.cultures[ "default" ];
+/**
+ * A toString method that outputs meaningful values for objects or arrays and
+ * still performs as fast as a plain string in case variable is string, or as
+ * fast as `"" + number` in case variable is a number.
+ * Ref: http://jsperf.com/my-stringify
+ */
+var toString = function( variable ) {
+ return typeof variable === "string" ? variable : ( typeof variable === "number" ? "" +
+ variable : JSON.stringify( variable ) );
+};
-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
-//
+/**
+ * formatMessage( message, data )
+ *
+ * @message [String] A message with optional {vars} to be replaced.
+ *
+ * @data [Array or JSON] Object with replacing-variables content.
+ *
+ * Return the formatted message. For example:
+ *
+ * - formatMessage( "{0} second", [ 1 ] ); // 1 second
+ *
+ * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s
+ *
+ * - formatMessage( "{name} <{email}>", {
+ * name: "Foo",
+ * email: "bar@baz.qux"
+ * }); // Foo <bar@baz.qux>
+ */
+var formatMessage = function( message, data ) {
-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;
-};
+ // Replace {attribute}'s
+ message = message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( name ) {
+ name = name.replace( /^{([^}]*)}$/, "$1" );
+ return toString( data[ name ] );
+ });
-endsWith = function( value, pattern ) {
- return value.substr( value.length - pattern.length ) === pattern;
+ return message;
};
-extend = function() {
- 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;
- }
- }
+
+var objectExtend = function() {
+ var destination = arguments[ 0 ],
+ sources = [].slice.call( arguments, 1 );
+
+ sources.forEach(function( source ) {
+ var prop;
+ for ( prop in source ) {
+ destination[ prop ] = source[ prop ];
}
- }
+ });
- // Return the modified object
- return target;
+ return destination;
};
-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;
-};
+var createError = function( code, message, attributes ) {
+ var error;
-trim = function( value ) {
- return ( value + "" ).replace( regexTrim, "" );
-};
+ message = code + ( message ? ": " + formatMessage( message, attributes ) : "" );
+ error = new Error( message );
+ error.code = code;
-truncate = function( value ) {
- if ( isNaN( value ) ) {
- return NaN;
- }
- return Math[ value < 0 ? "ceil" : "floor" ]( value );
-};
+ objectExtend( error, attributes );
-zeroPad = function( str, count, left ) {
- var l;
- for ( l = str.length; l < count; l += 1 ) {
- str = ( left ? ("0" + str) : (str + "0") );
- }
- return str;
+ return error;
};
-//
-// 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,
- ret;
-
- if ( !format || !format.length || format === "i" ) {
- 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;
+var validate = function( code, message, check, attributes ) {
+ if ( !check ) {
+ throw createError( code, message, attributes );
}
+};
- 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();
- default:
- throw "Invalid part value " + part;
- }
- }
- 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 );
+var alwaysArray = function( stringOrArray ) {
+ return Array.isArray( stringOrArray ) ? stringOrArray : stringOrArray ? [ stringOrArray ] : [];
+};
- // 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 + "\'.";
- }
- }
- return ret.join( "" );
-};
+var validateCldr = function( path, value, options ) {
+ var skipBoolean;
+ options = options || {};
-// formatNumber
-(function() {
- var expandNumber;
+ skipBoolean = alwaysArray( options.skip ).some(function( pathRe ) {
+ return pathRe.test( path );
+ });
- 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;
+ validate( "E_MISSING_CLDR", "Missing required CLDR content `{path}`.", value || skipBoolean, {
+ path: path
+ });
+};
- 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 ] : "";
-
- 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, true );
- 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) : "" );
+var validateDefaultLocale = function( value ) {
+ validate( "E_DEFAULT_LOCALE_NOT_DEFINED", "Default locale has not been defined.",
+ value !== undefined, {} );
+};
- 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;
- /* falls through */
- case "C":
- formatInfo = formatInfo || nf.currency;
- /* falls 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;
- }
- }
+var validateParameterPresence = function( value, name ) {
+ validate( "E_MISSING_PARAMETER", "Missing required parameter `{name}`.",
+ value !== undefined, { name: name });
+};
- 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;
+/**
+ * range( value, name, minimum, maximum )
+ *
+ * @value [Number].
+ *
+ * @name [String] name of variable.
+ *
+ * @minimum [Number]. The lowest valid value, inclusive.
+ *
+ * @maximum [Number]. The greatest valid value, inclusive.
+ */
+var validateParameterRange = function( value, name, minimum, maximum ) {
+ validate(
+ "E_PAR_OUT_OF_RANGE",
+ "Parameter `{name}` has value `{value}` out of range [{minimum}, {maximum}].",
+ value === undefined || value >= minimum && value <= maximum,
+ {
+ maximum: maximum,
+ minimum: minimum,
+ name: name,
+ value: value
}
- }
- 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.
- if ( year < 100 ) {
- var now = new Date(),
- era = getEra( now ),
- curr = getEraYear( now, cal, era ),
- twoDigitYearMax = cal.twoDigitYearMax;
- twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
- 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 = "(\\/)";
- break;
- default:
- throw "Invalid date format pattern \'" + m + "\'.";
- }
- 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 );
+
+var validateParameterType = function( value, name, check, expected ) {
+ validate(
+ "E_INVALID_PAR_TYPE",
+ "Invalid `{name}` parameter ({value}). {expected} expected.",
+ check,
+ {
+ expected: expected,
+ name: name,
+ value: value
}
- return result;
- };
-}());
-
-parseNegativePattern = function( value, nf, negativePattern ) {
- var neg = nf[ "-" ],
- pos = nf[ "+" ],
- ret;
- switch ( negativePattern ) {
- case "n -":
- neg = " " + neg;
- pos = " " + pos;
- /* falls 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 += " ";
- /* falls 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 );
+var validateParameterTypeLocale = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "string" || value instanceof Cldr,
+ "String or Cldr instance"
+ );
};
-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 );
+
+/**
+ * Function inspired by jQuery Core, but reduced to our use case.
+ */
+var isPlainObject = function( obj ) {
+ return obj !== null && "" + obj === "[object Object]";
};
-//
-// 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
+
+
+var validateParameterTypePlainObject = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || isPlainObject( value ),
+ "Plain Object"
);
- // 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.findClosestCulture( 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 ) {
- if ( a.pri < b.pri ) {
- return 1;
- } else if ( a.pri > b.pri ) {
- return -1;
- }
- return 0;
- });
- // 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 ) {
- var 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;
+var alwaysCldr = function( localeOrCldr ) {
+ return localeOrCldr instanceof Cldr ? localeOrCldr : new Cldr( localeOrCldr );
};
-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;
+// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
+var regexpEscape = function( string ) {
+ return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" );
};
-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["."] );
+var stringPad = function( str, count, right ) {
+ var length;
+ if ( typeof str !== "string" ) {
+ str = String( str );
}
-
- //Remove percentage character from number string before parsing
- if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){
- value = value.replace( culture.numberFormat.percent.symbol, "" );
+ for ( length = str.length; length < count; length += 1 ) {
+ str = ( right ? ( str + "0" ) : ( "0" + str ) );
}
+ return str;
+};
- // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR
- value = value.replace( / /g, "" );
- // 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 || "+";
+function validateLikelySubtags( cldr ) {
+ cldr.once( "get", validateCldr );
+ cldr.get( "supplemental/likelySubtags" );
+}
- // 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 );
- }
+/**
+ * [new] Globalize( locale|cldr )
+ *
+ * @locale [String]
+ *
+ * @cldr [Cldr instance]
+ *
+ * Create a Globalize instance.
+ */
+function Globalize( locale ) {
+ if ( !( this instanceof Globalize ) ) {
+ return new Globalize( locale );
}
- return ret;
+
+ validateParameterPresence( locale, "locale" );
+ validateParameterTypeLocale( locale, "locale" );
+
+ this.cldr = alwaysCldr( locale );
+
+ validateLikelySubtags( this.cldr );
+}
+
+/**
+ * Globalize.load( json, ... )
+ *
+ * @json [JSON]
+ *
+ * Load resolved or unresolved cldr data.
+ * Somewhat equivalent to previous Globalize.addCultureInfo(...).
+ */
+Globalize.load = function() {
+ // validations are delegated to Cldr.load().
+ Cldr.load.apply( Cldr, arguments );
};
-Globalize.culture = function( cultureSelector ) {
- // setter
- if ( typeof cultureSelector !== "undefined" ) {
- this.cultureSelector = cultureSelector;
+/**
+ * Globalize.locale( [locale|cldr] )
+ *
+ * @locale [String]
+ *
+ * @cldr [Cldr instance]
+ *
+ * Set default Cldr instance if locale or cldr argument is passed.
+ *
+ * Return the default Cldr instance.
+ */
+Globalize.locale = function( locale ) {
+ validateParameterTypeLocale( locale, "locale" );
+
+ if ( arguments.length ) {
+ this.cldr = alwaysCldr( locale );
+ validateLikelySubtags( this.cldr );
}
- // getter
- return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ];
+ return this.cldr;
};
-}( this )); \ No newline at end of file
+/**
+ * Optimization to avoid duplicating some internal functions across modules.
+ */
+Globalize._alwaysArray = alwaysArray;
+Globalize._createError = createError;
+Globalize._formatMessage = formatMessage;
+Globalize._isPlainObject = isPlainObject;
+Globalize._objectExtend = objectExtend;
+Globalize._regexpEscape = regexpEscape;
+Globalize._stringPad = stringPad;
+Globalize._validate = validate;
+Globalize._validateCldr = validateCldr;
+Globalize._validateDefaultLocale = validateDefaultLocale;
+Globalize._validateParameterPresence = validateParameterPresence;
+Globalize._validateParameterRange = validateParameterRange;
+Globalize._validateParameterTypePlainObject = validateParameterTypePlainObject;
+Globalize._validateParameterType = validateParameterType;
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/globalize/globalize/date.js b/external/globalize/globalize/date.js
new file mode 100644
index 000000000..9f26a105d
--- /dev/null
+++ b/external/globalize/globalize/date.js
@@ -0,0 +1,1845 @@
+/**
+ * Globalize v1.0.0
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-04-23T12:02Z
+ */
+/*!
+ * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define([
+ "cldr",
+ "../globalize",
+ "./number",
+ "cldr/event",
+ "cldr/supplemental"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory( require( "cldrjs" ), require( "globalize" ) );
+ } else {
+
+ // Extend global
+ factory( root.Cldr, root.Globalize );
+ }
+}(this, function( Cldr, Globalize ) {
+
+var createError = Globalize._createError,
+ createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature,
+ formatMessage = Globalize._formatMessage,
+ numberSymbol = Globalize._numberSymbol,
+ regexpEscape = Globalize._regexpEscape,
+ stringPad = Globalize._stringPad,
+ validateCldr = Globalize._validateCldr,
+ validateDefaultLocale = Globalize._validateDefaultLocale,
+ validateParameterPresence = Globalize._validateParameterPresence,
+ validateParameterType = Globalize._validateParameterType,
+ validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject,
+ validateParameterTypeString = Globalize._validateParameterTypeString;
+
+
+var validateParameterTypeDate = function( value, name ) {
+ validateParameterType( value, name, value === undefined || value instanceof Date, "Date" );
+};
+
+
+
+
+var createErrorInvalidParameterValue = function( name, value ) {
+ return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", {
+ name: name,
+ value: value
+ });
+};
+
+
+
+
+/**
+ * expandPattern( options, cldr )
+ *
+ * @options [Object] if String, it's considered a skeleton. Object accepts:
+ * - skeleton: [String] lookup availableFormat;
+ * - date: [String] ( "full" | "long" | "medium" | "short" );
+ * - time: [String] ( "full" | "long" | "medium" | "short" );
+ * - datetime: [String] ( "full" | "long" | "medium" | "short" );
+ * - raw: [String] For more info see datetime/format.js.
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return the corresponding pattern.
+ * Eg for "en":
+ * - "GyMMMd" returns "MMM d, y G";
+ * - { skeleton: "GyMMMd" } returns "MMM d, y G";
+ * - { date: "full" } returns "EEEE, MMMM d, y";
+ * - { time: "full" } returns "h:mm:ss a zzzz";
+ * - { datetime: "full" } returns "EEEE, MMMM d, y 'at' h:mm:ss a zzzz";
+ * - { raw: "dd/mm" } returns "dd/mm";
+ */
+
+var dateExpandPattern = function( options, cldr ) {
+ var dateSkeleton, result, skeleton, timeSkeleton, type;
+
+ function combineDateTime( type, datePattern, timePattern ) {
+ return formatMessage(
+ cldr.main([
+ "dates/calendars/gregorian/dateTimeFormats",
+ type
+ ]),
+ [ timePattern, datePattern ]
+ );
+ }
+
+ switch ( true ) {
+ case "skeleton" in options:
+ skeleton = options.skeleton;
+ result = cldr.main([
+ "dates/calendars/gregorian/dateTimeFormats/availableFormats",
+ skeleton
+ ]);
+ if ( !result ) {
+ timeSkeleton = skeleton.split( /[^hHKkmsSAzZOvVXx]/ ).slice( -1 )[ 0 ];
+ dateSkeleton = skeleton.split( /[^GyYuUrQqMLlwWdDFgEec]/ )[ 0 ];
+ if ( /(MMMM|LLLL).*[Ec]/.test( dateSkeleton ) ) {
+ type = "full";
+ } else if ( /MMMM/g.test( dateSkeleton ) ) {
+ type = "long";
+ } else if ( /MMM/g.test( dateSkeleton ) || /LLL/g.test( dateSkeleton ) ) {
+ type = "medium";
+ } else {
+ type = "short";
+ }
+ result = combineDateTime( type,
+ cldr.main([
+ "dates/calendars/gregorian/dateTimeFormats/availableFormats",
+ dateSkeleton
+ ]),
+ cldr.main([
+ "dates/calendars/gregorian/dateTimeFormats/availableFormats",
+ timeSkeleton
+ ])
+ );
+ }
+ break;
+
+ case "date" in options:
+ case "time" in options:
+ result = cldr.main([
+ "dates/calendars/gregorian",
+ "date" in options ? "dateFormats" : "timeFormats",
+ ( options.date || options.time )
+ ]);
+ break;
+
+ case "datetime" in options:
+ result = combineDateTime( options.datetime,
+ cldr.main([ "dates/calendars/gregorian/dateFormats", options.datetime ]),
+ cldr.main([ "dates/calendars/gregorian/timeFormats", options.datetime ])
+ );
+ break;
+
+ case "raw" in options:
+ result = options.raw;
+ break;
+
+ default:
+ throw createErrorInvalidParameterValue({
+ name: "options",
+ value: options
+ });
+ }
+
+ return result;
+};
+
+
+
+
+/**
+ * dayOfWeek( date, firstDay )
+ *
+ * @date
+ *
+ * @firstDay the result of `dateFirstDayOfWeek( cldr )`
+ *
+ * Return the day of the week normalized by the territory's firstDay [0-6].
+ * Eg for "mon":
+ * - return 0 if territory is GB, or BR, or DE, or FR (week starts on "mon");
+ * - return 1 if territory is US (week starts on "sun");
+ * - return 2 if territory is EG (week starts on "sat");
+ */
+var dateDayOfWeek = function( date, firstDay ) {
+ return ( date.getDay() - firstDay + 7 ) % 7;
+};
+
+
+
+
+/**
+ * distanceInDays( from, to )
+ *
+ * Return the distance in days between from and to Dates.
+ */
+var dateDistanceInDays = function( from, to ) {
+ var inDays = 864e5;
+ return ( to.getTime() - from.getTime() ) / inDays;
+};
+
+
+
+
+/**
+ * startOf changes the input to the beginning of the given unit.
+ *
+ * For example, starting at the start of a day, resets hours, minutes
+ * seconds and milliseconds to 0. Starting at the month does the same, but
+ * also sets the date to 1.
+ *
+ * Returns the modified date
+ */
+var dateStartOf = function( date, unit ) {
+ date = new Date( date.getTime() );
+ switch ( unit ) {
+ case "year":
+ date.setMonth( 0 );
+ /* falls through */
+ case "month":
+ date.setDate( 1 );
+ /* falls through */
+ case "day":
+ date.setHours( 0 );
+ /* falls through */
+ case "hour":
+ date.setMinutes( 0 );
+ /* falls through */
+ case "minute":
+ date.setSeconds( 0 );
+ /* falls through */
+ case "second":
+ date.setMilliseconds( 0 );
+ }
+ return date;
+};
+
+
+
+
+/**
+ * dayOfYear
+ *
+ * Return the distance in days of the date to the begin of the year [0-d].
+ */
+var dateDayOfYear = function( date ) {
+ return Math.floor( dateDistanceInDays( dateStartOf( date, "year" ), date ) );
+};
+
+
+
+
+var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ];
+
+
+
+
+/**
+ * firstDayOfWeek
+ */
+var dateFirstDayOfWeek = function( cldr ) {
+ return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() );
+};
+
+
+
+
+/**
+ * millisecondsInDay
+ */
+var dateMillisecondsInDay = function( date ) {
+ // TODO Handle daylight savings discontinuities
+ return date - dateStartOf( date, "day" );
+};
+
+
+
+
+var datePatternRe = (/([a-z])\1*|'([^']|'')+'|''|./ig);
+
+
+
+
+/**
+ * hourFormat( date, format, timeSeparator, formatNumber )
+ *
+ * Return date's timezone offset according to the format passed.
+ * Eg for format when timezone offset is 180:
+ * - "+H;-H": -3
+ * - "+HHmm;-HHmm": -0300
+ * - "+HH:mm;-HH:mm": -03:00
+ */
+var dateTimezoneHourFormat = function( date, format, timeSeparator, formatNumber ) {
+ var absOffset,
+ offset = date.getTimezoneOffset();
+
+ absOffset = Math.abs( offset );
+ formatNumber = formatNumber || {
+ 1: function( value ) {
+ return stringPad( value, 1 );
+ },
+ 2: function( value ) {
+ return stringPad( value, 2 );
+ }
+ };
+
+ return format
+
+ // Pick the correct sign side (+ or -).
+ .split( ";" )[ offset > 0 ? 1 : 0 ]
+
+ // Localize time separator
+ .replace( ":", timeSeparator )
+
+ // Update hours offset.
+ .replace( /HH?/, function( match ) {
+ return formatNumber[ match.length ]( Math.floor( absOffset / 60 ) );
+ })
+
+ // Update minutes offset and return.
+ .replace( /mm/, function() {
+ return formatNumber[ 2 ]( absOffset % 60 );
+ });
+};
+
+
+
+
+/**
+ * format( date, properties )
+ *
+ * @date [Date instance].
+ *
+ * @properties
+ *
+ * TODO Support other calendar types.
+ *
+ * Disclosure: this function borrows excerpts of dojo/date/locale.
+ */
+var dateFormat = function( date, numberFormatters, properties ) {
+ var timeSeparator = properties.timeSeparator;
+
+ return properties.pattern.replace( datePatternRe, function( current ) {
+ var ret,
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "j" ) {
+ // Locale preferred hHKk.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ chr = properties.preferredTime;
+ }
+
+ if ( chr === "Z" ) {
+ // Z..ZZZ: same as "xxxx".
+ if ( length < 4 ) {
+ chr = "x";
+ length = 4;
+
+ // ZZZZ: same as "OOOO".
+ } else if ( length < 5 ) {
+ chr = "O";
+ length = 4;
+
+ // ZZZZZ: same as "XXXXX"
+ } else {
+ chr = "X";
+ length = 5;
+ }
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ ret = properties.eras[ date.getFullYear() < 0 ? 0 : 1 ];
+ break;
+
+ // Year
+ case "y":
+ // Plain year.
+ // The length specifies the padding, but for two letters it also specifies the
+ // maximum length.
+ ret = date.getFullYear();
+ if ( length === 2 ) {
+ ret = String( ret );
+ ret = +ret.substr( ret.length - 2 );
+ }
+ break;
+
+ case "Y":
+ // Year in "Week of Year"
+ // The length specifies the padding, but for two letters it also specifies the
+ // maximum length.
+ // yearInWeekofYear = date + DaysInAWeek - (dayOfWeek - firstDay) - minDays
+ ret = new Date( date.getTime() );
+ ret.setDate(
+ ret.getDate() + 7 -
+ dateDayOfWeek( date, properties.firstDay ) -
+ properties.firstDay -
+ properties.minDays
+ );
+ ret = ret.getFullYear();
+ if ( length === 2 ) {
+ ret = String( ret );
+ ret = +ret.substr( ret.length - 2 );
+ }
+ break;
+
+ // Quarter
+ case "Q":
+ case "q":
+ ret = Math.ceil( ( date.getMonth() + 1 ) / 3 );
+ if ( length > 2 ) {
+ ret = properties.quarters[ chr ][ length ][ ret ];
+ }
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ ret = date.getMonth() + 1;
+ if ( length > 2 ) {
+ ret = properties.months[ chr ][ length ][ ret ];
+ }
+ break;
+
+ // Week
+ case "w":
+ // Week of Year.
+ // woy = ceil( ( doy + dow of 1/1 ) / 7 ) - minDaysStuff ? 1 : 0.
+ // TODO should pad on ww? Not documented, but I guess so.
+ ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay );
+ ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) -
+ ( 7 - ret >= properties.minDays ? 0 : 1 );
+ break;
+
+ case "W":
+ // Week of Month.
+ // wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0.
+ ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay );
+ ret = Math.ceil( ( date.getDate() + ret ) / 7 ) -
+ ( 7 - ret >= properties.minDays ? 0 : 1 );
+ break;
+
+ // Day
+ case "d":
+ ret = date.getDate();
+ break;
+
+ case "D":
+ ret = dateDayOfYear( date ) + 1;
+ break;
+
+ case "F":
+ // Day of Week in month. eg. 2nd Wed in July.
+ ret = Math.floor( date.getDate() / 7 ) + 1;
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+ if ( length <= 2 ) {
+ // Range is [1-7] (deduced by example provided on documentation)
+ // TODO Should pad with zeros (not specified in the docs)?
+ ret = dateDayOfWeek( date, properties.firstDay ) + 1;
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ ret = dateWeekDays[ date.getDay() ];
+ ret = properties.days[ chr ][ length ][ ret ];
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ ret = properties.dayPeriods[ date.getHours() < 12 ? "am" : "pm" ];
+ break;
+
+ // Hour
+ case "h": // 1-12
+ ret = ( date.getHours() % 12 ) || 12;
+ break;
+
+ case "H": // 0-23
+ ret = date.getHours();
+ break;
+
+ case "K": // 0-11
+ ret = date.getHours() % 12;
+ break;
+
+ case "k": // 1-24
+ ret = date.getHours() || 24;
+ break;
+
+ // Minute
+ case "m":
+ ret = date.getMinutes();
+ break;
+
+ // Second
+ case "s":
+ ret = date.getSeconds();
+ break;
+
+ case "S":
+ ret = Math.round( date.getMilliseconds() * Math.pow( 10, length - 3 ) );
+ break;
+
+ case "A":
+ ret = Math.round( dateMillisecondsInDay( date ) * Math.pow( 10, length - 3 ) );
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+ // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT".
+ // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT".
+ if ( date.getTimezoneOffset() === 0 ) {
+ ret = properties.gmtZeroFormat;
+ } else {
+ ret = dateTimezoneHourFormat(
+ date,
+ length < 4 ? "+H;-H" : properties.tzLongHourFormat,
+ timeSeparator,
+ numberFormatters
+ );
+ ret = properties.gmtFormat.replace( /\{0\}/, ret );
+ }
+ break;
+
+ case "X":
+ // Same as x*, except it uses "Z" for zero offset.
+ if ( date.getTimezoneOffset() === 0 ) {
+ ret = "Z";
+ break;
+ }
+
+ /* falls through */
+ case "x":
+ // x: hourFormat("+HH;-HH")
+ // xx or xxxx: hourFormat("+HHmm;-HHmm")
+ // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm")
+ ret = length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" );
+ ret = dateTimezoneHourFormat( date, ret, ":" );
+ break;
+
+ // timeSeparator
+ case ":":
+ ret = timeSeparator;
+ break;
+
+ // ' literals.
+ case "'":
+ current = current.replace( /''/, "'" );
+ if ( length > 2 ) {
+ current = current.slice( 1, -1 );
+ }
+ ret = current;
+ break;
+
+ // Anything else is considered a literal, including [ ,:/.@#], chinese, japonese, and
+ // arabic characters.
+ default:
+ ret = current;
+ }
+ if ( typeof ret === "number" ) {
+ ret = numberFormatters[ length ]( ret );
+ }
+ return ret;
+ });
+};
+
+
+
+
+/**
+ * properties( pattern, cldr )
+ *
+ * @pattern [String] raw pattern.
+ * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return the properties given the pattern and cldr.
+ *
+ * TODO Support other calendar types.
+ */
+var dateFormatProperties = function( pattern, cldr ) {
+ var properties = {
+ pattern: pattern,
+ timeSeparator: numberSymbol( "timeSeparator", cldr )
+ },
+ widths = [ "abbreviated", "wide", "narrow" ];
+
+ function setNumberFormatterPattern( pad ) {
+ if ( !properties.numberFormatters ) {
+ properties.numberFormatters = {};
+ }
+ properties.numberFormatters[ pad ] = stringPad( "", pad );
+ }
+
+ pattern.replace( datePatternRe, function( current ) {
+ var formatNumber,
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "j" ) {
+ // Locale preferred hHKk.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ properties.preferredTime = chr = cldr.supplemental.timeData.preferred();
+ }
+
+ // ZZZZ: same as "OOOO".
+ if ( chr === "Z" && length === 4 ) {
+ chr = "O";
+ length = 4;
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ properties.eras = cldr.main([
+ "dates/calendars/gregorian/eras",
+ length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
+ ]);
+ break;
+
+ // Year
+ case "y":
+ // Plain year.
+ formatNumber = true;
+ break;
+
+ case "Y":
+ // Year in "Week of Year"
+ properties.firstDay = dateFirstDayOfWeek( cldr );
+ properties.minDays = cldr.supplemental.weekData.minDays();
+ formatNumber = true;
+ break;
+
+ case "u": // Extended year. Need to be implemented.
+ case "U": // Cyclic year name. Need to be implemented.
+ throw createErrorUnsupportedFeature({
+ feature: "year pattern `" + chr + "`"
+ });
+
+ // Quarter
+ case "Q":
+ case "q":
+ if ( length > 2 ) {
+ if ( !properties.quarters ) {
+ properties.quarters = {};
+ }
+ if ( !properties.quarters[ chr ] ) {
+ properties.quarters[ chr ] = {};
+ }
+ properties.quarters[ chr ][ length ] = cldr.main([
+ "dates/calendars/gregorian/quarters",
+ chr === "Q" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ } else {
+ formatNumber = true;
+ }
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ if ( length > 2 ) {
+ if ( !properties.months ) {
+ properties.months = {};
+ }
+ if ( !properties.months[ chr ] ) {
+ properties.months[ chr ] = {};
+ }
+ properties.months[ chr ][ length ] = cldr.main([
+ "dates/calendars/gregorian/months",
+ chr === "M" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ } else {
+ formatNumber = true;
+ }
+ break;
+
+ // Week - Week of Year (w) or Week of Month (W).
+ case "w":
+ case "W":
+ properties.firstDay = dateFirstDayOfWeek( cldr );
+ properties.minDays = cldr.supplemental.weekData.minDays();
+ formatNumber = true;
+ break;
+
+ // Day
+ case "d":
+ case "D":
+ case "F":
+ formatNumber = true;
+ break;
+
+ case "g":
+ // Modified Julian day. Need to be implemented.
+ throw createErrorUnsupportedFeature({
+ feature: "Julian day pattern `g`"
+ });
+
+ // Week day
+ case "e":
+ case "c":
+ if ( length <= 2 ) {
+ properties.firstDay = dateFirstDayOfWeek( cldr );
+ formatNumber = true;
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ if ( !properties.days ) {
+ properties.days = {};
+ }
+ if ( !properties.days[ chr ] ) {
+ properties.days[ chr ] = {};
+ }
+ if ( length === 6 ) {
+
+ // If short day names are not explicitly specified, abbreviated day names are
+ // used instead.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
+ // http://unicode.org/cldr/trac/ticket/6790
+ properties.days[ chr ][ length ] = cldr.main([
+ "dates/calendars/gregorian/days",
+ chr === "c" ? "stand-alone" : "format",
+ "short"
+ ]) || cldr.main([
+ "dates/calendars/gregorian/days",
+ chr === "c" ? "stand-alone" : "format",
+ "abbreviated"
+ ]);
+ } else {
+ properties.days[ chr ][ length ] = cldr.main([
+ "dates/calendars/gregorian/days",
+ chr === "c" ? "stand-alone" : "format",
+ widths[ length < 3 ? 0 : length - 3 ]
+ ]);
+ }
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ properties.dayPeriods = cldr.main(
+ "dates/calendars/gregorian/dayPeriods/format/wide"
+ );
+ break;
+
+ // Hour
+ case "h": // 1-12
+ case "H": // 0-23
+ case "K": // 0-11
+ case "k": // 1-24
+
+ // Minute
+ case "m":
+
+ // Second
+ case "s":
+ case "S":
+ case "A":
+ formatNumber = true;
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+ // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT".
+ // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT".
+ properties.gmtFormat = cldr.main( "dates/timeZoneNames/gmtFormat" );
+ properties.gmtZeroFormat = cldr.main( "dates/timeZoneNames/gmtZeroFormat" );
+ properties.tzLongHourFormat = cldr.main( "dates/timeZoneNames/hourFormat" );
+
+ /* falls through */
+ case "Z":
+ case "X":
+ case "x":
+ setNumberFormatterPattern( 1 );
+ setNumberFormatterPattern( 2 );
+ break;
+
+ case "v":
+ case "V":
+ throw createErrorUnsupportedFeature({
+ feature: "timezone pattern `" + chr + "`"
+ });
+ }
+
+ if ( formatNumber ) {
+ setNumberFormatterPattern( length );
+ }
+ });
+
+ return properties;
+};
+
+
+
+
+/**
+ * isLeapYear( year )
+ *
+ * @year [Number]
+ *
+ * Returns an indication whether the specified year is a leap year.
+ */
+var dateIsLeapYear = function( year ) {
+ return new Date(year, 1, 29).getMonth() === 1;
+};
+
+
+
+
+/**
+ * lastDayOfMonth( date )
+ *
+ * @date [Date]
+ *
+ * Return the last day of the given date's month
+ */
+var dateLastDayOfMonth = function( date ) {
+ return new Date( date.getFullYear(), date.getMonth() + 1, 0).getDate();
+};
+
+
+
+
+/**
+ * Differently from native date.setDate(), this function returns a date whose
+ * day remains inside the month boundaries. For example:
+ *
+ * setDate( FebDate, 31 ): a "Feb 28" date.
+ * setDate( SepDate, 31 ): a "Sep 30" date.
+ */
+var dateSetDate = function( date, day ) {
+ var lastDay = new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate();
+
+ date.setDate( day < 1 ? 1 : day < lastDay ? day : lastDay );
+};
+
+
+
+
+/**
+ * Differently from native date.setMonth(), this function adjusts date if
+ * needed, so final month is always the one set.
+ *
+ * setMonth( Jan31Date, 1 ): a "Feb 28" date.
+ * setDate( Jan31Date, 8 ): a "Sep 30" date.
+ */
+var dateSetMonth = function( date, month ) {
+ var originalDate = date.getDate();
+
+ date.setDate( 1 );
+ date.setMonth( month );
+ dateSetDate( date, originalDate );
+};
+
+
+
+
+var outOfRange = function( value, low, high ) {
+ return value < low || value > high;
+};
+
+
+
+
+/**
+ * parse( value, tokens, properties )
+ *
+ * @value [String] string date.
+ *
+ * @tokens [Object] tokens returned by date/tokenizer.
+ *
+ * @properties [Object] output returned by date/tokenizer-properties.
+ *
+ * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
+ */
+var dateParse = function( value, tokens, properties ) {
+ var amPm, day, daysOfYear, era, hour, hour12, timezoneOffset, valid,
+ YEAR = 0,
+ MONTH = 1,
+ DAY = 2,
+ HOUR = 3,
+ MINUTE = 4,
+ SECOND = 5,
+ MILLISECONDS = 6,
+ date = new Date(),
+ truncateAt = [],
+ units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ];
+
+ if ( !tokens.length ) {
+ return null;
+ }
+
+ valid = tokens.every(function( token ) {
+ var century, chr, value, length;
+
+ if ( token.type === "literal" ) {
+ // continue
+ return true;
+ }
+
+ chr = token.type.charAt( 0 );
+ length = token.type.length;
+
+ if ( chr === "j" ) {
+ // Locale preferred hHKk.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ chr = properties.preferredTimeData;
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ truncateAt.push( YEAR );
+ era = +token.value;
+ break;
+
+ // Year
+ case "y":
+ value = token.value;
+ if ( length === 2 ) {
+ if ( outOfRange( value, 0, 99 ) ) {
+ return false;
+ }
+ // mimic dojo/date/locale: choose century to apply, according to a sliding
+ // window of 80 years before and 20 years after present year.
+ century = Math.floor( date.getFullYear() / 100 ) * 100;
+ value += century;
+ if ( value > date.getFullYear() + 20 ) {
+ value -= 100;
+ }
+ }
+ date.setFullYear( value );
+ truncateAt.push( YEAR );
+ break;
+
+ case "Y": // Year in "Week of Year"
+ throw createErrorUnsupportedFeature({
+ feature: "year pattern `" + chr + "`"
+ });
+
+ // Quarter (skip)
+ case "Q":
+ case "q":
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ if ( length <= 2 ) {
+ value = token.value;
+ } else {
+ value = +token.value;
+ }
+ if ( outOfRange( value, 1, 12 ) ) {
+ return false;
+ }
+ dateSetMonth( date, value - 1 );
+ truncateAt.push( MONTH );
+ break;
+
+ // Week (skip)
+ case "w": // Week of Year.
+ case "W": // Week of Month.
+ break;
+
+ // Day
+ case "d":
+ day = token.value;
+ truncateAt.push( DAY );
+ break;
+
+ case "D":
+ daysOfYear = token.value;
+ truncateAt.push( DAY );
+ break;
+
+ case "F":
+ // Day of Week in month. eg. 2nd Wed in July.
+ // Skip
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+ case "E":
+ // Skip.
+ // value = arrayIndexOf( dateWeekDays, token.value );
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ amPm = token.value;
+ break;
+
+ // Hour
+ case "h": // 1-12
+ value = token.value;
+ if ( outOfRange( value, 1, 12 ) ) {
+ return false;
+ }
+ hour = hour12 = true;
+ date.setHours( value === 12 ? 0 : value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "K": // 0-11
+ value = token.value;
+ if ( outOfRange( value, 0, 11 ) ) {
+ return false;
+ }
+ hour = hour12 = true;
+ date.setHours( value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "k": // 1-24
+ value = token.value;
+ if ( outOfRange( value, 1, 24 ) ) {
+ return false;
+ }
+ hour = true;
+ date.setHours( value === 24 ? 0 : value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "H": // 0-23
+ value = token.value;
+ if ( outOfRange( value, 0, 23 ) ) {
+ return false;
+ }
+ hour = true;
+ date.setHours( value );
+ truncateAt.push( HOUR );
+ break;
+
+ // Minute
+ case "m":
+ value = token.value;
+ if ( outOfRange( value, 0, 59 ) ) {
+ return false;
+ }
+ date.setMinutes( value );
+ truncateAt.push( MINUTE );
+ break;
+
+ // Second
+ case "s":
+ value = token.value;
+ if ( outOfRange( value, 0, 59 ) ) {
+ return false;
+ }
+ date.setSeconds( value );
+ truncateAt.push( SECOND );
+ break;
+
+ case "A":
+ date.setHours( 0 );
+ date.setMinutes( 0 );
+ date.setSeconds( 0 );
+
+ /* falls through */
+ case "S":
+ value = Math.round( token.value * Math.pow( 10, 3 - length ) );
+ date.setMilliseconds( value );
+ truncateAt.push( MILLISECONDS );
+ break;
+
+ // Zone
+ case "Z":
+ case "z":
+ case "O":
+ case "X":
+ case "x":
+ timezoneOffset = token.value - date.getTimezoneOffset();
+ break;
+ }
+
+ return true;
+ });
+
+ if ( !valid ) {
+ return null;
+ }
+
+ // 12-hour format needs AM or PM, 24-hour format doesn't, ie. return null
+ // if amPm && !hour12 || !amPm && hour12.
+ if ( hour && !( !amPm ^ hour12 ) ) {
+ return null;
+ }
+
+ if ( era === 0 ) {
+ // 1 BC = year 0
+ date.setFullYear( date.getFullYear() * -1 + 1 );
+ }
+
+ if ( day !== undefined ) {
+ if ( outOfRange( day, 1, dateLastDayOfMonth( date ) ) ) {
+ return null;
+ }
+ date.setDate( day );
+ } else if ( daysOfYear !== undefined ) {
+ if ( outOfRange( daysOfYear, 1, dateIsLeapYear( date.getFullYear() ) ? 366 : 365 ) ) {
+ return null;
+ }
+ date.setMonth(0);
+ date.setDate( daysOfYear );
+ }
+
+ if ( hour12 && amPm === "pm" ) {
+ date.setHours( date.getHours() + 12 );
+ }
+
+ if ( timezoneOffset ) {
+ date.setMinutes( date.getMinutes() + timezoneOffset );
+ }
+
+ // Truncate date at the most precise unit defined. Eg.
+ // If value is "12/31", and pattern is "MM/dd":
+ // => new Date( <current Year>, 12, 31, 0, 0, 0, 0 );
+ truncateAt = Math.max.apply( null, truncateAt );
+ date = dateStartOf( date, units[ truncateAt ] );
+
+ return date;
+};
+
+
+
+
+/**
+ * parseProperties( cldr )
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return parser properties.
+ */
+var dateParseProperties = function( cldr ) {
+ return {
+ preferredTimeData: cldr.supplemental.timeData.preferred()
+ };
+};
+
+
+
+
+/**
+ * Generated by:
+ *
+ * regenerate().add( require( "unicode-7.0.0/categories/N/symbols" ) ).toString();
+ *
+ * https://github.com/mathiasbynens/regenerate
+ * https://github.com/mathiasbynens/unicode-7.0.0
+ */
+var regexpN = /[0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]|\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD801[\uDCA0-\uDCA9]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDD16-\uDD1B\uDE40-\uDE47\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD803[\uDE60-\uDE7E]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDDE1-\uDDF4\uDEF0-\uDEF9]|\uD805[\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9]|\uD806[\uDCE0-\uDCF2]|\uD809[\uDC00-\uDC6E]|\uD81A[\uDE60-\uDE69\uDF50-\uDF59\uDF5B-\uDF61]|\uD834[\uDF60-\uDF71]|\uD835[\uDFCE-\uDFFF]|\uD83A[\uDCC7-\uDCCF]|\uD83C[\uDD00-\uDD0C]/;
+
+
+
+
+/**
+ * tokenizer( value, pattern, properties )
+ *
+ * @value [String] string date.
+ *
+ * @properties [Object] output returned by date/tokenizer-properties.
+ *
+ * Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a":
+ * [{
+ * type: "h",
+ * lexeme: "5"
+ * }, {
+ * type: "literal",
+ * lexeme: " "
+ * }, {
+ * type: "literal",
+ * lexeme: "o'clock"
+ * }, {
+ * type: "literal",
+ * lexeme: " "
+ * }, {
+ * type: "a",
+ * lexeme: "PM",
+ * value: "pm"
+ * }]
+ *
+ * OBS: lexeme's are always String and may return invalid ranges depending of the token type.
+ * Eg. "99" for month number.
+ *
+ * Return an empty Array when not successfully parsed.
+ */
+var dateTokenizer = function( value, numberParser, properties ) {
+ var valid,
+ timeSeparator = properties.timeSeparator,
+ tokens = [],
+ widths = [ "abbreviated", "wide", "narrow" ];
+
+ valid = properties.pattern.match( datePatternRe ).every(function( current ) {
+ var chr, length, numeric, tokenRe,
+ token = {};
+
+ function hourFormatParse( tokenRe, numberParser ) {
+ var aux = value.match( tokenRe );
+ numberParser = numberParser || function( value ) {
+ return +value;
+ };
+
+ if ( !aux ) {
+ return false;
+ }
+
+ // hourFormat containing H only, e.g., `+H;-H`
+ if ( aux.length < 8 ) {
+ token.value =
+ ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 4 ] ) ) * 60;
+
+ // hourFormat containing H and m, e.g., `+HHmm;-HHmm`
+ } else {
+ token.value =
+ ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 7 ] ) ) * 60 +
+ ( aux[ 1 ] ? -numberParser( aux[ 4 ] ) : numberParser( aux[ 10 ] ) );
+ }
+
+ return true;
+ }
+
+ // Transform:
+ // - "+H;-H" -> /\+(\d\d?)|-(\d\d?)/
+ // - "+HH;-HH" -> /\+(\d\d)|-(\d\d)/
+ // - "+HHmm;-HHmm" -> /\+(\d\d)(\d\d)|-(\d\d)(\d\d)/
+ // - "+HH:mm;-HH:mm" -> /\+(\d\d):(\d\d)|-(\d\d):(\d\d)/
+ //
+ // If gmtFormat is GMT{0}, the regexp must fill {0} in each side, e.g.:
+ // - "+H;-H" -> /GMT\+(\d\d?)|GMT-(\d\d?)/
+ function hourFormatRe( hourFormat, gmtFormat, timeSeparator ) {
+ var re;
+
+ if ( !gmtFormat ) {
+ gmtFormat = "{0}";
+ }
+
+ re = hourFormat
+ .replace( "+", "\\+" )
+
+ // Unicode equivalent to (\\d\\d)
+ .replace( /HH|mm/g, "((" + regexpN.source + ")(" + regexpN.source + "))" )
+
+ // Unicode equivalent to (\\d\\d?)
+ .replace( /H|m/g, "((" + regexpN.source + ")(" + regexpN.source + ")?)" );
+
+ if ( timeSeparator ) {
+ re = re.replace( /:/g, timeSeparator );
+ }
+
+ re = re.split( ";" ).map(function( part ) {
+ return gmtFormat.replace( "{0}", part );
+ }).join( "|" );
+
+ return new RegExp( re );
+ }
+
+ function oneDigitIfLengthOne() {
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d/
+ numeric = true;
+ return tokenRe = regexpN;
+ }
+ }
+
+ function oneOrTwoDigitsIfLengthOne() {
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d\d?/
+ numeric = true;
+ return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")?" );
+ }
+ }
+
+ function twoDigitsIfLengthTwo() {
+ if ( length === 2 ) {
+
+ // Unicode equivalent to /\d\d/
+ numeric = true;
+ return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" );
+ }
+ }
+
+ // Brute-force test every locale entry in an attempt to match the given value.
+ // Return the first found one (and set token accordingly), or null.
+ function lookup( path ) {
+ var i, re,
+ data = properties[ path.join( "/" ) ];
+
+ for ( i in data ) {
+ re = new RegExp( "^" + data[ i ] );
+ if ( re.test( value ) ) {
+ token.value = i;
+ return tokenRe = new RegExp( data[ i ] );
+ }
+ }
+ return null;
+ }
+
+ token.type = current;
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "Z" ) {
+ // Z..ZZZ: same as "xxxx".
+ if ( length < 4 ) {
+ chr = "x";
+ length = 4;
+
+ // ZZZZ: same as "OOOO".
+ } else if ( length < 5 ) {
+ chr = "O";
+ length = 4;
+
+ // ZZZZZ: same as "XXXXX"
+ } else {
+ chr = "X";
+ length = 5;
+ }
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ lookup([
+ "gregorian/eras",
+ length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
+ ]);
+ break;
+
+ // Year
+ case "y":
+ case "Y":
+ numeric = true;
+
+ // number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ...
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d+/.
+ tokenRe = new RegExp( "(" + regexpN.source + ")+" );
+ } else if ( length === 2 ) {
+
+ // Unicode equivalent to /\d\d/
+ tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" );
+ } else {
+
+ // Unicode equivalent to /\d{length,}/
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + ",}" );
+ }
+ break;
+
+ // Quarter
+ case "Q":
+ case "q":
+ // number l=1:{1}, l=2:{2}.
+ // lookup l=3...
+ oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
+ "gregorian/quarters",
+ chr === "Q" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ // number l=1:{1,2}, l=2:{2}.
+ // lookup l=3...
+ oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
+ "gregorian/months",
+ chr === "M" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ break;
+
+ // Day
+ case "D":
+ // number {l,3}.
+ if ( length <= 3 ) {
+
+ // Unicode equivalent to /\d{length,3}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + ",3}" );
+ }
+ break;
+
+ case "W":
+ case "F":
+ // number l=1:{1}.
+ oneDigitIfLengthOne();
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+ // number l=1:{1}, l=2:{2}.
+ // lookup for length >=3.
+ if ( length <= 2 ) {
+ oneDigitIfLengthOne() || twoDigitsIfLengthTwo();
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ if ( length === 6 ) {
+ // Note: if short day names are not explicitly specified, abbreviated day
+ // names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
+ lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "short"
+ ]) || lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "abbreviated"
+ ]);
+ } else {
+ lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ widths[ length < 3 ? 0 : length - 3 ]
+ ]);
+ }
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ lookup([
+ "gregorian/dayPeriods/format/wide"
+ ]);
+ break;
+
+ // Week, Day, Hour, Minute, or Second
+ case "w":
+ case "d":
+ case "h":
+ case "H":
+ case "K":
+ case "k":
+ case "j":
+ case "m":
+ case "s":
+ // number l1:{1,2}, l2:{2}.
+ oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo();
+ break;
+
+ case "S":
+ // number {l}.
+
+ // Unicode equivalent to /\d{length}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + "}" );
+ break;
+
+ case "A":
+ // number {l+5}.
+
+ // Unicode equivalent to /\d{length+5}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + ( length + 5 ) + "}" );
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+ // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT".
+ // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT".
+ if ( value === properties[ "timeZoneNames/gmtZeroFormat" ] ) {
+ token.value = 0;
+ tokenRe = new RegExp( properties[ "timeZoneNames/gmtZeroFormat" ] );
+ } else {
+ tokenRe = hourFormatRe(
+ length < 4 ? "+H;-H" : properties[ "timeZoneNames/hourFormat" ],
+ properties[ "timeZoneNames/gmtFormat" ],
+ timeSeparator
+ );
+ if ( !hourFormatParse( tokenRe, numberParser ) ) {
+ return null;
+ }
+ }
+ break;
+
+ case "X":
+ // Same as x*, except it uses "Z" for zero offset.
+ if ( value === "Z" ) {
+ token.value = 0;
+ tokenRe = /Z/;
+ break;
+ }
+
+ /* falls through */
+ case "x":
+ // x: hourFormat("+HH;-HH")
+ // xx or xxxx: hourFormat("+HHmm;-HHmm")
+ // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm")
+ tokenRe = hourFormatRe(
+ length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" )
+ );
+ if ( !hourFormatParse( tokenRe ) ) {
+ return null;
+ }
+ break;
+
+ case "'":
+ token.type = "literal";
+ current = current.replace( /''/, "'" );
+ if ( length > 2 ) {
+ current = current.slice( 1, -1 );
+ }
+ tokenRe = new RegExp( regexpEscape( current ) );
+ break;
+
+ default:
+ token.type = "literal";
+ tokenRe = /./;
+ }
+
+ if ( !tokenRe ) {
+ return false;
+ }
+
+ // Get lexeme and consume it.
+ value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) {
+ token.lexeme = lexeme;
+ if ( numeric ) {
+ token.value = numberParser( lexeme );
+ }
+ return "";
+ });
+
+ if ( !token.lexeme ) {
+ return false;
+ }
+
+ tokens.push( token );
+ return true;
+ });
+
+ return valid ? tokens : [];
+};
+
+
+
+
+/**
+ * tokenizerProperties( pattern, cldr )
+ *
+ * @pattern [String] raw pattern.
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return Object with data that will be used by tokenizer.
+ */
+var dateTokenizerProperties = function( pattern, cldr ) {
+ var properties = {
+ pattern: pattern,
+ timeSeparator: numberSymbol( "timeSeparator", cldr )
+ },
+ widths = [ "abbreviated", "wide", "narrow" ];
+
+ function populateProperties( path, value ) {
+
+ // The `dates` and `calendars` trim's purpose is to reduce properties' key size only.
+ properties[ path.replace( /^.*\/dates\//, "" ).replace( /calendars\//, "" ) ] = value;
+ }
+
+ cldr.on( "get", populateProperties );
+
+ pattern.match( datePatternRe ).forEach(function( current ) {
+ var chr, length;
+
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "Z" && length < 5 ) {
+ chr = "O";
+ length = 4;
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ cldr.main([
+ "dates/calendars/gregorian/eras",
+ length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
+ ]);
+ break;
+
+ // Year
+ case "u": // Extended year. Need to be implemented.
+ case "U": // Cyclic year name. Need to be implemented.
+ throw createErrorUnsupportedFeature({
+ feature: "year pattern `" + chr + "`"
+ });
+
+ // Quarter
+ case "Q":
+ case "q":
+ if ( length > 2 ) {
+ cldr.main([
+ "dates/calendars/gregorian/quarters",
+ chr === "Q" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ }
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ // number l=1:{1,2}, l=2:{2}.
+ // lookup l=3...
+ if ( length > 2 ) {
+ cldr.main([
+ "dates/calendars/gregorian/months",
+ chr === "M" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ }
+ break;
+
+ // Day
+ case "g":
+ // Modified Julian day. Need to be implemented.
+ throw createErrorUnsupportedFeature({
+ feature: "Julian day pattern `g`"
+ });
+
+ // Week day
+ case "e":
+ case "c":
+ // lookup for length >=3.
+ if ( length <= 2 ) {
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ if ( length === 6 ) {
+ // Note: if short day names are not explicitly specified, abbreviated day
+ // names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
+ cldr.main([
+ "dates/calendars/gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "short"
+ ]) || cldr.main([
+ "dates/calendars/gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "abbreviated"
+ ]);
+ } else {
+ cldr.main([
+ "dates/calendars/gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ widths[ length < 3 ? 0 : length - 3 ]
+ ]);
+ }
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ cldr.main([
+ "dates/calendars/gregorian/dayPeriods/format/wide"
+ ]);
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+ cldr.main( "dates/timeZoneNames/gmtFormat" );
+ cldr.main( "dates/timeZoneNames/gmtZeroFormat" );
+ cldr.main( "dates/timeZoneNames/hourFormat" );
+ break;
+
+ case "v":
+ case "V":
+ throw createErrorUnsupportedFeature({
+ feature: "timezone pattern `" + chr + "`"
+ });
+ }
+ });
+
+ cldr.off( "get", populateProperties );
+
+ return properties;
+};
+
+
+
+
+function validateRequiredCldr( path, value ) {
+ validateCldr( path, value, {
+ skip: [
+ /dates\/calendars\/gregorian\/dateTimeFormats\/availableFormats/,
+ /dates\/calendars\/gregorian\/days\/.*\/short/,
+ /supplemental\/timeData\/(?!001)/,
+ /supplemental\/weekData\/(?!001)/
+ ]
+ });
+}
+
+/**
+ * .dateFormatter( options )
+ *
+ * @options [Object] see date/expand_pattern for more info.
+ *
+ * Return a date formatter function (of the form below) according to the given options and the
+ * default/instance locale.
+ *
+ * fn( value )
+ *
+ * @value [Date]
+ *
+ * Return a function that formats a date according to the given `format` and the default/instance
+ * locale.
+ */
+Globalize.dateFormatter =
+Globalize.prototype.dateFormatter = function( options ) {
+ var cldr, numberFormatters, pad, pattern, properties;
+
+ validateParameterTypePlainObject( options, "options" );
+
+ cldr = this.cldr;
+ options = options || { skeleton: "yMd" };
+
+ validateDefaultLocale( cldr );
+
+ cldr.on( "get", validateRequiredCldr );
+ pattern = dateExpandPattern( options, cldr );
+ properties = dateFormatProperties( pattern, cldr );
+ cldr.off( "get", validateRequiredCldr );
+
+ // Create needed number formatters.
+ numberFormatters = properties.numberFormatters;
+ delete properties.numberFormatters;
+ for ( pad in numberFormatters ) {
+ numberFormatters[ pad ] = this.numberFormatter({
+ raw: numberFormatters[ pad ]
+ });
+ }
+
+ return function( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeDate( value, "value" );
+ return dateFormat( value, numberFormatters, properties );
+ };
+};
+
+/**
+ * .dateParser( options )
+ *
+ * @options [Object] see date/expand_pattern for more info.
+ *
+ * Return a function that parses a string date according to the given `formats` and the
+ * default/instance locale.
+ */
+Globalize.dateParser =
+Globalize.prototype.dateParser = function( options ) {
+ var cldr, numberParser, parseProperties, pattern, tokenizerProperties;
+
+ validateParameterTypePlainObject( options, "options" );
+
+ cldr = this.cldr;
+ options = options || { skeleton: "yMd" };
+
+ validateDefaultLocale( cldr );
+
+ cldr.on( "get", validateRequiredCldr );
+ pattern = dateExpandPattern( options, cldr );
+ tokenizerProperties = dateTokenizerProperties( pattern, cldr );
+ parseProperties = dateParseProperties( cldr );
+ cldr.off( "get", validateRequiredCldr );
+
+ numberParser = this.numberParser({ raw: "0" });
+
+ return function( value ) {
+ var tokens;
+
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ tokens = dateTokenizer( value, numberParser, tokenizerProperties );
+ return dateParse( value, tokens, parseProperties ) || null;
+ };
+};
+
+/**
+ * .formatDate( value, options )
+ *
+ * @value [Date]
+ *
+ * @options [Object] see date/expand_pattern for more info.
+ *
+ * Formats a date or number according to the given options string and the default/instance locale.
+ */
+Globalize.formatDate =
+Globalize.prototype.formatDate = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeDate( value, "value" );
+
+ return this.dateFormatter( options )( value );
+};
+
+/**
+ * .parseDate( value, options )
+ *
+ * @value [String]
+ *
+ * @options [Object] see date/expand_pattern for more info.
+ *
+ * Return a Date instance or null.
+ */
+Globalize.parseDate =
+Globalize.prototype.parseDate = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ return this.dateParser( options )( value );
+};
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/globalize/globalize/number.js b/external/globalize/globalize/number.js
new file mode 100644
index 000000000..7ab4256d4
--- /dev/null
+++ b/external/globalize/globalize/number.js
@@ -0,0 +1,1266 @@
+/**
+ * Globalize v1.0.0
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-04-23T12:02Z
+ */
+/*!
+ * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define([
+ "cldr",
+ "../globalize",
+ "cldr/event",
+ "cldr/supplemental"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory( require( "cldrjs" ), require( "globalize" ) );
+ } else {
+
+ // Global
+ factory( root.Cldr, root.Globalize );
+ }
+}(this, function( Cldr, Globalize ) {
+
+var createError = Globalize._createError,
+ objectExtend = Globalize._objectExtend,
+ regexpEscape = Globalize._regexpEscape,
+ stringPad = Globalize._stringPad,
+ validateCldr = Globalize._validateCldr,
+ validateDefaultLocale = Globalize._validateDefaultLocale,
+ validateParameterPresence = Globalize._validateParameterPresence,
+ validateParameterRange = Globalize._validateParameterRange,
+ validateParameterType = Globalize._validateParameterType,
+ validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject;
+
+
+var createErrorUnsupportedFeature = function( feature ) {
+ return createError( "E_UNSUPPORTED", "Unsupported {feature}.", {
+ feature: feature
+ });
+};
+
+
+
+
+var validateParameterTypeNumber = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "number",
+ "Number"
+ );
+};
+
+
+
+
+var validateParameterTypeString = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "string",
+ "a string"
+ );
+};
+
+
+
+
+/**
+ * goupingSeparator( number, primaryGroupingSize, secondaryGroupingSize )
+ *
+ * @number [Number].
+ *
+ * @primaryGroupingSize [Number]
+ *
+ * @secondaryGroupingSize [Number]
+ *
+ * Return the formatted number with group separator.
+ */
+var numberFormatGroupingSeparator = function( number, primaryGroupingSize, secondaryGroupingSize ) {
+ var index,
+ currentGroupingSize = primaryGroupingSize,
+ ret = "",
+ sep = ",",
+ switchToSecondary = secondaryGroupingSize ? true : false;
+
+ number = String( number ).split( "." );
+ index = number[ 0 ].length;
+
+ while ( index > currentGroupingSize ) {
+ ret = number[ 0 ].slice( index - currentGroupingSize, index ) +
+ ( ret.length ? sep : "" ) + ret;
+ index -= currentGroupingSize;
+ if ( switchToSecondary ) {
+ currentGroupingSize = secondaryGroupingSize;
+ switchToSecondary = false;
+ }
+ }
+
+ number[ 0 ] = number[ 0 ].slice( 0, index ) + ( ret.length ? sep : "" ) + ret;
+ return number.join( "." );
+};
+
+
+
+
+/**
+ * integerFractionDigits( number, minimumIntegerDigits, minimumFractionDigits,
+ * maximumFractionDigits, round, roundIncrement )
+ *
+ * @number [Number]
+ *
+ * @minimumIntegerDigits [Number]
+ *
+ * @minimumFractionDigits [Number]
+ *
+ * @maximumFractionDigits [Number]
+ *
+ * @round [Function]
+ *
+ * @roundIncrement [Function]
+ *
+ * Return the formatted integer and fraction digits.
+ */
+var numberFormatIntegerFractionDigits = function( number, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, round,
+ roundIncrement ) {
+
+ // Fraction
+ if ( maximumFractionDigits ) {
+
+ // Rounding
+ if ( roundIncrement ) {
+ number = round( number, roundIncrement );
+
+ // Maximum fraction digits
+ } else {
+ number = round( number, { exponent: -maximumFractionDigits } );
+ }
+
+ // Minimum fraction digits
+ if ( minimumFractionDigits ) {
+ number = String( number ).split( "." );
+ number[ 1 ] = stringPad( number[ 1 ] || "", minimumFractionDigits, true );
+ number = number.join( "." );
+ }
+ } else {
+ number = round( number );
+ }
+
+ number = String( number );
+
+ // Minimum integer digits
+ if ( minimumIntegerDigits ) {
+ number = number.split( "." );
+ number[ 0 ] = stringPad( number[ 0 ], minimumIntegerDigits );
+ number = number.join( "." );
+ }
+
+ return number;
+};
+
+
+
+
+/**
+ * toPrecision( number, precision, round )
+ *
+ * @number (Number)
+ *
+ * @precision (Number) significant figures precision (not decimal precision).
+ *
+ * @round (Function)
+ *
+ * Return number.toPrecision( precision ) using the given round function.
+ */
+var numberToPrecision = function( number, precision, round ) {
+ var roundOrder;
+
+ // Get number at two extra significant figure precision.
+ number = number.toPrecision( precision + 2 );
+
+ // Then, round it to the required significant figure precision.
+ roundOrder = Math.ceil( Math.log( Math.abs( number ) ) / Math.log( 10 ) );
+ roundOrder -= precision;
+
+ return round( number, { exponent: roundOrder } );
+};
+
+
+
+
+/**
+ * toPrecision( number, minimumSignificantDigits, maximumSignificantDigits, round )
+ *
+ * @number [Number]
+ *
+ * @minimumSignificantDigits [Number]
+ *
+ * @maximumSignificantDigits [Number]
+ *
+ * @round [Function]
+ *
+ * Return the formatted significant digits number.
+ */
+var numberFormatSignificantDigits = function( number, minimumSignificantDigits, maximumSignificantDigits, round ) {
+ var atMinimum, atMaximum;
+
+ // Sanity check.
+ if ( minimumSignificantDigits > maximumSignificantDigits ) {
+ maximumSignificantDigits = minimumSignificantDigits;
+ }
+
+ atMinimum = numberToPrecision( number, minimumSignificantDigits, round );
+ atMaximum = numberToPrecision( number, maximumSignificantDigits, round );
+
+ // Use atMaximum only if it has more significant digits than atMinimum.
+ number = +atMinimum === +atMaximum ? atMinimum : atMaximum;
+
+ // Expand integer numbers, eg. 123e5 to 12300.
+ number = ( +number ).toString( 10 );
+
+ if ( (/e/).test( number ) ) {
+ throw createErrorUnsupportedFeature({
+ feature: "integers out of (1e21, 1e-7)"
+ });
+ }
+
+ // Add trailing zeros if necessary.
+ if ( minimumSignificantDigits - number.replace( /^0+|\./g, "" ).length > 0 ) {
+ number = number.split( "." );
+ number[ 1 ] = stringPad( number[ 1 ] || "", minimumSignificantDigits - number[ 0 ].replace( /^0+/, "" ).length, true );
+ number = number.join( "." );
+ }
+
+ return number;
+};
+
+
+
+
+/**
+ * format( number, properties )
+ *
+ * @number [Number].
+ *
+ * @properties [Object] Output of number/format-properties.
+ *
+ * Return the formatted number.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberFormat = function( number, properties ) {
+ var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
+ minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix,
+ primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,
+ symbolMap;
+
+ padding = properties[ 1 ];
+ minimumIntegerDigits = properties[ 2 ];
+ minimumFractionDigits = properties[ 3 ];
+ maximumFractionDigits = properties[ 4 ];
+ minimumSignificantDigits = properties[ 5 ];
+ maximumSignificantDigits = properties[ 6 ];
+ roundIncrement = properties[ 7 ];
+ primaryGroupingSize = properties[ 8 ];
+ secondaryGroupingSize = properties[ 9 ];
+ round = properties[ 15 ];
+ infinitySymbol = properties[ 16 ];
+ nanSymbol = properties[ 17 ];
+ symbolMap = properties[ 18 ];
+ nuDigitsMap = properties[ 19 ];
+
+ // NaN
+ if ( isNaN( number ) ) {
+ return nanSymbol;
+ }
+
+ if ( number < 0 ) {
+ pattern = properties[ 12 ];
+ prefix = properties[ 13 ];
+ suffix = properties[ 14 ];
+ } else {
+ pattern = properties[ 11 ];
+ prefix = properties[ 0 ];
+ suffix = properties[ 10 ];
+ }
+
+ // Infinity
+ if ( !isFinite( number ) ) {
+ return prefix + infinitySymbol + suffix;
+ }
+
+ ret = prefix;
+
+ // Percent
+ if ( pattern.indexOf( "%" ) !== -1 ) {
+ number *= 100;
+
+ // Per mille
+ } else if ( pattern.indexOf( "\u2030" ) !== -1 ) {
+ number *= 1000;
+ }
+
+ // Significant digit format
+ if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
+ number = numberFormatSignificantDigits( number, minimumSignificantDigits,
+ maximumSignificantDigits, round );
+
+ // Integer and fractional format
+ } else {
+ number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits,
+ minimumFractionDigits, maximumFractionDigits, round, roundIncrement );
+ }
+
+ // Remove the possible number minus sign
+ number = number.replace( /^-/, "" );
+
+ // Grouping separators
+ if ( primaryGroupingSize ) {
+ number = numberFormatGroupingSeparator( number, primaryGroupingSize,
+ secondaryGroupingSize );
+ }
+
+ ret += number;
+
+ // Scientific notation
+ // TODO implement here
+
+ // Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g
+ // TODO implement here
+
+ ret += suffix;
+
+ return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) {
+
+ // Literals
+ if ( literal ) {
+ literal = literal.replace( /''/, "'" );
+ if ( literal.length > 2 ) {
+ literal = literal.slice( 1, -1 );
+ }
+ return literal;
+ }
+
+ // Symbols
+ character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) {
+ return symbolMap[ symbol ];
+ });
+
+ // Numbering system
+ if ( nuDigitsMap ) {
+ character = character.replace( /[0-9]/, function( digit ) {
+ return nuDigitsMap[ +digit ];
+ });
+ }
+
+ return character;
+ });
+};
+
+
+
+
+/**
+ * NumberingSystem( cldr )
+ *
+ * - http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems
+ * - http://cldr.unicode.org/index/bcp47-extension
+ * - http://www.unicode.org/reports/tr35/#u_Extension
+ */
+var numberNumberingSystem = function( cldr ) {
+ var nu = cldr.attributes[ "u-nu" ];
+
+ if ( nu ) {
+ if ( nu === "traditio" ) {
+ nu = "traditional";
+ }
+ if ( [ "native", "traditional", "finance" ].indexOf( nu ) !== -1 ) {
+
+ // Unicode locale extension `u-nu` is set using either (native, traditional or
+ // finance). So, lookup the respective locale's numberingSystem and return it.
+ return cldr.main([ "numbers/otherNumberingSystems", nu ]);
+ }
+
+ // Unicode locale extension `u-nu` is set with an explicit numberingSystem. Return it.
+ return nu;
+ }
+
+ // Return the default numberingSystem.
+ return cldr.main( "numbers/defaultNumberingSystem" );
+};
+
+
+
+
+/**
+ * nuMap( cldr )
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return digits map if numbering system is different than `latn`.
+ */
+var numberNumberingSystemDigitsMap = function( cldr ) {
+ var aux,
+ nu = numberNumberingSystem( cldr );
+
+ if ( nu === "latn" ) {
+ return;
+ }
+
+ aux = cldr.supplemental([ "numberingSystems", nu ]);
+
+ if ( aux._type !== "numeric" ) {
+ throw createErrorUnsupportedFeature( "`" + aux._type + "` numbering system" );
+ }
+
+ return aux._digits;
+};
+
+
+
+
+/**
+ * EBNF representation:
+ *
+ * number_pattern_re = prefix?
+ * padding?
+ * (integer_fraction_pattern | significant_pattern)
+ * scientific_notation?
+ * suffix?
+ *
+ * prefix = non_number_stuff
+ *
+ * padding = "*" regexp(.)
+ *
+ * integer_fraction_pattern = integer_pattern
+ * fraction_pattern?
+ *
+ * integer_pattern = regexp([#,]*[0,]*0+)
+ *
+ * fraction_pattern = "." regexp(0*[0-9]*#*)
+ *
+ * significant_pattern = regexp([#,]*@+#*)
+ *
+ * scientific_notation = regexp(E\+?0+)
+ *
+ * suffix = non_number_stuff
+ *
+ * non_number_stuff = regexp(('[^']+'|''|[^*#@0,.E])*)
+ *
+ *
+ * Regexp groups:
+ *
+ * 0: number_pattern_re
+ * 1: prefix
+ * 2: -
+ * 3: padding
+ * 4: (integer_fraction_pattern | significant_pattern)
+ * 5: integer_fraction_pattern
+ * 6: integer_pattern
+ * 7: fraction_pattern
+ * 8: significant_pattern
+ * 9: scientific_notation
+ * 10: suffix
+ * 11: -
+ */
+var numberPatternRe = (/^(('[^']+'|''|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/);
+
+
+
+
+/**
+ * format( number, pattern )
+ *
+ * @number [Number].
+ *
+ * @pattern [String] raw pattern for numbers.
+ *
+ * Return the formatted number.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberPatternProperties = function( pattern ) {
+ var aux1, aux2, fractionPattern, integerFractionOrSignificantPattern, integerPattern,
+ maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
+ minimumIntegerDigits, minimumSignificantDigits, padding, prefix, primaryGroupingSize,
+ roundIncrement, scientificNotation, secondaryGroupingSize, significantPattern, suffix;
+
+ pattern = pattern.match( numberPatternRe );
+ if ( !pattern ) {
+ throw new Error( "Invalid pattern: " + pattern );
+ }
+
+ prefix = pattern[ 1 ];
+ padding = pattern[ 3 ];
+ integerFractionOrSignificantPattern = pattern[ 4 ];
+ significantPattern = pattern[ 8 ];
+ scientificNotation = pattern[ 9 ];
+ suffix = pattern[ 10 ];
+
+ // Significant digit format
+ if ( significantPattern ) {
+ significantPattern.replace( /(@+)(#*)/, function( match, minimumSignificantDigitsMatch, maximumSignificantDigitsMatch ) {
+ minimumSignificantDigits = minimumSignificantDigitsMatch.length;
+ maximumSignificantDigits = minimumSignificantDigits +
+ maximumSignificantDigitsMatch.length;
+ });
+
+ // Integer and fractional format
+ } else {
+ fractionPattern = pattern[ 7 ];
+ integerPattern = pattern[ 6 ];
+
+ if ( fractionPattern ) {
+
+ // Minimum fraction digits, and rounding.
+ fractionPattern.replace( /[0-9]+/, function( match ) {
+ minimumFractionDigits = match;
+ });
+ if ( minimumFractionDigits ) {
+ roundIncrement = +( "0." + minimumFractionDigits );
+ minimumFractionDigits = minimumFractionDigits.length;
+ } else {
+ minimumFractionDigits = 0;
+ }
+
+ // Maximum fraction digits
+ // 1: ignore decimal character
+ maximumFractionDigits = fractionPattern.length - 1 /* 1 */;
+ }
+
+ // Minimum integer digits
+ integerPattern.replace( /0+$/, function( match ) {
+ minimumIntegerDigits = match.length;
+ });
+ }
+
+ // Scientific notation
+ if ( scientificNotation ) {
+ throw createErrorUnsupportedFeature({
+ feature: "scientific notation (not implemented)"
+ });
+ }
+
+ // Padding
+ if ( padding ) {
+ throw createErrorUnsupportedFeature({
+ feature: "padding (not implemented)"
+ });
+ }
+
+ // Grouping
+ if ( ( aux1 = integerFractionOrSignificantPattern.lastIndexOf( "," ) ) !== -1 ) {
+
+ // Primary grouping size is the interval between the last group separator and the end of
+ // the integer (or the end of the significant pattern).
+ aux2 = integerFractionOrSignificantPattern.split( "." )[ 0 ];
+ primaryGroupingSize = aux2.length - aux1 - 1;
+
+ // Secondary grouping size is the interval between the last two group separators.
+ if ( ( aux2 = integerFractionOrSignificantPattern.lastIndexOf( ",", aux1 - 1 ) ) !== -1 ) {
+ secondaryGroupingSize = aux1 - 1 - aux2;
+ }
+ }
+
+ // Return:
+ // 0: @prefix String
+ // 1: @padding Array [ <character>, <count> ] TODO
+ // 2: @minimumIntegerDigits non-negative integer Number value indicating the minimum integer
+ // digits to be used. Numbers will be padded with leading zeroes if necessary.
+ // 3: @minimumFractionDigits and
+ // 4: @maximumFractionDigits are non-negative integer Number values indicating the minimum and
+ // maximum fraction digits to be used. Numbers will be rounded or padded with trailing
+ // zeroes if necessary.
+ // 5: @minimumSignificantDigits and
+ // 6: @maximumSignificantDigits are positive integer Number values indicating the minimum and
+ // maximum fraction digits to be shown. Either none or both of these properties are
+ // present; if they are, they override minimum and maximum integer and fraction digits
+ // – the formatter uses however many integer and fraction digits are required to display
+ // the specified number of significant digits.
+ // 7: @roundIncrement Decimal round increment or null
+ // 8: @primaryGroupingSize
+ // 9: @secondaryGroupingSize
+ // 10: @suffix String
+ return [
+ prefix,
+ padding,
+ minimumIntegerDigits,
+ minimumFractionDigits,
+ maximumFractionDigits,
+ minimumSignificantDigits,
+ maximumSignificantDigits,
+ roundIncrement,
+ primaryGroupingSize,
+ secondaryGroupingSize,
+ suffix
+ ];
+};
+
+
+
+
+/**
+ * Symbol( name, cldr )
+ *
+ * @name [String] Symbol name.
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return the localized symbol given its name.
+ */
+var numberSymbol = function( name, cldr ) {
+ return cldr.main([
+ "numbers/symbols-numberSystem-" + numberNumberingSystem( cldr ),
+ name
+ ]);
+};
+
+
+
+
+var numberSymbolName = {
+ ".": "decimal",
+ ",": "group",
+ "%": "percentSign",
+ "+": "plusSign",
+ "-": "minusSign",
+ "E": "exponential",
+ "\u2030": "perMille"
+};
+
+
+
+
+/**
+ * symbolMap( cldr )
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return the (localized symbol, pattern symbol) key value pair, eg. {
+ * ".": "٫",
+ * ",": "٬",
+ * "%": "٪",
+ * ...
+ * };
+ */
+var numberSymbolMap = function( cldr ) {
+ var symbol,
+ symbolMap = {};
+
+ for ( symbol in numberSymbolName ) {
+ symbolMap[ symbol ] = numberSymbol( numberSymbolName[ symbol ], cldr );
+ }
+
+ return symbolMap;
+};
+
+
+
+
+var numberTruncate = function( value ) {
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+ return Math[ value < 0 ? "ceil" : "floor" ]( value );
+};
+
+
+
+
+/**
+ * round( method )
+ *
+ * @method [String] with either "round", "ceil", "floor", or "truncate".
+ *
+ * Return function( value, incrementOrExp ):
+ *
+ * @value [Number] eg. 123.45.
+ *
+ * @incrementOrExp [Number] optional, eg. 0.1; or
+ * [Object] Either { increment: <value> } or { exponent: <value> }
+ *
+ * Return the rounded number, eg:
+ * - round( "round" )( 123.45 ): 123;
+ * - round( "ceil" )( 123.45 ): 124;
+ * - round( "floor" )( 123.45 ): 123;
+ * - round( "truncate" )( 123.45 ): 123;
+ * - round( "round" )( 123.45, 0.1 ): 123.5;
+ * - round( "round" )( 123.45, 10 ): 120;
+ *
+ * Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
+ * Ref: #376
+ */
+var numberRound = function( method ) {
+ method = method || "round";
+ method = method === "truncate" ? numberTruncate : Math[ method ];
+
+ return function( value, incrementOrExp ) {
+ var exp, increment;
+
+ value = +value;
+
+ // If the value is not a number, return NaN.
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+
+ // Exponent given.
+ if ( typeof incrementOrExp === "object" && incrementOrExp.exponent ) {
+ exp = +incrementOrExp.exponent;
+ increment = 1;
+
+ if ( exp === 0 ) {
+ return method( value );
+ }
+
+ // If the exp is not an integer, return NaN.
+ if ( !( typeof exp === "number" && exp % 1 === 0 ) ) {
+ return NaN;
+ }
+
+ // Increment given.
+ } else {
+ increment = +incrementOrExp || 1;
+
+ if ( increment === 1 ) {
+ return method( value );
+ }
+
+ // If the increment is not a number, return NaN.
+ if ( isNaN( increment ) ) {
+ return NaN;
+ }
+
+ increment = increment.toExponential().split( "e" );
+ exp = +increment[ 1 ];
+ increment = +increment[ 0 ];
+ }
+
+ // Shift & Round
+ value = value.toString().split( "e" );
+ value[ 0 ] = +value[ 0 ] / increment;
+ value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] - exp ) : -exp;
+ value = method( +(value[ 0 ] + "e" + value[ 1 ] ) );
+
+ // Shift back
+ value = value.toString().split( "e" );
+ value[ 0 ] = +value[ 0 ] * increment;
+ value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] + exp ) : exp;
+ return +( value[ 0 ] + "e" + value[ 1 ] );
+ };
+};
+
+
+
+
+/**
+ * formatProperties( pattern, cldr [, options] )
+ *
+ * @pattern [String] raw pattern for numbers.
+ *
+ * @cldr [Cldr instance].
+ *
+ * @options [Object]:
+ * - minimumIntegerDigits [Number]
+ * - minimumFractionDigits, maximumFractionDigits [Number]
+ * - minimumSignificantDigits, maximumSignificantDigits [Number]
+ * - round [String] "ceil", "floor", "round" (default), or "truncate".
+ * - useGrouping [Boolean] default true.
+ *
+ * Return the processed properties that will be used in number/format.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberFormatProperties = function( pattern, cldr, options ) {
+ var negativePattern, negativePrefix, negativeProperties, negativeSuffix, positivePattern,
+ properties;
+
+ function getOptions( attribute, propertyIndex ) {
+ if ( attribute in options ) {
+ properties[ propertyIndex ] = options[ attribute ];
+ }
+ }
+
+ options = options || {};
+ pattern = pattern.split( ";" );
+
+ positivePattern = pattern[ 0 ];
+
+ negativePattern = pattern[ 1 ] || "-" + positivePattern;
+ negativeProperties = numberPatternProperties( negativePattern );
+ negativePrefix = negativeProperties[ 0 ];
+ negativeSuffix = negativeProperties[ 10 ];
+
+ properties = numberPatternProperties( positivePattern ).concat([
+ positivePattern,
+ negativePrefix + positivePattern + negativeSuffix,
+ negativePrefix,
+ negativeSuffix,
+ numberRound( options.round ),
+ numberSymbol( "infinity", cldr ),
+ numberSymbol( "nan", cldr ),
+ numberSymbolMap( cldr ),
+ numberNumberingSystemDigitsMap( cldr )
+ ]);
+
+ getOptions( "minimumIntegerDigits", 2 );
+ getOptions( "minimumFractionDigits", 3 );
+ getOptions( "maximumFractionDigits", 4 );
+ getOptions( "minimumSignificantDigits", 5 );
+ getOptions( "maximumSignificantDigits", 6 );
+
+ // Grouping separators
+ if ( options.useGrouping === false ) {
+ properties[ 8 ] = null;
+ }
+
+ // Normalize number of digits if only one of either minimumFractionDigits or
+ // maximumFractionDigits is passed in as an option
+ if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) {
+ // maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits );
+ properties[ 4 ] = Math.max( properties[ 3 ], properties[ 4 ] );
+ } else if ( !( "minimumFractionDigits" in options ) &&
+ "maximumFractionDigits" in options ) {
+ // minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits );
+ properties[ 3 ] = Math.min( properties[ 3 ], properties[ 4 ] );
+ }
+
+ // Return:
+ // 0-10: see number/pattern-properties.
+ // 11: @positivePattern [String] Positive pattern.
+ // 12: @negativePattern [String] Negative pattern.
+ // 13: @negativePrefix [String] Negative prefix.
+ // 14: @negativeSuffix [String] Negative suffix.
+ // 15: @round [Function] Round function.
+ // 16: @infinitySymbol [String] Infinity symbol.
+ // 17: @nanSymbol [String] NaN symbol.
+ // 18: @symbolMap [Object] A bunch of other symbols.
+ // 19: @nuDigitsMap [Array] Digits map if numbering system is different than `latn`.
+ return properties;
+};
+
+
+
+
+/**
+ * EBNF representation:
+ *
+ * number_pattern_re = prefix_including_padding?
+ * number
+ * scientific_notation?
+ * suffix?
+ *
+ * number = integer_including_group_separator fraction_including_decimal_separator
+ *
+ * integer_including_group_separator =
+ * regexp([0-9,]*[0-9]+)
+ *
+ * fraction_including_decimal_separator =
+ * regexp((\.[0-9]+)?)
+
+ * prefix_including_padding = non_number_stuff
+ *
+ * scientific_notation = regexp(E[+-]?[0-9]+)
+ *
+ * suffix = non_number_stuff
+ *
+ * non_number_stuff = regexp([^0-9]*)
+ *
+ *
+ * Regexp groups:
+ *
+ * 0: number_pattern_re
+ * 1: prefix
+ * 2: integer_including_group_separator fraction_including_decimal_separator
+ * 3: integer_including_group_separator
+ * 4: fraction_including_decimal_separator
+ * 5: scientific_notation
+ * 6: suffix
+ */
+var numberNumberRe = (/^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/);
+
+
+
+
+/**
+ * parse( value, properties )
+ *
+ * @value [String].
+ *
+ * @properties [Object] Parser properties is a reduced pre-processed cldr
+ * data set returned by numberParserProperties().
+ *
+ * Return the parsed Number (including Infinity) or NaN when value is invalid.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberParse = function( value, properties ) {
+ var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe,
+ localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix;
+
+ infinitySymbol = properties[ 0 ];
+ invertedSymbolMap = properties[ 1 ];
+ negativePrefix = properties[ 2 ];
+ negativeSuffix = properties[ 3 ];
+ invertedNuDigitsMap = properties[ 4 ];
+
+ // Infinite number.
+ if ( aux = value.match( infinitySymbol ) ) {
+
+ number = Infinity;
+ prefix = value.slice( 0, aux.length );
+ suffix = value.slice( aux.length + 1 );
+
+ // Finite number.
+ } else {
+
+ // TODO: Create it during setup, i.e., make it a property.
+ localizedSymbolsRe = new RegExp(
+ Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {
+ return regexpEscape( localizedSymbol );
+ }).join( "|" ),
+ "g"
+ );
+
+ // Reverse localized symbols.
+ value = value.replace( localizedSymbolsRe, function( localizedSymbol ) {
+ return invertedSymbolMap[ localizedSymbol ];
+ });
+
+ // Reverse localized numbering system.
+ if ( invertedNuDigitsMap ) {
+
+ // TODO: Create it during setup, i.e., make it a property.
+ localizedDigitRe = new RegExp(
+ Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) {
+ return regexpEscape( localizedDigit );
+ }).join( "|" ),
+ "g"
+ );
+ value = value.replace( localizedDigitRe, function( localizedDigit ) {
+ return invertedNuDigitsMap[ localizedDigit ];
+ });
+ }
+
+ // Is it a valid number?
+ value = value.match( numberNumberRe );
+ if ( !value ) {
+
+ // Invalid number.
+ return NaN;
+ }
+
+ prefix = value[ 1 ];
+ suffix = value[ 6 ];
+
+ // Remove grouping separators.
+ number = value[ 2 ].replace( /,/g, "" );
+
+ // Scientific notation
+ if ( value[ 5 ] ) {
+ number += value[ 5 ];
+ }
+
+ number = +number;
+
+ // Is it a valid number?
+ if ( isNaN( number ) ) {
+
+ // Invalid number.
+ return NaN;
+ }
+
+ // Percent
+ if ( value[ 0 ].indexOf( "%" ) !== -1 ) {
+ number /= 100;
+ suffix = suffix.replace( "%", "" );
+
+ // Per mille
+ } else if ( value[ 0 ].indexOf( "\u2030" ) !== -1 ) {
+ number /= 1000;
+ suffix = suffix.replace( "\u2030", "" );
+ }
+ }
+
+ // Negative number
+ // "If there is an explicit negative subpattern, it serves only to specify the negative prefix
+ // and suffix. If there is no explicit negative subpattern, the negative subpattern is the
+ // localized minus sign prefixed to the positive subpattern" UTS#35
+ if ( prefix === negativePrefix && suffix === negativeSuffix ) {
+ number *= -1;
+ }
+
+ return number;
+};
+
+
+
+
+/**
+ * symbolMap( cldr )
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return the (localized symbol, pattern symbol) key value pair, eg. {
+ * "٫": ".",
+ * "٬": ",",
+ * "٪": "%",
+ * ...
+ * };
+ */
+var numberSymbolInvertedMap = function( cldr ) {
+ var symbol,
+ symbolMap = {};
+
+ for ( symbol in numberSymbolName ) {
+ symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol;
+ }
+
+ return symbolMap;
+};
+
+
+
+
+/**
+ * parseProperties( pattern, cldr )
+ *
+ * @pattern [String] raw pattern for numbers.
+ *
+ * @cldr [Cldr instance].
+ *
+ * Return parser properties, used to feed parser function.
+ */
+var numberParseProperties = function( pattern, cldr ) {
+ var invertedNuDigitsMap, invertedNuDigitsMapSanityCheck, negativePattern, negativeProperties,
+ nuDigitsMap = numberNumberingSystemDigitsMap( cldr );
+
+ pattern = pattern.split( ";" );
+ negativePattern = pattern[ 1 ] || "-" + pattern[ 0 ];
+ negativeProperties = numberPatternProperties( negativePattern );
+ if ( nuDigitsMap ) {
+ invertedNuDigitsMap = nuDigitsMap.split( "" ).reduce(function( object, localizedDigit, i ) {
+ object[ localizedDigit ] = String( i );
+ return object;
+ }, {} );
+ invertedNuDigitsMapSanityCheck = "0123456789".split( "" ).reduce(function( object, digit ) {
+ object[ digit ] = "invalid";
+ return object;
+ }, {} );
+ invertedNuDigitsMap = objectExtend(
+ invertedNuDigitsMapSanityCheck,
+ invertedNuDigitsMap
+ );
+ }
+
+ // 0: @infinitySymbol [String] Infinity symbol.
+ // 1: @invertedSymbolMap [Object] Inverted symbol map augmented with sanity check.
+ // The sanity check prevents permissive parsing, i.e., it prevents symbols that doesn't
+ // belong to the localized set to pass through. This is obtained with the result of the
+ // inverted map object overloading symbol name map object (the remaining symbol name
+ // mappings will invalidate parsing, working as the sanity check).
+ // 2: @negativePrefix [String] Negative prefix.
+ // 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out.
+ // 4: @invertedNuDigitsMap [Object] Inverted digits map if numbering system is different than
+ // `latn` augmented with sanity check (similar to invertedSymbolMap).
+ return [
+ numberSymbol( "infinity", cldr ),
+ objectExtend( {}, numberSymbolName, numberSymbolInvertedMap( cldr ) ),
+ negativeProperties[ 0 ],
+ negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" ),
+ invertedNuDigitsMap
+ ];
+};
+
+
+
+
+/**
+ * Pattern( style )
+ *
+ * @style [String] "decimal" (default) or "percent".
+ *
+ * @cldr [Cldr instance].
+ */
+var numberPattern = function( style, cldr ) {
+ if ( style !== "decimal" && style !== "percent" ) {
+ throw new Error( "Invalid style" );
+ }
+
+ return cldr.main([
+ "numbers",
+ style + "Formats-numberSystem-" + numberNumberingSystem( cldr ),
+ "standard"
+ ]);
+};
+
+
+
+
+/**
+ * .numberFormatter( [options] )
+ *
+ * @options [Object]:
+ * - style: [String] "decimal" (default) or "percent".
+ * - see also number/format options.
+ *
+ * Return a function that formats a number according to the given options and default/instance
+ * locale.
+ */
+Globalize.numberFormatter =
+Globalize.prototype.numberFormatter = function( options ) {
+ var cldr, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
+ minimumIntegerDigits, minimumSignificantDigits, pattern, properties;
+
+ validateParameterTypePlainObject( options, "options" );
+
+ options = options || {};
+ cldr = this.cldr;
+
+ validateDefaultLocale( cldr );
+
+ cldr.on( "get", validateCldr );
+
+ if ( options.raw ) {
+ pattern = options.raw;
+ } else {
+ pattern = numberPattern( options.style || "decimal", cldr );
+ }
+
+ properties = numberFormatProperties( pattern, cldr, options );
+
+ cldr.off( "get", validateCldr );
+
+ minimumIntegerDigits = properties[ 2 ];
+ minimumFractionDigits = properties[ 3 ];
+ maximumFractionDigits = properties[ 4 ];
+
+ minimumSignificantDigits = properties[ 5 ];
+ maximumSignificantDigits = properties[ 6 ];
+
+ // Validate significant digit format properties
+ if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
+ validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 );
+ validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits",
+ minimumSignificantDigits, 21 );
+
+ } else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) {
+ throw new Error( "Neither or both the minimum and maximum significant digits must be " +
+ "present" );
+
+ // Validate integer and fractional format
+ } else {
+ validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 );
+ validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 );
+ validateParameterRange( maximumFractionDigits, "maximumFractionDigits",
+ minimumFractionDigits, 20 );
+ }
+
+ return function( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeNumber( value, "value" );
+ return numberFormat( value, properties );
+ };
+};
+
+/**
+ * .numberParser( [options] )
+ *
+ * @options [Object]:
+ * - style: [String] "decimal" (default) or "percent".
+ *
+ * Return the number parser according to the default/instance locale.
+ */
+Globalize.numberParser =
+Globalize.prototype.numberParser = function( options ) {
+ var cldr, pattern, properties;
+
+ validateParameterTypePlainObject( options, "options" );
+
+ options = options || {};
+ cldr = this.cldr;
+
+ validateDefaultLocale( cldr );
+
+ cldr.on( "get", validateCldr );
+
+ if ( options.raw ) {
+ pattern = options.raw;
+ } else {
+ pattern = numberPattern( options.style || "decimal", cldr );
+ }
+
+ properties = numberParseProperties( pattern, cldr );
+
+ cldr.off( "get", validateCldr );
+
+ return function( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+ return numberParse( value, properties );
+ };
+};
+
+/**
+ * .formatNumber( value [, options] )
+ *
+ * @value [Number] number to be formatted.
+ *
+ * @options [Object]: see number/format-properties.
+ *
+ * Format a number according to the given options and default/instance locale.
+ */
+Globalize.formatNumber =
+Globalize.prototype.formatNumber = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeNumber( value, "value" );
+
+ return this.numberFormatter( options )( value );
+};
+
+/**
+ * .parseNumber( value [, options] )
+ *
+ * @value [String]
+ *
+ * @options [Object]: See numberParser().
+ *
+ * Return the parsed Number (including Infinity) or NaN when value is invalid.
+ */
+Globalize.parseNumber =
+Globalize.prototype.parseNumber = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ return this.numberParser( options )( value );
+};
+
+/**
+ * Optimization to avoid duplicating some internal functions across modules.
+ */
+Globalize._createErrorUnsupportedFeature = createErrorUnsupportedFeature;
+Globalize._numberNumberingSystem = numberNumberingSystem;
+Globalize._numberPattern = numberPattern;
+Globalize._numberSymbol = numberSymbol;
+Globalize._stringPad = stringPad;
+Globalize._validateParameterTypeNumber = validateParameterTypeNumber;
+Globalize._validateParameterTypeString = validateParameterTypeString;
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/localization.js b/external/localization.js
new file mode 100644
index 000000000..2879601f8
--- /dev/null
+++ b/external/localization.js
@@ -0,0 +1,5357 @@
+/**
+ * CLDR data
+ */
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "globalize"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( Globalize );
+ }
+}( function( Globalize ) {
+
+Globalize.load({
+ "main": {
+ "ar": {
+ "identity": {
+ "version": {
+ "_cldrVersion": "27.0.1",
+ "_number": "$Revision: 11294 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $"
+ },
+ "language": "ar"
+ },
+ "dates": {
+ "calendars": {
+ "gregorian": {
+ "months": {
+ "format": {
+ "abbreviated": {
+ "1": "يناير",
+ "2": "فبراير",
+ "3": "مارس",
+ "4": "أبريل",
+ "5": "مايو",
+ "6": "يونيو",
+ "7": "يوليو",
+ "8": "أغسطس",
+ "9": "سبتمبر",
+ "10": "أكتوبر",
+ "11": "نوفمبر",
+ "12": "ديسمبر"
+ },
+ "narrow": {
+ "1": "ي",
+ "2": "ف",
+ "3": "م",
+ "4": "أ",
+ "5": "و",
+ "6": "ن",
+ "7": "ل",
+ "8": "غ",
+ "9": "س",
+ "10": "ك",
+ "11": "ب",
+ "12": "د"
+ },
+ "wide": {
+ "1": "يناير",
+ "2": "فبراير",
+ "3": "مارس",
+ "4": "أبريل",
+ "5": "مايو",
+ "6": "يونيو",
+ "7": "يوليو",
+ "8": "أغسطس",
+ "9": "سبتمبر",
+ "10": "أكتوبر",
+ "11": "نوفمبر",
+ "12": "ديسمبر"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "يناير",
+ "2": "فبراير",
+ "3": "مارس",
+ "4": "أبريل",
+ "5": "مايو",
+ "6": "يونيو",
+ "7": "يوليو",
+ "8": "أغسطس",
+ "9": "سبتمبر",
+ "10": "أكتوبر",
+ "11": "نوفمبر",
+ "12": "ديسمبر"
+ },
+ "narrow": {
+ "1": "ي",
+ "2": "ف",
+ "3": "م",
+ "4": "أ",
+ "5": "و",
+ "6": "ن",
+ "7": "ل",
+ "8": "غ",
+ "9": "س",
+ "10": "ك",
+ "11": "ب",
+ "12": "د"
+ },
+ "wide": {
+ "1": "يناير",
+ "2": "فبراير",
+ "3": "مارس",
+ "4": "أبريل",
+ "5": "مايو",
+ "6": "يونيو",
+ "7": "يوليو",
+ "8": "أغسطس",
+ "9": "سبتمبر",
+ "10": "أكتوبر",
+ "11": "نوفمبر",
+ "12": "ديسمبر"
+ }
+ }
+ },
+ "days": {
+ "format": {
+ "abbreviated": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ },
+ "narrow": {
+ "sun": "ح",
+ "mon": "ن",
+ "tue": "ث",
+ "wed": "ر",
+ "thu": "خ",
+ "fri": "ج",
+ "sat": "س"
+ },
+ "short": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ },
+ "wide": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ },
+ "narrow": {
+ "sun": "ح",
+ "mon": "ن",
+ "tue": "ث",
+ "wed": "ر",
+ "thu": "خ",
+ "fri": "ج",
+ "sat": "س"
+ },
+ "short": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ },
+ "wide": {
+ "sun": "الأحد",
+ "mon": "الاثنين",
+ "tue": "الثلاثاء",
+ "wed": "الأربعاء",
+ "thu": "الخميس",
+ "fri": "الجمعة",
+ "sat": "السبت"
+ }
+ }
+ },
+ "quarters": {
+ "format": {
+ "abbreviated": {
+ "1": "الربع الأول",
+ "2": "الربع الثاني",
+ "3": "الربع الثالث",
+ "4": "الربع الرابع"
+ },
+ "narrow": {
+ "1": "١",
+ "2": "٢",
+ "3": "٣",
+ "4": "٤"
+ },
+ "wide": {
+ "1": "الربع الأول",
+ "2": "الربع الثاني",
+ "3": "الربع الثالث",
+ "4": "الربع الرابع"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "الربع الأول",
+ "2": "الربع الثاني",
+ "3": "الربع الثالث",
+ "4": "الربع الرابع"
+ },
+ "narrow": {
+ "1": "١",
+ "2": "٢",
+ "3": "٣",
+ "4": "٤"
+ },
+ "wide": {
+ "1": "الربع الأول",
+ "2": "الربع الثاني",
+ "3": "الربع الثالث",
+ "4": "الربع الرابع"
+ }
+ }
+ },
+ "dayPeriods": {
+ "format": {
+ "abbreviated": {
+ "am": "ص",
+ "noon": "ظهرا",
+ "pm": "م"
+ },
+ "narrow": {
+ "am": "ص",
+ "noon": "ظ",
+ "pm": "م"
+ },
+ "wide": {
+ "am": "ص",
+ "noon": "ظهرا",
+ "pm": "م"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "am": "ص",
+ "noon": "ظهرا",
+ "pm": "م"
+ },
+ "narrow": {
+ "am": "ص",
+ "noon": "ظ",
+ "pm": "م"
+ },
+ "wide": {
+ "am": "ص",
+ "noon": "ظهرا",
+ "pm": "م"
+ }
+ }
+ },
+ "eras": {
+ "eraNames": {
+ "0": "قبل الميلاد",
+ "0-alt-variant": "BCE",
+ "1": "ميلادي",
+ "1-alt-variant": "بعد الميلاد"
+ },
+ "eraAbbr": {
+ "0": "ق.م",
+ "0-alt-variant": "BCE",
+ "1": "م",
+ "1-alt-variant": "ب.م"
+ },
+ "eraNarrow": {
+ "0": "ق.م",
+ "0-alt-variant": "BCE",
+ "1": "م",
+ "1-alt-variant": "ب.م"
+ }
+ },
+ "dateFormats": {
+ "full": "EEEE، d MMMM، y",
+ "long": "d MMMM، y",
+ "medium": "dd‏/MM‏/y",
+ "short": "d‏/M‏/y"
+ },
+ "timeFormats": {
+ "full": "h:mm:ss a zzzz",
+ "long": "h:mm:ss a z",
+ "medium": "h:mm:ss a",
+ "short": "h:mm a"
+ },
+ "dateTimeFormats": {
+ "full": "{1} {0}",
+ "long": "{1} {0}",
+ "medium": "{1} {0}",
+ "short": "{1} {0}",
+ "availableFormats": {
+ "E": "ccc",
+ "EHm": "E HH:mm",
+ "EHms": "E HH:mm:ss",
+ "Ed": "E، d",
+ "Ehm": "E h:mm a",
+ "Ehms": "E h:mm:ss a",
+ "Gy": "y G",
+ "GyMMM": "MMM y G",
+ "GyMMMEd": "E، d MMM، y G",
+ "GyMMMd": "d MMM، y G",
+ "H": "HH",
+ "Hm": "HH:mm",
+ "Hms": "HH:mm:ss",
+ "Hmsv": "HH:mm:ss v",
+ "Hmv": "HH:mm v",
+ "M": "L",
+ "MEd": "E، d/M",
+ "MMM": "LLL",
+ "MMMEd": "E، d MMM",
+ "MMMMEd": "E، d MMMM",
+ "MMMMd": "d MMMM",
+ "MMMd": "d MMM",
+ "MMdd": "dd‏/MM",
+ "Md": "d/‏M",
+ "d": "d",
+ "h": "h a",
+ "hm": "h:mm a",
+ "hms": "h:mm:ss a",
+ "hmsv": "h:mm:ss a v",
+ "hmv": "h:mm a v",
+ "ms": "mm:ss",
+ "y": "y",
+ "yM": "M‏/y",
+ "yMEd": "E، d/‏M/‏y",
+ "yMM": "MM‏/y",
+ "yMMM": "MMM y",
+ "yMMMEd": "E، d MMM، y",
+ "yMMMM": "MMMM y",
+ "yMMMd": "d MMM، y",
+ "yMd": "d‏/M‏/y",
+ "yQQQ": "QQQ y",
+ "yQQQQ": "QQQQ y"
+ },
+ "appendItems": {
+ "Day": "{0} ({2}: {1})",
+ "Day-Of-Week": "{0} {1}",
+ "Era": "{1} {0}",
+ "Hour": "{0} ({2}: {1})",
+ "Minute": "{0} ({2}: {1})",
+ "Month": "{0} ({2}: {1})",
+ "Quarter": "{0} ({2}: {1})",
+ "Second": "{0} ({2}: {1})",
+ "Timezone": "{0} {1}",
+ "Week": "{0} ({2}: {1})",
+ "Year": "{1} {0}"
+ },
+ "intervalFormats": {
+ "intervalFormatFallback": "{0} – {1}",
+ "H": {
+ "H": "HH–HH"
+ },
+ "Hm": {
+ "H": "HH:mm–HH:mm",
+ "m": "HH:mm–HH:mm"
+ },
+ "Hmv": {
+ "H": "HH:mm–HH:mm v",
+ "m": "HH:mm–HH:mm v"
+ },
+ "Hv": {
+ "H": "HH–HH v"
+ },
+ "M": {
+ "M": "M–M"
+ },
+ "MEd": {
+ "M": "E، d/‏M – E، d/‏M",
+ "d": "E، d/‏M –‏ E، d/‏M"
+ },
+ "MMM": {
+ "M": "MMM–MMM"
+ },
+ "MMMEd": {
+ "M": "E، d MMM – E، d MMM",
+ "d": "E، d – E، d MMM"
+ },
+ "MMMM": {
+ "M": "LLLL–LLLL"
+ },
+ "MMMd": {
+ "M": "d MMM – d MMM",
+ "d": "d–d MMM"
+ },
+ "Md": {
+ "M": "M/d – M/d",
+ "d": "M/d – M/d"
+ },
+ "d": {
+ "d": "d–d"
+ },
+ "h": {
+ "a": "h a – h a",
+ "h": "h–h a"
+ },
+ "hm": {
+ "a": "h:mm a – h:mm a",
+ "h": "h:mm–h:mm a",
+ "m": "h:mm–h:mm a"
+ },
+ "hmv": {
+ "a": "h:mm a – h:mm a v",
+ "h": "h:mm–h:mm a v",
+ "m": "h:mm–h:mm a v"
+ },
+ "hv": {
+ "a": "h a – h a v",
+ "h": "h–h a v"
+ },
+ "y": {
+ "y": "y–y"
+ },
+ "yM": {
+ "M": "M‏/y – M‏/y",
+ "y": "M‏/y – M‏/y"
+ },
+ "yMEd": {
+ "M": "E، d‏/M‏/y – E، d‏/M‏/y",
+ "d": "E، dd‏/MM‏/y – E، dd‏/MM‏/y",
+ "y": "E، d‏/M‏/y – E، d‏/M‏/y"
+ },
+ "yMMM": {
+ "M": "MMM – MMM، y",
+ "y": "MMM، y – MMM، y"
+ },
+ "yMMMEd": {
+ "M": "E، d MMM – E، d MMM، y",
+ "d": "E، d – E، d MMM، y",
+ "y": "E، d MMM، y – E، d MMM، y"
+ },
+ "yMMMM": {
+ "M": "MMMM – MMMM، y",
+ "y": "MMMM، y – MMMM، y"
+ },
+ "yMMMd": {
+ "M": "d MMM – d MMM، y",
+ "d": "d–d MMM، y",
+ "y": "d MMM، y – d MMM، y"
+ },
+ "yMd": {
+ "M": "d‏/M‏/y – d‏/M‏/y",
+ "d": "d‏/M‏/y – d‏/M‏/y",
+ "y": "d‏/M‏/y – d‏/M‏/y"
+ }
+ }
+ }
+ }
+ }
+ },
+ "numbers": {
+ "defaultNumberingSystem": "arab",
+ "otherNumberingSystems": {
+ "native": "arab"
+ },
+ "minimumGroupingDigits": "1",
+ "symbols-numberSystem-arab": {
+ "decimal": "٫",
+ "group": "٬",
+ "list": "؛",
+ "percentSign": "٪",
+ "plusSign": "‏+",
+ "minusSign": "‏-",
+ "exponential": "اس",
+ "superscriptingExponent": "×",
+ "perMille": "؉",
+ "infinity": "∞",
+ "nan": "ليس رقم",
+ "timeSeparator": "،"
+ },
+ "symbols-numberSystem-latn": {
+ "decimal": ".",
+ "group": ",",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "‎+",
+ "minusSign": "‎-",
+ "exponential": "E",
+ "superscriptingExponent": "×",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "decimalFormats-numberSystem-arab": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-zero": "0 ألف",
+ "1000-count-one": "0 ألف",
+ "1000-count-two": "0 ألف",
+ "1000-count-few": "0 ألف",
+ "1000-count-many": "0 ألف",
+ "1000-count-other": "0 ألف",
+ "10000-count-zero": "00 ألف",
+ "10000-count-one": "00 ألف",
+ "10000-count-two": "00 ألف",
+ "10000-count-few": "00 ألف",
+ "10000-count-many": "00 ألف",
+ "10000-count-other": "00 ألف",
+ "100000-count-zero": "000 ألف",
+ "100000-count-one": "000 ألف",
+ "100000-count-two": "000 ألف",
+ "100000-count-few": "000 ألف",
+ "100000-count-many": "000 ألف",
+ "100000-count-other": "000 ألف",
+ "1000000-count-zero": "0 مليون",
+ "1000000-count-one": "0 مليون",
+ "1000000-count-two": "0 مليون",
+ "1000000-count-few": "0 مليون",
+ "1000000-count-many": "0 مليون",
+ "1000000-count-other": "0 مليون",
+ "10000000-count-zero": "00 مليون",
+ "10000000-count-one": "00 مليون",
+ "10000000-count-two": "00 مليون",
+ "10000000-count-few": "00 مليون",
+ "10000000-count-many": "00 مليون",
+ "10000000-count-other": "00 مليون",
+ "100000000-count-zero": "000 مليون",
+ "100000000-count-one": "000 مليون",
+ "100000000-count-two": "000 مليون",
+ "100000000-count-few": "000 مليون",
+ "100000000-count-many": "000 مليون",
+ "100000000-count-other": "000 مليون",
+ "1000000000-count-zero": "0 بليون",
+ "1000000000-count-one": "0 بليون",
+ "1000000000-count-two": "0 بليون",
+ "1000000000-count-few": "0 بليون",
+ "1000000000-count-many": "0 بليون",
+ "1000000000-count-other": "0 بليون",
+ "10000000000-count-zero": "00 بليون",
+ "10000000000-count-one": "00 بليون",
+ "10000000000-count-two": "00 بليون",
+ "10000000000-count-few": "00 بليون",
+ "10000000000-count-many": "00 بليون",
+ "10000000000-count-other": "00 بليون",
+ "100000000000-count-zero": "000 بليون",
+ "100000000000-count-one": "000 بليون",
+ "100000000000-count-two": "000 بليون",
+ "100000000000-count-few": "000 بليون",
+ "100000000000-count-many": "000 بليون",
+ "100000000000-count-other": "000 بليون",
+ "1000000000000-count-zero": "0 تريليون",
+ "1000000000000-count-one": "0 تريليون",
+ "1000000000000-count-two": "0 تريليون",
+ "1000000000000-count-few": "0 تريليون",
+ "1000000000000-count-many": "0 تريليون",
+ "1000000000000-count-other": "0 تريليون",
+ "10000000000000-count-zero": "00 تريليون",
+ "10000000000000-count-one": "00 تريليون",
+ "10000000000000-count-two": "00 تريليون",
+ "10000000000000-count-few": "00 تريليون",
+ "10000000000000-count-many": "00 تريليون",
+ "10000000000000-count-other": "00 تريليون",
+ "100000000000000-count-zero": "000 تريليون",
+ "100000000000000-count-one": "000 تريليون",
+ "100000000000000-count-two": "000 تريليون",
+ "100000000000000-count-few": "000 تريليون",
+ "100000000000000-count-many": "000 تريليون",
+ "100000000000000-count-other": "000 تريليون"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-zero": "0 ألف",
+ "1000-count-one": "0 ألف",
+ "1000-count-two": "0 ألف",
+ "1000-count-few": "0 ألف",
+ "1000-count-many": "0 ألف",
+ "1000-count-other": "0 ألف",
+ "10000-count-zero": "00 ألف",
+ "10000-count-one": "00 ألف",
+ "10000-count-two": "00 ألف",
+ "10000-count-few": "00 ألف",
+ "10000-count-many": "00 ألف",
+ "10000-count-other": "00 ألف",
+ "100000-count-zero": "000 ألف",
+ "100000-count-one": "000 ألف",
+ "100000-count-two": "000 ألف",
+ "100000-count-few": "000 ألف",
+ "100000-count-many": "000 ألف",
+ "100000-count-other": "000 ألف",
+ "1000000-count-zero": "0 مليو",
+ "1000000-count-one": "0 مليو",
+ "1000000-count-two": "0 مليو",
+ "1000000-count-few": "0 مليو",
+ "1000000-count-many": "0 مليو",
+ "1000000-count-other": "0 مليو",
+ "10000000-count-zero": "00 مليو",
+ "10000000-count-one": "00 مليو",
+ "10000000-count-two": "00 مليو",
+ "10000000-count-few": "00 مليو",
+ "10000000-count-many": "00 مليو",
+ "10000000-count-other": "00 مليو",
+ "100000000-count-zero": "000 مليو",
+ "100000000-count-one": "000 مليو",
+ "100000000-count-two": "000 مليو",
+ "100000000-count-few": "000 مليو",
+ "100000000-count-many": "000 مليو",
+ "100000000-count-other": "000 مليو",
+ "1000000000-count-zero": "0 بليو",
+ "1000000000-count-one": "0 بليو",
+ "1000000000-count-two": "0 بليو",
+ "1000000000-count-few": "0 بليو",
+ "1000000000-count-many": "0 بليو",
+ "1000000000-count-other": "0 بليو",
+ "10000000000-count-zero": "00 بليو",
+ "10000000000-count-one": "00 بليو",
+ "10000000000-count-two": "00 بليو",
+ "10000000000-count-few": "00 بليو",
+ "10000000000-count-many": "00 بليو",
+ "10000000000-count-other": "00 بليو",
+ "100000000000-count-zero": "000 بليو",
+ "100000000000-count-one": "000 بليو",
+ "100000000000-count-two": "000 بليو",
+ "100000000000-count-few": "000 بليو",
+ "100000000000-count-many": "000 بليو",
+ "100000000000-count-other": "000 بليو",
+ "1000000000000-count-zero": "0 ترليو",
+ "1000000000000-count-one": "0 ترليو",
+ "1000000000000-count-two": "0 ترليو",
+ "1000000000000-count-few": "0 ترليو",
+ "1000000000000-count-many": "0 ترليو",
+ "1000000000000-count-other": "0 ترليو",
+ "10000000000000-count-zero": "00 ترليو",
+ "10000000000000-count-one": "00 ترليو",
+ "10000000000000-count-two": "00 ترليو",
+ "10000000000000-count-few": "00 ترليو",
+ "10000000000000-count-many": "00 ترليو",
+ "10000000000000-count-other": "00 ترليو",
+ "100000000000000-count-zero": "000 ترليو",
+ "100000000000000-count-one": "000 ترليو",
+ "100000000000000-count-two": "000 ترليو",
+ "100000000000000-count-few": "000 ترليو",
+ "100000000000000-count-many": "000 ترليو",
+ "100000000000000-count-other": "000 ترليو"
+ }
+ }
+ },
+ "decimalFormats-numberSystem-latn": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-zero": "0 ألف",
+ "1000-count-one": "0 ألف",
+ "1000-count-two": "0 ألف",
+ "1000-count-few": "0 آلاف",
+ "1000-count-many": "0 ألف",
+ "1000-count-other": "0 ألف",
+ "10000-count-zero": "00 ألف",
+ "10000-count-one": "00 ألف",
+ "10000-count-two": "00 ألف",
+ "10000-count-few": "00 ألف",
+ "10000-count-many": "00 ألف",
+ "10000-count-other": "00 ألف",
+ "100000-count-zero": "000 ألف",
+ "100000-count-one": "000 ألف",
+ "100000-count-two": "000 ألف",
+ "100000-count-few": "000 ألف",
+ "100000-count-many": "000 ألف",
+ "100000-count-other": "000 ألف",
+ "1000000-count-zero": "0 مليون",
+ "1000000-count-one": "0 مليون",
+ "1000000-count-two": "0 مليون",
+ "1000000-count-few": "0 ملايين",
+ "1000000-count-many": "0 مليون",
+ "1000000-count-other": "0 مليون",
+ "10000000-count-zero": "00 مليون",
+ "10000000-count-one": "00 مليون",
+ "10000000-count-two": "00 مليون",
+ "10000000-count-few": "00 ملايين",
+ "10000000-count-many": "00 مليون",
+ "10000000-count-other": "00 مليون",
+ "100000000-count-zero": "000 مليون",
+ "100000000-count-one": "000 مليون",
+ "100000000-count-two": "000 مليون",
+ "100000000-count-few": "000 مليون",
+ "100000000-count-many": "000 مليون",
+ "100000000-count-other": "000 مليون",
+ "1000000000-count-zero": "0 بليون",
+ "1000000000-count-one": "0 بليون",
+ "1000000000-count-two": "0 بليون",
+ "1000000000-count-few": "0 بلايين",
+ "1000000000-count-many": "0 بليون",
+ "1000000000-count-other": "0 بليون",
+ "10000000000-count-zero": "00 بليون",
+ "10000000000-count-one": "00 بليون",
+ "10000000000-count-two": "00 بليون",
+ "10000000000-count-few": "00 بليون",
+ "10000000000-count-many": "00 بليون",
+ "10000000000-count-other": "00 بليون",
+ "100000000000-count-zero": "000 بليون",
+ "100000000000-count-one": "000 بليون",
+ "100000000000-count-two": "000 بليون",
+ "100000000000-count-few": "000 بليون",
+ "100000000000-count-many": "000 بليون",
+ "100000000000-count-other": "000 بليون",
+ "1000000000000-count-zero": "0 تريليون",
+ "1000000000000-count-one": "0 تريليون",
+ "1000000000000-count-two": "0 تريليون",
+ "1000000000000-count-few": "0 تريليونات",
+ "1000000000000-count-many": "0 تريليون",
+ "1000000000000-count-other": "0 تريليون",
+ "10000000000000-count-zero": "00 تريليون",
+ "10000000000000-count-one": "00 تريليون",
+ "10000000000000-count-two": "00 تريليون",
+ "10000000000000-count-few": "00 تريليون",
+ "10000000000000-count-many": "00 تريليون",
+ "10000000000000-count-other": "00 تريليون",
+ "100000000000000-count-zero": "000 تريليون",
+ "100000000000000-count-one": "000 تريليون",
+ "100000000000000-count-two": "000 تريليون",
+ "100000000000000-count-few": "000 تريليون",
+ "100000000000000-count-many": "000 تريليون",
+ "100000000000000-count-other": "000 تريليون"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-zero": "0 ألف",
+ "1000-count-one": "0 ألف",
+ "1000-count-two": "0 ألف",
+ "1000-count-few": "0 آلاف",
+ "1000-count-many": "0 ألف",
+ "1000-count-other": "0 ألف",
+ "10000-count-zero": "00 ألف",
+ "10000-count-one": "00 ألف",
+ "10000-count-two": "00 ألف",
+ "10000-count-few": "00 ألف",
+ "10000-count-many": "00 ألف",
+ "10000-count-other": "00 ألف",
+ "100000-count-zero": "000 ألف",
+ "100000-count-one": "000 ألف",
+ "100000-count-two": "000 ألف",
+ "100000-count-few": "000 ألف",
+ "100000-count-many": "000 ألف",
+ "100000-count-other": "000 ألف",
+ "1000000-count-zero": "0 مليو",
+ "1000000-count-one": "0 مليو",
+ "1000000-count-two": "0 مليو",
+ "1000000-count-few": "0 مليو",
+ "1000000-count-many": "0 مليو",
+ "1000000-count-other": "0 مليو",
+ "10000000-count-zero": "00 مليو",
+ "10000000-count-one": "00 مليو",
+ "10000000-count-two": "00 مليو",
+ "10000000-count-few": "00 مليو",
+ "10000000-count-many": "00 مليو",
+ "10000000-count-other": "00 مليو",
+ "100000000-count-zero": "000 مليو",
+ "100000000-count-one": "000 مليو",
+ "100000000-count-two": "000 مليو",
+ "100000000-count-few": "000 مليو",
+ "100000000-count-many": "000 مليو",
+ "100000000-count-other": "000 مليو",
+ "1000000000-count-zero": "0 بليو",
+ "1000000000-count-one": "0 بليو",
+ "1000000000-count-two": "0 بليو",
+ "1000000000-count-few": "0 بليو",
+ "1000000000-count-many": "0 بليو",
+ "1000000000-count-other": "0 بليو",
+ "10000000000-count-zero": "00 بليو",
+ "10000000000-count-one": "00 بليو",
+ "10000000000-count-two": "00 بليو",
+ "10000000000-count-few": "00 بليو",
+ "10000000000-count-many": "00 بليو",
+ "10000000000-count-other": "00 بليو",
+ "100000000000-count-zero": "000 بليو",
+ "100000000000-count-one": "000 بليو",
+ "100000000000-count-two": "000 بليو",
+ "100000000000-count-few": "000 بليو",
+ "100000000000-count-many": "000 بليو",
+ "100000000000-count-other": "000 بليو",
+ "1000000000000-count-zero": "0 ترليو",
+ "1000000000000-count-one": "0 ترليو",
+ "1000000000000-count-two": "0 ترليو",
+ "1000000000000-count-few": "0 ترليو",
+ "1000000000000-count-many": "0 ترليو",
+ "1000000000000-count-other": "0 ترليو",
+ "10000000000000-count-zero": "00 ترليو",
+ "10000000000000-count-one": "00 ترليو",
+ "10000000000000-count-two": "00 ترليو",
+ "10000000000000-count-few": "00 ترليو",
+ "10000000000000-count-many": "00 ترليو",
+ "10000000000000-count-other": "00 ترليو",
+ "100000000000000-count-zero": "000 ترليو",
+ "100000000000000-count-one": "000 ترليو",
+ "100000000000000-count-two": "000 ترليو",
+ "100000000000000-count-few": "000 ترليو",
+ "100000000000000-count-many": "000 ترليو",
+ "100000000000000-count-other": "000 ترليو"
+ }
+ }
+ },
+ "scientificFormats-numberSystem-arab": {
+ "standard": "#E0"
+ },
+ "scientificFormats-numberSystem-latn": {
+ "standard": "#E0"
+ },
+ "percentFormats-numberSystem-arab": {
+ "standard": "#,##0%"
+ },
+ "percentFormats-numberSystem-latn": {
+ "standard": "#,##0%"
+ },
+ "currencyFormats-numberSystem-arab": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "¤#,##0.00;(¤#,##0.00)",
+ "standard": "¤ #,##0.00",
+ "unitPattern-count-zero": "{0} {1}",
+ "unitPattern-count-one": "{0} {1}",
+ "unitPattern-count-two": "{0} {1}",
+ "unitPattern-count-few": "{0} {1}",
+ "unitPattern-count-many": "{0} {1}",
+ "unitPattern-count-other": "{0} {1}"
+ },
+ "currencyFormats-numberSystem-latn": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "¤#,##0.00;(¤#,##0.00)",
+ "standard": "¤ #,##0.00",
+ "unitPattern-count-zero": "{0} {1}",
+ "unitPattern-count-one": "{0} {1}",
+ "unitPattern-count-two": "{0} {1}",
+ "unitPattern-count-few": "{0} {1}",
+ "unitPattern-count-many": "{0} {1}",
+ "unitPattern-count-other": "{0} {1}"
+ },
+ "miscPatterns-numberSystem-arab": {
+ "atLeast": "+{0}",
+ "range": "{0}–{1}"
+ },
+ "miscPatterns-numberSystem-latn": {
+ "atLeast": "+{0}",
+ "range": "{0}–{1}"
+ }
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "main": {
+ "es": {
+ "identity": {
+ "version": {
+ "_cldrVersion": "27.0.1",
+ "_number": "$Revision: 11321 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-26 14:20:05 -0600 (Thu, 26 Feb 2015) $"
+ },
+ "language": "es"
+ },
+ "dates": {
+ "calendars": {
+ "gregorian": {
+ "months": {
+ "format": {
+ "abbreviated": {
+ "1": "ene.",
+ "2": "feb.",
+ "3": "mar.",
+ "4": "abr.",
+ "5": "may.",
+ "6": "jun.",
+ "7": "jul.",
+ "8": "ago.",
+ "9": "sept.",
+ "10": "oct.",
+ "11": "nov.",
+ "12": "dic."
+ },
+ "narrow": {
+ "1": "E",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "enero",
+ "2": "febrero",
+ "3": "marzo",
+ "4": "abril",
+ "5": "mayo",
+ "6": "junio",
+ "7": "julio",
+ "8": "agosto",
+ "9": "septiembre",
+ "10": "octubre",
+ "11": "noviembre",
+ "12": "diciembre"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "Ene.",
+ "2": "Feb.",
+ "3": "Mar.",
+ "4": "Abr.",
+ "5": "May.",
+ "6": "Jun.",
+ "7": "Jul.",
+ "8": "Ago.",
+ "9": "Sept.",
+ "10": "Oct.",
+ "11": "Nov.",
+ "12": "Dic."
+ },
+ "narrow": {
+ "1": "E",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "Enero",
+ "2": "Febrero",
+ "3": "Marzo",
+ "4": "Abril",
+ "5": "Mayo",
+ "6": "Junio",
+ "7": "Julio",
+ "8": "Agosto",
+ "9": "Septiembre",
+ "10": "Octubre",
+ "11": "Noviembre",
+ "12": "Diciembre"
+ }
+ }
+ },
+ "days": {
+ "format": {
+ "abbreviated": {
+ "sun": "dom.",
+ "mon": "lun.",
+ "tue": "mar.",
+ "wed": "mié.",
+ "thu": "jue.",
+ "fri": "vie.",
+ "sat": "sáb."
+ },
+ "narrow": {
+ "sun": "D",
+ "mon": "L",
+ "tue": "M",
+ "wed": "X",
+ "thu": "J",
+ "fri": "V",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "DO",
+ "mon": "LU",
+ "tue": "MA",
+ "wed": "MI",
+ "thu": "JU",
+ "fri": "VI",
+ "sat": "SA"
+ },
+ "wide": {
+ "sun": "domingo",
+ "mon": "lunes",
+ "tue": "martes",
+ "wed": "miércoles",
+ "thu": "jueves",
+ "fri": "viernes",
+ "sat": "sábado"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "sun": "Dom.",
+ "mon": "Lun.",
+ "tue": "Mar.",
+ "wed": "Mié.",
+ "thu": "Jue.",
+ "fri": "Vie.",
+ "sat": "Sáb."
+ },
+ "narrow": {
+ "sun": "D",
+ "mon": "L",
+ "tue": "M",
+ "wed": "X",
+ "thu": "J",
+ "fri": "V",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "DO",
+ "mon": "LU",
+ "tue": "MA",
+ "wed": "MI",
+ "thu": "JU",
+ "fri": "VI",
+ "sat": "SA"
+ },
+ "wide": {
+ "sun": "Domingo",
+ "mon": "Lunes",
+ "tue": "Martes",
+ "wed": "Miércoles",
+ "thu": "Jueves",
+ "fri": "Viernes",
+ "sat": "Sábado"
+ }
+ }
+ },
+ "quarters": {
+ "format": {
+ "abbreviated": {
+ "1": "T1",
+ "2": "T2",
+ "3": "T3",
+ "4": "T4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1.er trimestre",
+ "2": "2.º trimestre",
+ "3": "3.er trimestre",
+ "4": "4.º trimestre"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "T1",
+ "2": "T2",
+ "3": "T3",
+ "4": "T4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1.er trimestre",
+ "2": "2.º trimestre",
+ "3": "3.er trimestre",
+ "4": "4.º trimestre"
+ }
+ }
+ },
+ "dayPeriods": {
+ "format": {
+ "abbreviated": {
+ "am": "a. m.",
+ "noon": "mediodía",
+ "pm": "p. m."
+ },
+ "narrow": {
+ "am": "a.m.",
+ "noon": "m.",
+ "pm": "p.m."
+ },
+ "wide": {
+ "am": "a. m.",
+ "noon": "mediodía",
+ "pm": "p. m."
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "am": "a. m.",
+ "noon": "mediodía",
+ "pm": "p. m."
+ },
+ "narrow": {
+ "am": "a.m.",
+ "noon": "m.",
+ "pm": "p.m."
+ },
+ "wide": {
+ "am": "a. m.",
+ "noon": "mediodía",
+ "pm": "p. m."
+ }
+ }
+ },
+ "eras": {
+ "eraNames": {
+ "0": "antes de Cristo",
+ "0-alt-variant": "antes de la era común",
+ "1": "después de Cristo",
+ "1-alt-variant": "era común"
+ },
+ "eraAbbr": {
+ "0": "a. C.",
+ "0-alt-variant": "a. e. c.",
+ "1": "d. C.",
+ "1-alt-variant": "e. c."
+ },
+ "eraNarrow": {
+ "0": "a. C.",
+ "0-alt-variant": "a. e. c.",
+ "1": "d. C.",
+ "1-alt-variant": "e. c."
+ }
+ },
+ "dateFormats": {
+ "full": "EEEE, d 'de' MMMM 'de' y",
+ "long": "d 'de' MMMM 'de' y",
+ "medium": "d MMM y",
+ "short": "d/M/yy"
+ },
+ "timeFormats": {
+ "full": "H:mm:ss (zzzz)",
+ "long": "H:mm:ss z",
+ "medium": "H:mm:ss",
+ "short": "H:mm"
+ },
+ "dateTimeFormats": {
+ "full": "{1}, {0}",
+ "long": "{1}, {0}",
+ "medium": "{1} {0}",
+ "short": "{1} {0}",
+ "availableFormats": {
+ "E": "ccc",
+ "EHm": "E, H:mm",
+ "EHms": "E, H:mm:ss",
+ "Ed": "E d",
+ "Ehm": "E, h:mm a",
+ "Ehms": "E, h:mm:ss a",
+ "Gy": "y G",
+ "GyMMM": "MMM y G",
+ "GyMMMEd": "E, d MMM y G",
+ "GyMMMM": "MMMM 'de' y G",
+ "GyMMMMEd": "E, d 'de' MMMM 'de' y G",
+ "GyMMMMd": "d 'de' MMMM 'de' y G",
+ "GyMMMd": "d MMM y G",
+ "H": "H",
+ "Hm": "H:mm",
+ "Hms": "H:mm:ss",
+ "Hmsv": "H:mm:ss v",
+ "Hmsvvvv": "H:mm:ss (vvvv)",
+ "Hmv": "H:mm v",
+ "M": "L",
+ "MEd": "E, d/M",
+ "MMM": "LLL",
+ "MMMEd": "E, d MMM",
+ "MMMMEd": "E, d 'de' MMMM",
+ "MMMMd": "d 'de' MMMM",
+ "MMMd": "d MMM",
+ "MMd": "d/M",
+ "MMdd": "d/M",
+ "Md": "d/M",
+ "d": "d",
+ "h": "h a",
+ "hm": "h:mm a",
+ "hms": "h:mm:ss a",
+ "hmsv": "h:mm:ss a v",
+ "hmsvvvv": "h:mm:ss a (vvvv)",
+ "hmv": "h:mm a v",
+ "ms": "mm:ss",
+ "y": "y",
+ "yM": "M/y",
+ "yMEd": "EEE, d/M/y",
+ "yMM": "M/y",
+ "yMMM": "MMM y",
+ "yMMMEd": "EEE, d MMM y",
+ "yMMMM": "MMMM 'de' y",
+ "yMMMMEd": "EEE, d 'de' MMMM 'de' y",
+ "yMMMMd": "d 'de' MMMM 'de' y",
+ "yMMMd": "d MMM y",
+ "yMd": "d/M/y",
+ "yQQQ": "QQQ y",
+ "yQQQQ": "QQQQ 'de' y"
+ },
+ "appendItems": {
+ "Day": "{0} ({2}: {1})",
+ "Day-Of-Week": "{0} {1}",
+ "Era": "{1} {0}",
+ "Hour": "{0} ({2}: {1})",
+ "Minute": "{0} ({2}: {1})",
+ "Month": "{0} ({2}: {1})",
+ "Quarter": "{0} ({2}: {1})",
+ "Second": "{0} ({2}: {1})",
+ "Timezone": "{0} {1}",
+ "Week": "{0} ({2}: {1})",
+ "Year": "{1} {0}"
+ },
+ "intervalFormats": {
+ "intervalFormatFallback": "{0}–{1}",
+ "H": {
+ "H": "H–H"
+ },
+ "Hm": {
+ "H": "H:mm–H:mm",
+ "m": "H:mm–H:mm"
+ },
+ "Hmv": {
+ "H": "H:mm–H:mm v",
+ "m": "H:mm–H:mm v"
+ },
+ "Hv": {
+ "H": "H–H v"
+ },
+ "M": {
+ "M": "M–M"
+ },
+ "MEd": {
+ "M": "E, d/M–E, d/M",
+ "d": "E, d/M–E, d/M"
+ },
+ "MMM": {
+ "M": "MMM–MMM"
+ },
+ "MMMEd": {
+ "M": "E, d MMM–E, d MMM",
+ "d": "E, d MMM–E, d MMM"
+ },
+ "MMMMEd": {
+ "M": "E, d 'de' MMMM–E, d 'de' MMMM",
+ "d": "E, d 'de' MMMM–E, d 'de' MMMM"
+ },
+ "MMMMd": {
+ "M": "d 'de' MMMM–d 'de' MMMM",
+ "d": "d–d 'de' MMMM"
+ },
+ "MMMd": {
+ "M": "d MMM–d MMM",
+ "d": "d–d MMM"
+ },
+ "Md": {
+ "M": "d/M–d/M",
+ "d": "d/M–d/M"
+ },
+ "d": {
+ "d": "d–d"
+ },
+ "h": {
+ "a": "h a–h a",
+ "h": "h–h a"
+ },
+ "hm": {
+ "a": "h:mm a – h:mm a",
+ "h": "h:mm – h:mm a",
+ "m": "h:mm – h:mm a"
+ },
+ "hmv": {
+ "a": "h:mm a–h:mm a v",
+ "h": "h:mm–h:mm a v",
+ "m": "h:mm–h:mm a v"
+ },
+ "hv": {
+ "a": "h a–h a v",
+ "h": "h–h a v"
+ },
+ "y": {
+ "y": "y–y"
+ },
+ "yM": {
+ "M": "M/y–M/y",
+ "y": "M/y–M/y"
+ },
+ "yMEd": {
+ "M": "E, d/M/y–E, d/M/y",
+ "d": "E, d/M/y–E, d/M/y",
+ "y": "E, d/M/y–E, d/M/y"
+ },
+ "yMMM": {
+ "M": "MMM–MMM y",
+ "y": "MMM y–MMM y"
+ },
+ "yMMMEd": {
+ "M": "E, d MMM–E, d MMM y",
+ "d": "E, d MMM–E, d MMM y",
+ "y": "E, d MMM y–E, d MMM y"
+ },
+ "yMMMM": {
+ "M": "MMMM–MMMM 'de' y",
+ "y": "MMMM 'de' y–MMMM 'de' y"
+ },
+ "yMMMMEd": {
+ "M": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y",
+ "d": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y",
+ "y": "E, d 'de' MMMM 'de' y–E, d 'de' MMMM 'de' y"
+ },
+ "yMMMMd": {
+ "M": "d 'de' MMMM–d 'de' MMMM 'de' y",
+ "d": "d–d 'de' MMMM 'de' y",
+ "y": "d 'de' MMMM 'de' y–d 'de' MMMM 'de' y"
+ },
+ "yMMMd": {
+ "M": "d MMM–d MMM y",
+ "d": "d–d MMM y",
+ "y": "d MMM y–d MMM y"
+ },
+ "yMd": {
+ "M": "d/M/y–d/M/y",
+ "d": "d/M/y–d/M/y",
+ "y": "d/M/y–d/M/y"
+ }
+ }
+ }
+ }
+ }
+ },
+ "numbers": {
+ "defaultNumberingSystem": "latn",
+ "otherNumberingSystems": {
+ "native": "latn"
+ },
+ "minimumGroupingDigits": "1",
+ "symbols-numberSystem-latn": {
+ "decimal": ",",
+ "group": ".",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "superscriptingExponent": "×",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "decimalFormats-numberSystem-latn": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-one": "0 mil",
+ "1000-count-other": "0 mil",
+ "10000-count-one": "00 mil",
+ "10000-count-other": "00 mil",
+ "100000-count-one": "000 mil",
+ "100000-count-other": "000 mil",
+ "1000000-count-one": "0 millón",
+ "1000000-count-other": "0 millones",
+ "10000000-count-one": "00 millones",
+ "10000000-count-other": "00 millones",
+ "100000000-count-one": "000 millones",
+ "100000000-count-other": "000 millones",
+ "1000000000-count-one": "0 mil millones",
+ "1000000000-count-other": "0 mil millones",
+ "10000000000-count-one": "00 mil millones",
+ "10000000000-count-other": "00 mil millones",
+ "100000000000-count-one": "000 mil millones",
+ "100000000000-count-other": "000 mil millones",
+ "1000000000000-count-one": "0 billón",
+ "1000000000000-count-other": "0 billones",
+ "10000000000000-count-one": "00 billones",
+ "10000000000000-count-other": "00 billones",
+ "100000000000000-count-one": "000 billones",
+ "100000000000000-count-other": "000 billones"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-one": "0 K",
+ "1000-count-other": "0 K",
+ "10000-count-one": "00 K",
+ "10000-count-other": "00 K",
+ "100000-count-one": "000 K",
+ "100000-count-other": "000 K",
+ "1000000-count-one": "0 M",
+ "1000000-count-other": "0 M",
+ "10000000-count-one": "00 M",
+ "10000000-count-other": "00 M",
+ "100000000-count-one": "000 M",
+ "100000000-count-other": "000 M",
+ "1000000000-count-one": "0000 M",
+ "1000000000-count-other": "0000 M",
+ "10000000000-count-one": "00 MRD",
+ "10000000000-count-other": "00 MRD",
+ "100000000000-count-one": "000 MRD",
+ "100000000000-count-other": "000 MRD",
+ "1000000000000-count-one": "0 B",
+ "1000000000000-count-other": "0 B",
+ "10000000000000-count-one": "00 B",
+ "10000000000000-count-other": "00 B",
+ "100000000000000-count-one": "000 B",
+ "100000000000000-count-other": "000 B"
+ }
+ }
+ },
+ "scientificFormats-numberSystem-latn": {
+ "standard": "#E0"
+ },
+ "percentFormats-numberSystem-latn": {
+ "standard": "#,##0 %"
+ },
+ "currencyFormats-numberSystem-latn": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "#,##0.00 ¤",
+ "standard": "#,##0.00 ¤",
+ "unitPattern-count-one": "{0} {1}",
+ "unitPattern-count-other": "{0} {1}"
+ },
+ "miscPatterns-numberSystem-latn": {
+ "atLeast": "Más de {0}",
+ "range": "{0}-{1}"
+ }
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "main": {
+ "en": {
+ "identity": {
+ "version": {
+ "_cldrVersion": "27.0.1",
+ "_number": "$Revision: 11348 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-03-05 01:15:52 -0600 (Thu, 05 Mar 2015) $"
+ },
+ "language": "en"
+ },
+ "numbers": {
+ "defaultNumberingSystem": "latn",
+ "otherNumberingSystems": {
+ "native": "latn"
+ },
+ "minimumGroupingDigits": "1",
+ "symbols-numberSystem-latn": {
+ "decimal": ".",
+ "group": ",",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "superscriptingExponent": "×",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "decimalFormats-numberSystem-latn": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-one": "0 thousand",
+ "1000-count-other": "0 thousand",
+ "10000-count-one": "00 thousand",
+ "10000-count-other": "00 thousand",
+ "100000-count-one": "000 thousand",
+ "100000-count-other": "000 thousand",
+ "1000000-count-one": "0 million",
+ "1000000-count-other": "0 million",
+ "10000000-count-one": "00 million",
+ "10000000-count-other": "00 million",
+ "100000000-count-one": "000 million",
+ "100000000-count-other": "000 million",
+ "1000000000-count-one": "0 billion",
+ "1000000000-count-other": "0 billion",
+ "10000000000-count-one": "00 billion",
+ "10000000000-count-other": "00 billion",
+ "100000000000-count-one": "000 billion",
+ "100000000000-count-other": "000 billion",
+ "1000000000000-count-one": "0 trillion",
+ "1000000000000-count-other": "0 trillion",
+ "10000000000000-count-one": "00 trillion",
+ "10000000000000-count-other": "00 trillion",
+ "100000000000000-count-one": "000 trillion",
+ "100000000000000-count-other": "000 trillion"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-one": "0K",
+ "1000-count-other": "0K",
+ "10000-count-one": "00K",
+ "10000-count-other": "00K",
+ "100000-count-one": "000K",
+ "100000-count-other": "000K",
+ "1000000-count-one": "0M",
+ "1000000-count-other": "0M",
+ "10000000-count-one": "00M",
+ "10000000-count-other": "00M",
+ "100000000-count-one": "000M",
+ "100000000-count-other": "000M",
+ "1000000000-count-one": "0B",
+ "1000000000-count-other": "0B",
+ "10000000000-count-one": "00B",
+ "10000000000-count-other": "00B",
+ "100000000000-count-one": "000B",
+ "100000000000-count-other": "000B",
+ "1000000000000-count-one": "0T",
+ "1000000000000-count-other": "0T",
+ "10000000000000-count-one": "00T",
+ "10000000000000-count-other": "00T",
+ "100000000000000-count-one": "000T",
+ "100000000000000-count-other": "000T"
+ }
+ }
+ },
+ "scientificFormats-numberSystem-latn": {
+ "standard": "#E0"
+ },
+ "percentFormats-numberSystem-latn": {
+ "standard": "#,##0%"
+ },
+ "currencyFormats-numberSystem-latn": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "¤#,##0.00;(¤#,##0.00)",
+ "standard": "¤#,##0.00",
+ "unitPattern-count-one": "{0} {1}",
+ "unitPattern-count-other": "{0} {1}"
+ },
+ "miscPatterns-numberSystem-latn": {
+ "atLeast": "{0}+",
+ "range": "{0}–{1}"
+ }
+ },
+ "dates": {
+ "calendars": {
+ "gregorian": {
+ "months": {
+ "format": {
+ "abbreviated": {
+ "1": "Jan",
+ "2": "Feb",
+ "3": "Mar",
+ "4": "Apr",
+ "5": "May",
+ "6": "Jun",
+ "7": "Jul",
+ "8": "Aug",
+ "9": "Sep",
+ "10": "Oct",
+ "11": "Nov",
+ "12": "Dec"
+ },
+ "narrow": {
+ "1": "J",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "January",
+ "2": "February",
+ "3": "March",
+ "4": "April",
+ "5": "May",
+ "6": "June",
+ "7": "July",
+ "8": "August",
+ "9": "September",
+ "10": "October",
+ "11": "November",
+ "12": "December"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "Jan",
+ "2": "Feb",
+ "3": "Mar",
+ "4": "Apr",
+ "5": "May",
+ "6": "Jun",
+ "7": "Jul",
+ "8": "Aug",
+ "9": "Sep",
+ "10": "Oct",
+ "11": "Nov",
+ "12": "Dec"
+ },
+ "narrow": {
+ "1": "J",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "January",
+ "2": "February",
+ "3": "March",
+ "4": "April",
+ "5": "May",
+ "6": "June",
+ "7": "July",
+ "8": "August",
+ "9": "September",
+ "10": "October",
+ "11": "November",
+ "12": "December"
+ }
+ }
+ },
+ "days": {
+ "format": {
+ "abbreviated": {
+ "sun": "Sun",
+ "mon": "Mon",
+ "tue": "Tue",
+ "wed": "Wed",
+ "thu": "Thu",
+ "fri": "Fri",
+ "sat": "Sat"
+ },
+ "narrow": {
+ "sun": "S",
+ "mon": "M",
+ "tue": "T",
+ "wed": "W",
+ "thu": "T",
+ "fri": "F",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "Su",
+ "mon": "Mo",
+ "tue": "Tu",
+ "wed": "We",
+ "thu": "Th",
+ "fri": "Fr",
+ "sat": "Sa"
+ },
+ "wide": {
+ "sun": "Sunday",
+ "mon": "Monday",
+ "tue": "Tuesday",
+ "wed": "Wednesday",
+ "thu": "Thursday",
+ "fri": "Friday",
+ "sat": "Saturday"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "sun": "Sun",
+ "mon": "Mon",
+ "tue": "Tue",
+ "wed": "Wed",
+ "thu": "Thu",
+ "fri": "Fri",
+ "sat": "Sat"
+ },
+ "narrow": {
+ "sun": "S",
+ "mon": "M",
+ "tue": "T",
+ "wed": "W",
+ "thu": "T",
+ "fri": "F",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "Su",
+ "mon": "Mo",
+ "tue": "Tu",
+ "wed": "We",
+ "thu": "Th",
+ "fri": "Fr",
+ "sat": "Sa"
+ },
+ "wide": {
+ "sun": "Sunday",
+ "mon": "Monday",
+ "tue": "Tuesday",
+ "wed": "Wednesday",
+ "thu": "Thursday",
+ "fri": "Friday",
+ "sat": "Saturday"
+ }
+ }
+ },
+ "quarters": {
+ "format": {
+ "abbreviated": {
+ "1": "Q1",
+ "2": "Q2",
+ "3": "Q3",
+ "4": "Q4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1st quarter",
+ "2": "2nd quarter",
+ "3": "3rd quarter",
+ "4": "4th quarter"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "Q1",
+ "2": "Q2",
+ "3": "Q3",
+ "4": "Q4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1st quarter",
+ "2": "2nd quarter",
+ "3": "3rd quarter",
+ "4": "4th quarter"
+ }
+ }
+ },
+ "dayPeriods": {
+ "format": {
+ "abbreviated": {
+ "am": "AM",
+ "am-alt-variant": "am",
+ "noon": "noon",
+ "pm": "PM",
+ "pm-alt-variant": "pm"
+ },
+ "narrow": {
+ "am": "a",
+ "noon": "n",
+ "pm": "p"
+ },
+ "wide": {
+ "am": "AM",
+ "am-alt-variant": "am",
+ "noon": "noon",
+ "pm": "PM",
+ "pm-alt-variant": "pm"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "am": "AM",
+ "am-alt-variant": "am",
+ "noon": "noon",
+ "pm": "PM",
+ "pm-alt-variant": "pm"
+ },
+ "narrow": {
+ "am": "a",
+ "noon": "n",
+ "pm": "p"
+ },
+ "wide": {
+ "am": "AM",
+ "am-alt-variant": "am",
+ "noon": "noon",
+ "pm": "PM",
+ "pm-alt-variant": "pm"
+ }
+ }
+ },
+ "eras": {
+ "eraNames": {
+ "0": "Before Christ",
+ "0-alt-variant": "Before Common Era",
+ "1": "Anno Domini",
+ "1-alt-variant": "Common Era"
+ },
+ "eraAbbr": {
+ "0": "BC",
+ "0-alt-variant": "BCE",
+ "1": "AD",
+ "1-alt-variant": "CE"
+ },
+ "eraNarrow": {
+ "0": "B",
+ "0-alt-variant": "BCE",
+ "1": "A",
+ "1-alt-variant": "CE"
+ }
+ },
+ "dateFormats": {
+ "full": "EEEE, MMMM d, y",
+ "long": "MMMM d, y",
+ "medium": "MMM d, y",
+ "short": "M/d/yy"
+ },
+ "timeFormats": {
+ "full": "h:mm:ss a zzzz",
+ "long": "h:mm:ss a z",
+ "medium": "h:mm:ss a",
+ "short": "h:mm a"
+ },
+ "dateTimeFormats": {
+ "full": "{1} 'at' {0}",
+ "long": "{1} 'at' {0}",
+ "medium": "{1}, {0}",
+ "short": "{1}, {0}",
+ "availableFormats": {
+ "E": "ccc",
+ "EHm": "E HH:mm",
+ "EHms": "E HH:mm:ss",
+ "Ed": "d E",
+ "Ehm": "E h:mm a",
+ "Ehms": "E h:mm:ss a",
+ "Gy": "y G",
+ "GyMMM": "MMM y G",
+ "GyMMMEd": "E, MMM d, y G",
+ "GyMMMd": "MMM d, y G",
+ "H": "HH",
+ "Hm": "HH:mm",
+ "Hms": "HH:mm:ss",
+ "Hmsv": "HH:mm:ss v",
+ "Hmv": "HH:mm v",
+ "M": "L",
+ "MEd": "E, M/d",
+ "MMM": "LLL",
+ "MMMEd": "E, MMM d",
+ "MMMd": "MMM d",
+ "Md": "M/d",
+ "d": "d",
+ "h": "h a",
+ "hm": "h:mm a",
+ "hms": "h:mm:ss a",
+ "hmsv": "h:mm:ss a v",
+ "hmv": "h:mm a v",
+ "ms": "mm:ss",
+ "y": "y",
+ "yM": "M/y",
+ "yMEd": "E, M/d/y",
+ "yMMM": "MMM y",
+ "yMMMEd": "E, MMM d, y",
+ "yMMMd": "MMM d, y",
+ "yMd": "M/d/y",
+ "yQQQ": "QQQ y",
+ "yQQQQ": "QQQQ y"
+ },
+ "appendItems": {
+ "Day": "{0} ({2}: {1})",
+ "Day-Of-Week": "{0} {1}",
+ "Era": "{0} {1}",
+ "Hour": "{0} ({2}: {1})",
+ "Minute": "{0} ({2}: {1})",
+ "Month": "{0} ({2}: {1})",
+ "Quarter": "{0} ({2}: {1})",
+ "Second": "{0} ({2}: {1})",
+ "Timezone": "{0} {1}",
+ "Week": "{0} ({2}: {1})",
+ "Year": "{0} {1}"
+ },
+ "intervalFormats": {
+ "intervalFormatFallback": "{0} – {1}",
+ "H": {
+ "H": "HH – HH"
+ },
+ "Hm": {
+ "H": "HH:mm – HH:mm",
+ "m": "HH:mm – HH:mm"
+ },
+ "Hmv": {
+ "H": "HH:mm – HH:mm v",
+ "m": "HH:mm – HH:mm v"
+ },
+ "Hv": {
+ "H": "HH – HH v"
+ },
+ "M": {
+ "M": "M – M"
+ },
+ "MEd": {
+ "M": "E, M/d – E, M/d",
+ "d": "E, M/d – E, M/d"
+ },
+ "MMM": {
+ "M": "MMM – MMM"
+ },
+ "MMMEd": {
+ "M": "E, MMM d – E, MMM d",
+ "d": "E, MMM d – E, MMM d"
+ },
+ "MMMd": {
+ "M": "MMM d – MMM d",
+ "d": "MMM d – d"
+ },
+ "Md": {
+ "M": "M/d – M/d",
+ "d": "M/d – M/d"
+ },
+ "d": {
+ "d": "d – d"
+ },
+ "h": {
+ "a": "h a – h a",
+ "h": "h – h a"
+ },
+ "hm": {
+ "a": "h:mm a – h:mm a",
+ "h": "h:mm – h:mm a",
+ "m": "h:mm – h:mm a"
+ },
+ "hmv": {
+ "a": "h:mm a – h:mm a v",
+ "h": "h:mm – h:mm a v",
+ "m": "h:mm – h:mm a v"
+ },
+ "hv": {
+ "a": "h a – h a v",
+ "h": "h – h a v"
+ },
+ "y": {
+ "y": "y – y"
+ },
+ "yM": {
+ "M": "M/y – M/y",
+ "y": "M/y – M/y"
+ },
+ "yMEd": {
+ "M": "E, M/d/y – E, M/d/y",
+ "d": "E, M/d/y – E, M/d/y",
+ "y": "E, M/d/y – E, M/d/y"
+ },
+ "yMMM": {
+ "M": "MMM – MMM y",
+ "y": "MMM y – MMM y"
+ },
+ "yMMMEd": {
+ "M": "E, MMM d – E, MMM d, y",
+ "d": "E, MMM d – E, MMM d, y",
+ "y": "E, MMM d, y – E, MMM d, y"
+ },
+ "yMMMM": {
+ "M": "MMMM – MMMM y",
+ "y": "MMMM y – MMMM y"
+ },
+ "yMMMd": {
+ "M": "MMM d – MMM d, y",
+ "d": "MMM d – d, y",
+ "y": "MMM d, y – MMM d, y"
+ },
+ "yMd": {
+ "M": "M/d/y – M/d/y",
+ "d": "M/d/y – M/d/y",
+ "y": "M/d/y – M/d/y"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "main": {
+ "de": {
+ "identity": {
+ "version": {
+ "_cldrVersion": "27.0.1",
+ "_number": "$Revision: 11304 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-24 11:35:18 -0600 (Tue, 24 Feb 2015) $"
+ },
+ "language": "de"
+ },
+ "dates": {
+ "calendars": {
+ "gregorian": {
+ "months": {
+ "format": {
+ "abbreviated": {
+ "1": "Jan.",
+ "2": "Feb.",
+ "3": "März",
+ "4": "Apr.",
+ "5": "Mai",
+ "6": "Juni",
+ "7": "Juli",
+ "8": "Aug.",
+ "9": "Sep.",
+ "10": "Okt.",
+ "11": "Nov.",
+ "12": "Dez."
+ },
+ "narrow": {
+ "1": "J",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "Januar",
+ "2": "Februar",
+ "3": "März",
+ "4": "April",
+ "5": "Mai",
+ "6": "Juni",
+ "7": "Juli",
+ "8": "August",
+ "9": "September",
+ "10": "Oktober",
+ "11": "November",
+ "12": "Dezember"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "Jan",
+ "2": "Feb",
+ "3": "Mär",
+ "4": "Apr",
+ "5": "Mai",
+ "6": "Jun",
+ "7": "Jul",
+ "8": "Aug",
+ "9": "Sep",
+ "10": "Okt",
+ "11": "Nov",
+ "12": "Dez"
+ },
+ "narrow": {
+ "1": "J",
+ "2": "F",
+ "3": "M",
+ "4": "A",
+ "5": "M",
+ "6": "J",
+ "7": "J",
+ "8": "A",
+ "9": "S",
+ "10": "O",
+ "11": "N",
+ "12": "D"
+ },
+ "wide": {
+ "1": "Januar",
+ "2": "Februar",
+ "3": "März",
+ "4": "April",
+ "5": "Mai",
+ "6": "Juni",
+ "7": "Juli",
+ "8": "August",
+ "9": "September",
+ "10": "Oktober",
+ "11": "November",
+ "12": "Dezember"
+ }
+ }
+ },
+ "days": {
+ "format": {
+ "abbreviated": {
+ "sun": "So.",
+ "mon": "Mo.",
+ "tue": "Di.",
+ "wed": "Mi.",
+ "thu": "Do.",
+ "fri": "Fr.",
+ "sat": "Sa."
+ },
+ "narrow": {
+ "sun": "S",
+ "mon": "M",
+ "tue": "D",
+ "wed": "M",
+ "thu": "D",
+ "fri": "F",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "So.",
+ "mon": "Mo.",
+ "tue": "Di.",
+ "wed": "Mi.",
+ "thu": "Do.",
+ "fri": "Fr.",
+ "sat": "Sa."
+ },
+ "wide": {
+ "sun": "Sonntag",
+ "mon": "Montag",
+ "tue": "Dienstag",
+ "wed": "Mittwoch",
+ "thu": "Donnerstag",
+ "fri": "Freitag",
+ "sat": "Samstag"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "sun": "So",
+ "mon": "Mo",
+ "tue": "Di",
+ "wed": "Mi",
+ "thu": "Do",
+ "fri": "Fr",
+ "sat": "Sa"
+ },
+ "narrow": {
+ "sun": "S",
+ "mon": "M",
+ "tue": "D",
+ "wed": "M",
+ "thu": "D",
+ "fri": "F",
+ "sat": "S"
+ },
+ "short": {
+ "sun": "So.",
+ "mon": "Mo.",
+ "tue": "Di.",
+ "wed": "Mi.",
+ "thu": "Do.",
+ "fri": "Fr.",
+ "sat": "Sa."
+ },
+ "wide": {
+ "sun": "Sonntag",
+ "mon": "Montag",
+ "tue": "Dienstag",
+ "wed": "Mittwoch",
+ "thu": "Donnerstag",
+ "fri": "Freitag",
+ "sat": "Samstag"
+ }
+ }
+ },
+ "quarters": {
+ "format": {
+ "abbreviated": {
+ "1": "Q1",
+ "2": "Q2",
+ "3": "Q3",
+ "4": "Q4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1. Quartal",
+ "2": "2. Quartal",
+ "3": "3. Quartal",
+ "4": "4. Quartal"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "Q1",
+ "2": "Q2",
+ "3": "Q3",
+ "4": "Q4"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "1. Quartal",
+ "2": "2. Quartal",
+ "3": "3. Quartal",
+ "4": "4. Quartal"
+ }
+ }
+ },
+ "dayPeriods": {
+ "format": {
+ "abbreviated": {
+ "afternoon": "nachmittags",
+ "am": "vorm.",
+ "earlyMorning": "morgens",
+ "evening": "abends",
+ "morning": "vormittags",
+ "night": "nachts",
+ "noon": "mittags",
+ "pm": "nachm."
+ },
+ "narrow": {
+ "am": "vm.",
+ "noon": "m.",
+ "pm": "nm."
+ },
+ "wide": {
+ "afternoon": "nachmittags",
+ "am": "vorm.",
+ "earlyMorning": "morgens",
+ "evening": "abends",
+ "morning": "vormittags",
+ "night": "nachts",
+ "noon": "mittags",
+ "pm": "nachm."
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "afternoon": "nachmittags",
+ "am": "vorm.",
+ "earlyMorning": "morgens",
+ "evening": "abends",
+ "morning": "vormittags",
+ "night": "nachts",
+ "noon": "mittags",
+ "pm": "nachm."
+ },
+ "narrow": {
+ "am": "vm.",
+ "noon": "m.",
+ "pm": "nm."
+ },
+ "wide": {
+ "afternoon": "nachmittags",
+ "am": "vorm.",
+ "earlyMorning": "morgens",
+ "evening": "abends",
+ "morning": "vormittags",
+ "night": "nachts",
+ "noon": "mittags",
+ "pm": "nachm."
+ }
+ }
+ },
+ "eras": {
+ "eraNames": {
+ "0": "v. Chr.",
+ "0-alt-variant": "vor unserer Zeitrechnung",
+ "1": "n. Chr.",
+ "1-alt-variant": "unserer Zeitrechnung"
+ },
+ "eraAbbr": {
+ "0": "v. Chr.",
+ "0-alt-variant": "v. u. Z.",
+ "1": "n. Chr.",
+ "1-alt-variant": "u. Z."
+ },
+ "eraNarrow": {
+ "0": "v. Chr.",
+ "0-alt-variant": "v. u. Z.",
+ "1": "n. Chr.",
+ "1-alt-variant": "u. Z."
+ }
+ },
+ "dateFormats": {
+ "full": "EEEE, d. MMMM y",
+ "long": "d. MMMM y",
+ "medium": "dd.MM.y",
+ "short": "dd.MM.yy"
+ },
+ "timeFormats": {
+ "full": "HH:mm:ss zzzz",
+ "long": "HH:mm:ss z",
+ "medium": "HH:mm:ss",
+ "short": "HH:mm"
+ },
+ "dateTimeFormats": {
+ "full": "{1} 'um' {0}",
+ "long": "{1} 'um' {0}",
+ "medium": "{1}, {0}",
+ "short": "{1}, {0}",
+ "availableFormats": {
+ "E": "ccc",
+ "EHm": "E, HH:mm",
+ "EHms": "E, HH:mm:ss",
+ "Ed": "E, d.",
+ "Ehm": "E h:mm a",
+ "Ehms": "E, h:mm:ss a",
+ "Gy": "y G",
+ "GyMMM": "MMM y G",
+ "GyMMMEd": "E, d. MMM y G",
+ "GyMMMd": "d. MMM y G",
+ "H": "HH 'Uhr'",
+ "Hm": "HH:mm",
+ "Hms": "HH:mm:ss",
+ "Hmsv": "HH:mm:ss v",
+ "Hmv": "HH:mm v",
+ "M": "L",
+ "MEd": "E, d.M.",
+ "MMM": "LLL",
+ "MMMEd": "E, d. MMM",
+ "MMMMEd": "E, d. MMMM",
+ "MMMd": "d. MMM",
+ "MMd": "d.MM.",
+ "MMdd": "dd.MM.",
+ "Md": "d.M.",
+ "d": "d",
+ "h": "h a",
+ "hm": "h:mm a",
+ "hms": "h:mm:ss a",
+ "hmsv": "h:mm:ss a v",
+ "hmv": "h:mm a v",
+ "ms": "mm:ss",
+ "y": "y",
+ "yM": "M.y",
+ "yMEd": "E, d.M.y",
+ "yMM": "MM.y",
+ "yMMM": "MMM y",
+ "yMMMEd": "E, d. MMM y",
+ "yMMMM": "MMMM y",
+ "yMMMd": "d. MMM y",
+ "yMMdd": "dd.MM.y",
+ "yMd": "d.M.y",
+ "yQQQ": "QQQ y",
+ "yQQQQ": "QQQQ y"
+ },
+ "appendItems": {
+ "Day": "{0} ({2}: {1})",
+ "Day-Of-Week": "{0} {1}",
+ "Era": "{1} {0}",
+ "Hour": "{0} ({2}: {1})",
+ "Minute": "{0} ({2}: {1})",
+ "Month": "{0} ({2}: {1})",
+ "Quarter": "{0} ({2}: {1})",
+ "Second": "{0} ({2}: {1})",
+ "Timezone": "{0} {1}",
+ "Week": "{0} ({2}: {1})",
+ "Year": "{1} {0}"
+ },
+ "intervalFormats": {
+ "intervalFormatFallback": "{0} – {1}",
+ "H": {
+ "H": "HH–HH 'Uhr'"
+ },
+ "Hm": {
+ "H": "HH:mm–HH:mm",
+ "m": "HH:mm–HH:mm"
+ },
+ "Hmv": {
+ "H": "HH:mm–HH:mm v",
+ "m": "HH:mm–HH:mm v"
+ },
+ "Hv": {
+ "H": "HH–HH 'Uhr' v"
+ },
+ "M": {
+ "M": "M.–M."
+ },
+ "MEd": {
+ "M": "E, dd.MM. – E, dd.MM.",
+ "d": "E, dd.MM. – E, dd.MM."
+ },
+ "MMM": {
+ "M": "MMM–MMM"
+ },
+ "MMMEd": {
+ "M": "E, d. MMM – E, d. MMM",
+ "d": "E, d. – E, d. MMM"
+ },
+ "MMMM": {
+ "M": "LLLL–LLLL"
+ },
+ "MMMd": {
+ "M": "d. MMM – d. MMM",
+ "d": "d.–d. MMM"
+ },
+ "Md": {
+ "M": "dd.MM. – dd.MM.",
+ "d": "dd.MM. – dd.MM."
+ },
+ "d": {
+ "d": "d.–d."
+ },
+ "h": {
+ "a": "h a – h a",
+ "h": "h–h a"
+ },
+ "hm": {
+ "a": "h:mm a – h:mm a",
+ "h": "h:mm–h:mm a",
+ "m": "h:mm–h:mm a"
+ },
+ "hmv": {
+ "a": "h:mm a – h:mm a v",
+ "h": "h:mm–h:mm a v",
+ "m": "h:mm–h:mm a v"
+ },
+ "hv": {
+ "a": "h a – h a v",
+ "h": "h–h a v"
+ },
+ "y": {
+ "y": "y–y"
+ },
+ "yM": {
+ "M": "MM.y – MM.y",
+ "y": "MM.y – MM.y"
+ },
+ "yMEd": {
+ "M": "E, dd.MM.y – E, dd.MM.y",
+ "d": "E, dd.MM.y – E, dd.MM.y",
+ "y": "E, dd.MM.y – E, dd.MM.y"
+ },
+ "yMMM": {
+ "M": "MMM–MMM y",
+ "y": "MMM y – MMM y"
+ },
+ "yMMMEd": {
+ "M": "E, d. MMM – E, d. MMM y",
+ "d": "E, d. – E, d. MMM y",
+ "y": "E, d. MMM y – E, d. MMM y"
+ },
+ "yMMMM": {
+ "M": "MMMM–MMMM y",
+ "y": "MMMM y – MMMM y"
+ },
+ "yMMMd": {
+ "M": "d. MMM – d. MMM y",
+ "d": "d.–d. MMM y",
+ "y": "d. MMM y – d. MMM y"
+ },
+ "yMd": {
+ "M": "dd.MM.y – dd.MM.y",
+ "d": "dd.MM.y – dd.MM.y",
+ "y": "dd.MM.y – dd.MM.y"
+ }
+ }
+ }
+ }
+ }
+ },
+ "numbers": {
+ "defaultNumberingSystem": "latn",
+ "otherNumberingSystems": {
+ "native": "latn"
+ },
+ "minimumGroupingDigits": "1",
+ "symbols-numberSystem-latn": {
+ "decimal": ",",
+ "group": ".",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "superscriptingExponent": "·",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "decimalFormats-numberSystem-latn": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-one": "0 Tausend",
+ "1000-count-other": "0 Tausend",
+ "10000-count-one": "00 Tausend",
+ "10000-count-other": "00 Tausend",
+ "100000-count-one": "000 Tausend",
+ "100000-count-other": "000 Tausend",
+ "1000000-count-one": "0 Million",
+ "1000000-count-other": "0 Millionen",
+ "10000000-count-one": "00 Millionen",
+ "10000000-count-other": "00 Millionen",
+ "100000000-count-one": "000 Millionen",
+ "100000000-count-other": "000 Millionen",
+ "1000000000-count-one": "0 Milliarde",
+ "1000000000-count-other": "0 Milliarden",
+ "10000000000-count-one": "00 Milliarden",
+ "10000000000-count-other": "00 Milliarden",
+ "100000000000-count-one": "000 Milliarden",
+ "100000000000-count-other": "000 Milliarden",
+ "1000000000000-count-one": "0 Billion",
+ "1000000000000-count-other": "0 Billionen",
+ "10000000000000-count-one": "00 Billionen",
+ "10000000000000-count-other": "00 Billionen",
+ "100000000000000-count-one": "000 Billionen",
+ "100000000000000-count-other": "000 Billionen"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-one": "0 Tsd'.'",
+ "1000-count-other": "0 Tsd'.'",
+ "10000-count-one": "00 Tsd'.'",
+ "10000-count-other": "00 Tsd'.'",
+ "100000-count-one": "000 Tsd'.'",
+ "100000-count-other": "000 Tsd'.'",
+ "1000000-count-one": "0 Mio'.'",
+ "1000000-count-other": "0 Mio'.'",
+ "10000000-count-one": "00 Mio'.'",
+ "10000000-count-other": "00 Mio'.'",
+ "100000000-count-one": "000 Mio'.'",
+ "100000000-count-other": "000 Mio'.'",
+ "1000000000-count-one": "0 Mrd'.'",
+ "1000000000-count-other": "0 Mrd'.'",
+ "10000000000-count-one": "00 Mrd'.'",
+ "10000000000-count-other": "00 Mrd'.'",
+ "100000000000-count-one": "000 Mrd'.'",
+ "100000000000-count-other": "000 Mrd'.'",
+ "1000000000000-count-one": "0 Bio'.'",
+ "1000000000000-count-other": "0 Bio'.'",
+ "10000000000000-count-one": "00 Bio'.'",
+ "10000000000000-count-other": "00 Bio'.'",
+ "100000000000000-count-one": "000 Bio'.'",
+ "100000000000000-count-other": "000 Bio'.'"
+ }
+ }
+ },
+ "scientificFormats-numberSystem-latn": {
+ "standard": "#E0"
+ },
+ "percentFormats-numberSystem-latn": {
+ "standard": "#,##0 %"
+ },
+ "currencyFormats-numberSystem-latn": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "#,##0.00 ¤",
+ "standard": "#,##0.00 ¤",
+ "unitPattern-count-one": "{0} {1}",
+ "unitPattern-count-other": "{0} {1}"
+ },
+ "miscPatterns-numberSystem-latn": {
+ "atLeast": "{0}+",
+ "range": "{0}–{1}"
+ }
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "main": {
+ "zh": {
+ "identity": {
+ "version": {
+ "_cldrVersion": "27.0.1",
+ "_number": "$Revision: 11294 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $"
+ },
+ "language": "zh"
+ },
+ "dates": {
+ "calendars": {
+ "gregorian": {
+ "months": {
+ "format": {
+ "abbreviated": {
+ "1": "1月",
+ "2": "2月",
+ "3": "3月",
+ "4": "4月",
+ "5": "5月",
+ "6": "6月",
+ "7": "7月",
+ "8": "8月",
+ "9": "9月",
+ "10": "10月",
+ "11": "11月",
+ "12": "12月"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7",
+ "8": "8",
+ "9": "9",
+ "10": "10",
+ "11": "11",
+ "12": "12"
+ },
+ "wide": {
+ "1": "一月",
+ "2": "二月",
+ "3": "三月",
+ "4": "四月",
+ "5": "五月",
+ "6": "六月",
+ "7": "七月",
+ "8": "八月",
+ "9": "九月",
+ "10": "十月",
+ "11": "十一月",
+ "12": "十二月"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "1月",
+ "2": "2月",
+ "3": "3月",
+ "4": "4月",
+ "5": "5月",
+ "6": "6月",
+ "7": "7月",
+ "8": "8月",
+ "9": "9月",
+ "10": "10月",
+ "11": "11月",
+ "12": "12月"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7",
+ "8": "8",
+ "9": "9",
+ "10": "10",
+ "11": "11",
+ "12": "12"
+ },
+ "wide": {
+ "1": "一月",
+ "2": "二月",
+ "3": "三月",
+ "4": "四月",
+ "5": "五月",
+ "6": "六月",
+ "7": "七月",
+ "8": "八月",
+ "9": "九月",
+ "10": "十月",
+ "11": "十一月",
+ "12": "十二月"
+ }
+ }
+ },
+ "days": {
+ "format": {
+ "abbreviated": {
+ "sun": "周日",
+ "mon": "周一",
+ "tue": "周二",
+ "wed": "周三",
+ "thu": "周四",
+ "fri": "周五",
+ "sat": "周六"
+ },
+ "narrow": {
+ "sun": "日",
+ "mon": "一",
+ "tue": "二",
+ "wed": "三",
+ "thu": "四",
+ "fri": "五",
+ "sat": "六"
+ },
+ "short": {
+ "sun": "周日",
+ "mon": "周一",
+ "tue": "周二",
+ "wed": "周三",
+ "thu": "周四",
+ "fri": "周五",
+ "sat": "周六"
+ },
+ "wide": {
+ "sun": "星期日",
+ "mon": "星期一",
+ "tue": "星期二",
+ "wed": "星期三",
+ "thu": "星期四",
+ "fri": "星期五",
+ "sat": "星期六"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "sun": "周日",
+ "mon": "周一",
+ "tue": "周二",
+ "wed": "周三",
+ "thu": "周四",
+ "fri": "周五",
+ "sat": "周六"
+ },
+ "narrow": {
+ "sun": "日",
+ "mon": "一",
+ "tue": "二",
+ "wed": "三",
+ "thu": "四",
+ "fri": "五",
+ "sat": "六"
+ },
+ "short": {
+ "sun": "周日",
+ "mon": "周一",
+ "tue": "周二",
+ "wed": "周三",
+ "thu": "周四",
+ "fri": "周五",
+ "sat": "周六"
+ },
+ "wide": {
+ "sun": "星期日",
+ "mon": "星期一",
+ "tue": "星期二",
+ "wed": "星期三",
+ "thu": "星期四",
+ "fri": "星期五",
+ "sat": "星期六"
+ }
+ }
+ },
+ "quarters": {
+ "format": {
+ "abbreviated": {
+ "1": "1季度",
+ "2": "2季度",
+ "3": "3季度",
+ "4": "4季度"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "第一季度",
+ "2": "第二季度",
+ "3": "第三季度",
+ "4": "第四季度"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "1": "1季度",
+ "2": "2季度",
+ "3": "3季度",
+ "4": "4季度"
+ },
+ "narrow": {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4"
+ },
+ "wide": {
+ "1": "第一季度",
+ "2": "第二季度",
+ "3": "第三季度",
+ "4": "第四季度"
+ }
+ }
+ },
+ "dayPeriods": {
+ "format": {
+ "abbreviated": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ },
+ "narrow": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ },
+ "wide": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ }
+ },
+ "stand-alone": {
+ "abbreviated": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ },
+ "narrow": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ },
+ "wide": {
+ "afternoon": "下午",
+ "am": "上午",
+ "earlyMorning": "清晨",
+ "midDay": "中午",
+ "morning": "上午",
+ "night": "晚上",
+ "noon": "中午",
+ "pm": "下午",
+ "weeHours": "凌晨"
+ }
+ }
+ },
+ "eras": {
+ "eraNames": {
+ "0": "公元前",
+ "0-alt-variant": "BCE",
+ "1": "公元",
+ "1-alt-variant": "CE"
+ },
+ "eraAbbr": {
+ "0": "公元前",
+ "0-alt-variant": "BCE",
+ "1": "公元",
+ "1-alt-variant": "CE"
+ },
+ "eraNarrow": {
+ "0": "公元前",
+ "0-alt-variant": "BCE",
+ "1": "公元",
+ "1-alt-variant": "CE"
+ }
+ },
+ "dateFormats": {
+ "full": "y年M月d日EEEE",
+ "long": "y年M月d日",
+ "medium": "y年M月d日",
+ "short": "yy/M/d"
+ },
+ "timeFormats": {
+ "full": "zzzz ah:mm:ss",
+ "long": "z ah:mm:ss",
+ "medium": "ah:mm:ss",
+ "short": "ah:mm"
+ },
+ "dateTimeFormats": {
+ "full": "{1} {0}",
+ "long": "{1} {0}",
+ "medium": "{1} {0}",
+ "short": "{1} {0}",
+ "availableFormats": {
+ "E": "ccc",
+ "EHm": "EHH:mm",
+ "EHms": "EHH:mm:ss",
+ "Ed": "d日E",
+ "Ehm": "Eah:mm",
+ "Ehms": "Eah:mm:ss",
+ "Gy": "Gy年",
+ "GyMMM": "Gy年M月",
+ "GyMMMEd": "Gy年M月d日E",
+ "GyMMMd": "Gy年M月d日",
+ "H": "H时",
+ "Hm": "HH:mm",
+ "Hms": "HH:mm:ss",
+ "Hmsv": "v HH:mm:ss",
+ "Hmv": "v HH:mm",
+ "M": "M月",
+ "MEd": "M/dE",
+ "MMM": "LLL",
+ "MMMEd": "M月d日E",
+ "MMMMdd": "M月dd日",
+ "MMMd": "M月d日",
+ "MMdd": "MM/dd",
+ "Md": "M/d",
+ "d": "d日",
+ "h": "ah时",
+ "hm": "ah:mm",
+ "hms": "ah:mm:ss",
+ "hmsv": "v ah:mm:ss",
+ "hmv": "v ah:mm",
+ "ms": "mm:ss",
+ "y": "y年",
+ "yM": "y年M月",
+ "yMEd": "y/M/dE",
+ "yMM": "y年M月",
+ "yMMM": "y年M月",
+ "yMMMEd": "y年M月d日E",
+ "yMMMM": "y年M月",
+ "yMMMd": "y年M月d日",
+ "yMd": "y/M/d",
+ "yQQQ": "y年第Q季度",
+ "yQQQQ": "y年第Q季度"
+ },
+ "appendItems": {
+ "Day": "{0} ({2}: {1})",
+ "Day-Of-Week": "{0} {1}",
+ "Era": "{1} {0}",
+ "Hour": "{0} ({2}: {1})",
+ "Minute": "{0} ({2}: {1})",
+ "Month": "{0} ({2}: {1})",
+ "Quarter": "{0} ({2}: {1})",
+ "Second": "{0} ({2}: {1})",
+ "Timezone": "{1}{0}",
+ "Week": "{0} ({2}: {1})",
+ "Year": "{1} {0}"
+ },
+ "intervalFormats": {
+ "intervalFormatFallback": "{0} – {1}",
+ "H": {
+ "H": "HH–HH"
+ },
+ "Hm": {
+ "H": "HH:mm–HH:mm",
+ "m": "HH:mm–HH:mm"
+ },
+ "Hmv": {
+ "H": "v HH:mm–HH:mm",
+ "m": "v HH:mm–HH:mm"
+ },
+ "Hv": {
+ "H": "v HH–HH"
+ },
+ "M": {
+ "M": "M–M月"
+ },
+ "MEd": {
+ "M": "M/dE至M/dE",
+ "d": "M/dE至M/dE"
+ },
+ "MMM": {
+ "M": "LLL至LLL"
+ },
+ "MMMEd": {
+ "M": "M月d日E至M月d日E",
+ "d": "M月d日E至d日E"
+ },
+ "MMMd": {
+ "M": "M月d日至M月d日",
+ "d": "M月d日至d日"
+ },
+ "Md": {
+ "M": "M/d – M/d",
+ "d": "M/d – M/d"
+ },
+ "d": {
+ "d": "d–d日"
+ },
+ "h": {
+ "a": "ah时至ah时",
+ "h": "ah时至h时"
+ },
+ "hm": {
+ "a": "ah:mm至ah:mm",
+ "h": "ah:mm至h:mm",
+ "m": "ah:mm至h:mm"
+ },
+ "hmv": {
+ "a": "vah:mm至ah:mm",
+ "h": "vah:mm至h:mm",
+ "m": "vah:mm至h:mm"
+ },
+ "hv": {
+ "a": "vah时至ah时",
+ "h": "vah时至h时"
+ },
+ "y": {
+ "y": "y–y年"
+ },
+ "yM": {
+ "M": "y年M月至M月",
+ "y": "y年M月至y年M月"
+ },
+ "yMEd": {
+ "M": "y/M/dE至y/M/dE",
+ "d": "y/M/dE至y/M/dE",
+ "y": "y/M/dE至y/M/dE"
+ },
+ "yMMM": {
+ "M": "y年M月至M月",
+ "y": "y年M月至y年M月"
+ },
+ "yMMMEd": {
+ "M": "y年M月d日E至M月d日E",
+ "d": "y年M月d日E至d日E",
+ "y": "y年M月d日E至y年M月d日E"
+ },
+ "yMMMM": {
+ "M": "y年M月至M月",
+ "y": "y年M月至y年M月"
+ },
+ "yMMMd": {
+ "M": "y年M月d日至M月d日",
+ "d": "y年M月d日至d日",
+ "y": "y年M月d日至y年M月d日"
+ },
+ "yMd": {
+ "M": "y/M/d – y/M/d",
+ "d": "y/M/d – y/M/d",
+ "y": "y/M/d – y/M/d"
+ }
+ }
+ }
+ }
+ }
+ },
+ "numbers": {
+ "defaultNumberingSystem": "latn",
+ "otherNumberingSystems": {
+ "native": "hanidec",
+ "traditional": "hans",
+ "finance": "hansfin"
+ },
+ "minimumGroupingDigits": "1",
+ "symbols-numberSystem-hanidec": {
+ "decimal": ".",
+ "group": ",",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "superscriptingExponent": "×",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "symbols-numberSystem-latn": {
+ "decimal": ".",
+ "group": ",",
+ "list": ";",
+ "percentSign": "%",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "superscriptingExponent": "×",
+ "perMille": "‰",
+ "infinity": "∞",
+ "nan": "NaN",
+ "timeSeparator": ":"
+ },
+ "decimalFormats-numberSystem-hanidec": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-other": "0千",
+ "10000-count-other": "0万",
+ "100000-count-other": "00万",
+ "1000000-count-other": "000万",
+ "10000000-count-other": "0000万",
+ "100000000-count-other": "0亿",
+ "1000000000-count-other": "00亿",
+ "10000000000-count-other": "000亿",
+ "100000000000-count-other": "0000亿",
+ "1000000000000-count-other": "0兆",
+ "10000000000000-count-other": "00兆",
+ "100000000000000-count-other": "000兆"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-other": "0千",
+ "10000-count-other": "0万",
+ "100000-count-other": "00万",
+ "1000000-count-other": "000万",
+ "10000000-count-other": "0000万",
+ "100000000-count-other": "0亿",
+ "1000000000-count-other": "00亿",
+ "10000000000-count-other": "000亿",
+ "100000000000-count-other": "0000亿",
+ "1000000000000-count-other": "0兆",
+ "10000000000000-count-other": "00兆",
+ "100000000000000-count-other": "000兆"
+ }
+ }
+ },
+ "decimalFormats-numberSystem-latn": {
+ "standard": "#,##0.###",
+ "long": {
+ "decimalFormat": {
+ "1000-count-other": "0千",
+ "10000-count-other": "0万",
+ "100000-count-other": "00万",
+ "1000000-count-other": "000万",
+ "10000000-count-other": "0000万",
+ "100000000-count-other": "0亿",
+ "1000000000-count-other": "00亿",
+ "10000000000-count-other": "000亿",
+ "100000000000-count-other": "0000亿",
+ "1000000000000-count-other": "0兆",
+ "10000000000000-count-other": "00兆",
+ "100000000000000-count-other": "000兆"
+ }
+ },
+ "short": {
+ "decimalFormat": {
+ "1000-count-other": "0千",
+ "10000-count-other": "0万",
+ "100000-count-other": "00万",
+ "1000000-count-other": "000万",
+ "10000000-count-other": "0000万",
+ "100000000-count-other": "0亿",
+ "1000000000-count-other": "00亿",
+ "10000000000-count-other": "000亿",
+ "100000000000-count-other": "0000亿",
+ "1000000000000-count-other": "0兆",
+ "10000000000000-count-other": "00兆",
+ "100000000000000-count-other": "000兆"
+ }
+ }
+ },
+ "scientificFormats-numberSystem-hanidec": {
+ "standard": "#E0"
+ },
+ "scientificFormats-numberSystem-latn": {
+ "standard": "#E0"
+ },
+ "percentFormats-numberSystem-hanidec": {
+ "standard": "#,##0%"
+ },
+ "percentFormats-numberSystem-latn": {
+ "standard": "#,##0%"
+ },
+ "currencyFormats-numberSystem-hanidec": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "¤#,##0.00;(¤#,##0.00)",
+ "standard": "¤ #,##0.00",
+ "unitPattern-count-other": "{0}{1}"
+ },
+ "currencyFormats-numberSystem-latn": {
+ "currencySpacing": {
+ "beforeCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ },
+ "afterCurrency": {
+ "currencyMatch": "[:^S:]",
+ "surroundingMatch": "[:digit:]",
+ "insertBetween": " "
+ }
+ },
+ "accounting": "¤#,##0.00;(¤#,##0.00)",
+ "standard": "¤ #,##0.00",
+ "unitPattern-count-other": "{0}{1}"
+ },
+ "miscPatterns-numberSystem-hanidec": {
+ "atLeast": "{0}+",
+ "range": "{0}-{1}"
+ },
+ "miscPatterns-numberSystem-latn": {
+ "atLeast": "{0}+",
+ "range": "{0}-{1}"
+ }
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "supplemental": {
+ "version": {
+ "_unicodeVersion": "7.0.0",
+ "_number": "$Revision: 11318 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $"
+ },
+ "likelySubtags": {
+ "aa": "aa-Latn-ET",
+ "ab": "ab-Cyrl-GE",
+ "abr": "abr-Latn-GH",
+ "ace": "ace-Latn-ID",
+ "ach": "ach-Latn-UG",
+ "ada": "ada-Latn-GH",
+ "ady": "ady-Cyrl-RU",
+ "ae": "ae-Avst-IR",
+ "aeb": "aeb-Arab-TN",
+ "af": "af-Latn-ZA",
+ "agq": "agq-Latn-CM",
+ "ak": "ak-Latn-GH",
+ "akk": "akk-Xsux-IQ",
+ "aln": "aln-Latn-XK",
+ "alt": "alt-Cyrl-RU",
+ "am": "am-Ethi-ET",
+ "amo": "amo-Latn-NG",
+ "aoz": "aoz-Latn-ID",
+ "ar": "ar-Arab-EG",
+ "arc": "arc-Armi-IR",
+ "arc-Nbat": "arc-Nbat-JO",
+ "arc-Palm": "arc-Palm-SY",
+ "arn": "arn-Latn-CL",
+ "aro": "aro-Latn-BO",
+ "arq": "arq-Arab-DZ",
+ "ary": "ary-Arab-MA",
+ "arz": "arz-Arab-EG",
+ "as": "as-Beng-IN",
+ "asa": "asa-Latn-TZ",
+ "ast": "ast-Latn-ES",
+ "atj": "atj-Latn-CA",
+ "av": "av-Cyrl-RU",
+ "awa": "awa-Deva-IN",
+ "ay": "ay-Latn-BO",
+ "az": "az-Latn-AZ",
+ "az-Arab": "az-Arab-IR",
+ "az-IR": "az-Arab-IR",
+ "az-RU": "az-Cyrl-RU",
+ "azb": "azb-Arab-IR",
+ "ba": "ba-Cyrl-RU",
+ "bal": "bal-Arab-PK",
+ "ban": "ban-Latn-ID",
+ "bap": "bap-Deva-NP",
+ "bar": "bar-Latn-AT",
+ "bas": "bas-Latn-CM",
+ "bax": "bax-Bamu-CM",
+ "bbc": "bbc-Latn-ID",
+ "bbj": "bbj-Latn-CM",
+ "bci": "bci-Latn-CI",
+ "be": "be-Cyrl-BY",
+ "bem": "bem-Latn-ZM",
+ "bew": "bew-Latn-ID",
+ "bez": "bez-Latn-TZ",
+ "bfd": "bfd-Latn-CM",
+ "bfq": "bfq-Taml-IN",
+ "bft": "bft-Arab-PK",
+ "bfy": "bfy-Deva-IN",
+ "bg": "bg-Cyrl-BG",
+ "bgc": "bgc-Deva-IN",
+ "bgx": "bgx-Grek-TR",
+ "bh": "bh-Kthi-IN",
+ "bhb": "bhb-Deva-IN",
+ "bhi": "bhi-Deva-IN",
+ "bhk": "bhk-Latn-PH",
+ "bho": "bho-Deva-IN",
+ "bi": "bi-Latn-VU",
+ "bik": "bik-Latn-PH",
+ "bin": "bin-Latn-NG",
+ "bjj": "bjj-Deva-IN",
+ "bjn": "bjn-Latn-ID",
+ "bkm": "bkm-Latn-CM",
+ "bku": "bku-Latn-PH",
+ "blt": "blt-Tavt-VN",
+ "bm": "bm-Latn-ML",
+ "bmq": "bmq-Latn-ML",
+ "bn": "bn-Beng-BD",
+ "bo": "bo-Tibt-CN",
+ "bpy": "bpy-Beng-IN",
+ "bqi": "bqi-Arab-IR",
+ "bqv": "bqv-Latn-CI",
+ "br": "br-Latn-FR",
+ "bra": "bra-Deva-IN",
+ "brh": "brh-Arab-PK",
+ "brx": "brx-Deva-IN",
+ "bs": "bs-Latn-BA",
+ "bsq": "bsq-Bass-LR",
+ "bss": "bss-Latn-CM",
+ "bto": "bto-Latn-PH",
+ "btv": "btv-Deva-PK",
+ "bua": "bua-Cyrl-RU",
+ "buc": "buc-Latn-YT",
+ "bug": "bug-Latn-ID",
+ "bum": "bum-Latn-CM",
+ "bvb": "bvb-Latn-GQ",
+ "byn": "byn-Ethi-ER",
+ "byv": "byv-Latn-CM",
+ "bze": "bze-Latn-ML",
+ "ca": "ca-Latn-ES",
+ "cch": "cch-Latn-NG",
+ "ccp": "ccp-Beng-IN",
+ "ccp-Cakm": "ccp-Cakm-BD",
+ "ce": "ce-Cyrl-RU",
+ "ceb": "ceb-Latn-PH",
+ "cgg": "cgg-Latn-UG",
+ "ch": "ch-Latn-GU",
+ "chk": "chk-Latn-FM",
+ "chm": "chm-Cyrl-RU",
+ "cho": "cho-Latn-US",
+ "chp": "chp-Latn-CA",
+ "chr": "chr-Cher-US",
+ "cja": "cja-Arab-KH",
+ "cjm": "cjm-Cham-VN",
+ "ckb": "ckb-Arab-IQ",
+ "co": "co-Latn-FR",
+ "cop": "cop-Copt-EG",
+ "cps": "cps-Latn-PH",
+ "cr": "cr-Cans-CA",
+ "crj": "crj-Cans-CA",
+ "crk": "crk-Cans-CA",
+ "crl": "crl-Cans-CA",
+ "crm": "crm-Cans-CA",
+ "crs": "crs-Latn-SC",
+ "cs": "cs-Latn-CZ",
+ "csb": "csb-Latn-PL",
+ "csw": "csw-Cans-CA",
+ "ctd": "ctd-Pauc-MM",
+ "cu": "cu-Cyrl-RU",
+ "cu-Glag": "cu-Glag-BG",
+ "cv": "cv-Cyrl-RU",
+ "cy": "cy-Latn-GB",
+ "da": "da-Latn-DK",
+ "dak": "dak-Latn-US",
+ "dar": "dar-Cyrl-RU",
+ "dav": "dav-Latn-KE",
+ "dcc": "dcc-Arab-IN",
+ "de": "de-Latn-DE",
+ "den": "den-Latn-CA",
+ "dgr": "dgr-Latn-CA",
+ "dje": "dje-Latn-NE",
+ "dnj": "dnj-Latn-CI",
+ "doi": "doi-Arab-IN",
+ "dsb": "dsb-Latn-DE",
+ "dtm": "dtm-Latn-ML",
+ "dtp": "dtp-Latn-MY",
+ "dua": "dua-Latn-CM",
+ "dv": "dv-Thaa-MV",
+ "dyo": "dyo-Latn-SN",
+ "dyu": "dyu-Latn-BF",
+ "dz": "dz-Tibt-BT",
+ "ebu": "ebu-Latn-KE",
+ "ee": "ee-Latn-GH",
+ "efi": "efi-Latn-NG",
+ "egl": "egl-Latn-IT",
+ "egy": "egy-Egyp-EG",
+ "eky": "eky-Kali-MM",
+ "el": "el-Grek-GR",
+ "en": "en-Latn-US",
+ "en-Shaw": "en-Shaw-GB",
+ "eo": "eo-Latn-001",
+ "es": "es-Latn-ES",
+ "esu": "esu-Latn-US",
+ "et": "et-Latn-EE",
+ "ett": "ett-Ital-IT",
+ "eu": "eu-Latn-ES",
+ "ewo": "ewo-Latn-CM",
+ "ext": "ext-Latn-ES",
+ "fa": "fa-Arab-IR",
+ "fan": "fan-Latn-GQ",
+ "ff": "ff-Latn-SN",
+ "ffm": "ffm-Latn-ML",
+ "fi": "fi-Latn-FI",
+ "fil": "fil-Latn-PH",
+ "fit": "fit-Latn-SE",
+ "fj": "fj-Latn-FJ",
+ "fo": "fo-Latn-FO",
+ "fon": "fon-Latn-BJ",
+ "fr": "fr-Latn-FR",
+ "frc": "frc-Latn-US",
+ "frp": "frp-Latn-FR",
+ "frr": "frr-Latn-DE",
+ "frs": "frs-Latn-DE",
+ "fud": "fud-Latn-WF",
+ "fuq": "fuq-Latn-NE",
+ "fur": "fur-Latn-IT",
+ "fuv": "fuv-Latn-NG",
+ "fy": "fy-Latn-NL",
+ "ga": "ga-Latn-IE",
+ "gaa": "gaa-Latn-GH",
+ "gag": "gag-Latn-MD",
+ "gan": "gan-Hans-CN",
+ "gay": "gay-Latn-ID",
+ "gbm": "gbm-Deva-IN",
+ "gbz": "gbz-Arab-IR",
+ "gcr": "gcr-Latn-GF",
+ "gd": "gd-Latn-GB",
+ "gez": "gez-Ethi-ET",
+ "ggn": "ggn-Deva-NP",
+ "gil": "gil-Latn-KI",
+ "gjk": "gjk-Arab-PK",
+ "gju": "gju-Arab-PK",
+ "gl": "gl-Latn-ES",
+ "glk": "glk-Arab-IR",
+ "gn": "gn-Latn-PY",
+ "gom": "gom-Deva-IN",
+ "gon": "gon-Telu-IN",
+ "gor": "gor-Latn-ID",
+ "gos": "gos-Latn-NL",
+ "got": "got-Goth-UA",
+ "grc": "grc-Cprt-CY",
+ "grc-Linb": "grc-Linb-GR",
+ "grt": "grt-Beng-IN",
+ "gsw": "gsw-Latn-CH",
+ "gu": "gu-Gujr-IN",
+ "gub": "gub-Latn-BR",
+ "guc": "guc-Latn-CO",
+ "gur": "gur-Latn-GH",
+ "guz": "guz-Latn-KE",
+ "gv": "gv-Latn-IM",
+ "gvr": "gvr-Deva-NP",
+ "gwi": "gwi-Latn-CA",
+ "ha": "ha-Latn-NG",
+ "ha-CM": "ha-Arab-CM",
+ "ha-SD": "ha-Arab-SD",
+ "hak": "hak-Hans-CN",
+ "haw": "haw-Latn-US",
+ "haz": "haz-Arab-AF",
+ "he": "he-Hebr-IL",
+ "hi": "hi-Deva-IN",
+ "hif": "hif-Deva-FJ",
+ "hil": "hil-Latn-PH",
+ "hmd": "hmd-Plrd-CN",
+ "hnd": "hnd-Arab-PK",
+ "hne": "hne-Deva-IN",
+ "hnj": "hnj-Hmng-LA",
+ "hnn": "hnn-Latn-PH",
+ "hno": "hno-Arab-PK",
+ "ho": "ho-Latn-PG",
+ "hoc": "hoc-Deva-IN",
+ "hoj": "hoj-Deva-IN",
+ "hr": "hr-Latn-HR",
+ "hsb": "hsb-Latn-DE",
+ "hsn": "hsn-Hans-CN",
+ "ht": "ht-Latn-HT",
+ "hu": "hu-Latn-HU",
+ "hy": "hy-Armn-AM",
+ "hz": "hz-Latn-NA",
+ "ia": "ia-Latn-FR",
+ "iba": "iba-Latn-MY",
+ "ibb": "ibb-Latn-NG",
+ "id": "id-Latn-ID",
+ "ig": "ig-Latn-NG",
+ "ii": "ii-Yiii-CN",
+ "ik": "ik-Latn-US",
+ "ikt": "ikt-Latn-CA",
+ "ilo": "ilo-Latn-PH",
+ "in": "in-Latn-ID",
+ "inh": "inh-Cyrl-RU",
+ "is": "is-Latn-IS",
+ "it": "it-Latn-IT",
+ "iu": "iu-Cans-CA",
+ "iw": "iw-Hebr-IL",
+ "izh": "izh-Latn-RU",
+ "ja": "ja-Jpan-JP",
+ "jam": "jam-Latn-JM",
+ "jgo": "jgo-Latn-CM",
+ "ji": "ji-Hebr-UA",
+ "jmc": "jmc-Latn-TZ",
+ "jml": "jml-Deva-NP",
+ "jut": "jut-Latn-DK",
+ "jv": "jv-Latn-ID",
+ "jw": "jw-Latn-ID",
+ "ka": "ka-Geor-GE",
+ "kaa": "kaa-Cyrl-UZ",
+ "kab": "kab-Latn-DZ",
+ "kac": "kac-Latn-MM",
+ "kaj": "kaj-Latn-NG",
+ "kam": "kam-Latn-KE",
+ "kao": "kao-Latn-ML",
+ "kbd": "kbd-Cyrl-RU",
+ "kcg": "kcg-Latn-NG",
+ "kck": "kck-Latn-ZW",
+ "kde": "kde-Latn-TZ",
+ "kdt": "kdt-Thai-TH",
+ "kea": "kea-Latn-CV",
+ "ken": "ken-Latn-CM",
+ "kfo": "kfo-Latn-CI",
+ "kfr": "kfr-Deva-IN",
+ "kfy": "kfy-Deva-IN",
+ "kg": "kg-Latn-CD",
+ "kge": "kge-Latn-ID",
+ "kgp": "kgp-Latn-BR",
+ "kha": "kha-Latn-IN",
+ "khb": "khb-Talu-CN",
+ "khn": "khn-Deva-IN",
+ "khq": "khq-Latn-ML",
+ "kht": "kht-Mymr-IN",
+ "khw": "khw-Arab-PK",
+ "ki": "ki-Latn-KE",
+ "kiu": "kiu-Latn-TR",
+ "kj": "kj-Latn-NA",
+ "kjg": "kjg-Laoo-LA",
+ "kk": "kk-Cyrl-KZ",
+ "kk-AF": "kk-Arab-AF",
+ "kk-Arab": "kk-Arab-CN",
+ "kk-CN": "kk-Arab-CN",
+ "kk-IR": "kk-Arab-IR",
+ "kk-MN": "kk-Arab-MN",
+ "kkj": "kkj-Latn-CM",
+ "kl": "kl-Latn-GL",
+ "kln": "kln-Latn-KE",
+ "km": "km-Khmr-KH",
+ "kmb": "kmb-Latn-AO",
+ "kn": "kn-Knda-IN",
+ "ko": "ko-Kore-KR",
+ "koi": "koi-Cyrl-RU",
+ "kok": "kok-Deva-IN",
+ "kos": "kos-Latn-FM",
+ "kpe": "kpe-Latn-LR",
+ "krc": "krc-Cyrl-RU",
+ "kri": "kri-Latn-SL",
+ "krj": "krj-Latn-PH",
+ "krl": "krl-Latn-RU",
+ "kru": "kru-Deva-IN",
+ "ks": "ks-Arab-IN",
+ "ksb": "ksb-Latn-TZ",
+ "ksf": "ksf-Latn-CM",
+ "ksh": "ksh-Latn-DE",
+ "ku": "ku-Latn-TR",
+ "ku-Arab": "ku-Arab-IQ",
+ "ku-LB": "ku-Arab-LB",
+ "kum": "kum-Cyrl-RU",
+ "kv": "kv-Cyrl-RU",
+ "kvr": "kvr-Latn-ID",
+ "kvx": "kvx-Arab-PK",
+ "kw": "kw-Latn-GB",
+ "kxm": "kxm-Thai-TH",
+ "kxp": "kxp-Arab-PK",
+ "ky": "ky-Cyrl-KG",
+ "ky-Arab": "ky-Arab-CN",
+ "ky-CN": "ky-Arab-CN",
+ "ky-Latn": "ky-Latn-TR",
+ "ky-TR": "ky-Latn-TR",
+ "la": "la-Latn-VA",
+ "lab": "lab-Lina-GR",
+ "lad": "lad-Hebr-IL",
+ "lag": "lag-Latn-TZ",
+ "lah": "lah-Arab-PK",
+ "laj": "laj-Latn-UG",
+ "lb": "lb-Latn-LU",
+ "lbe": "lbe-Cyrl-RU",
+ "lbw": "lbw-Latn-ID",
+ "lcp": "lcp-Thai-CN",
+ "lep": "lep-Lepc-IN",
+ "lez": "lez-Cyrl-RU",
+ "lg": "lg-Latn-UG",
+ "li": "li-Latn-NL",
+ "lif": "lif-Deva-NP",
+ "lif-Limb": "lif-Limb-IN",
+ "lij": "lij-Latn-IT",
+ "lis": "lis-Lisu-CN",
+ "ljp": "ljp-Latn-ID",
+ "lki": "lki-Arab-IR",
+ "lkt": "lkt-Latn-US",
+ "lmn": "lmn-Telu-IN",
+ "lmo": "lmo-Latn-IT",
+ "ln": "ln-Latn-CD",
+ "lo": "lo-Laoo-LA",
+ "lol": "lol-Latn-CD",
+ "loz": "loz-Latn-ZM",
+ "lrc": "lrc-Arab-IR",
+ "lt": "lt-Latn-LT",
+ "ltg": "ltg-Latn-LV",
+ "lu": "lu-Latn-CD",
+ "lua": "lua-Latn-CD",
+ "luo": "luo-Latn-KE",
+ "luy": "luy-Latn-KE",
+ "luz": "luz-Arab-IR",
+ "lv": "lv-Latn-LV",
+ "lwl": "lwl-Thai-TH",
+ "lzh": "lzh-Hans-CN",
+ "lzz": "lzz-Latn-TR",
+ "mad": "mad-Latn-ID",
+ "maf": "maf-Latn-CM",
+ "mag": "mag-Deva-IN",
+ "mai": "mai-Deva-IN",
+ "mak": "mak-Latn-ID",
+ "man": "man-Latn-GM",
+ "man-GN": "man-Nkoo-GN",
+ "man-Nkoo": "man-Nkoo-GN",
+ "mas": "mas-Latn-KE",
+ "maz": "maz-Latn-MX",
+ "mdf": "mdf-Cyrl-RU",
+ "mdh": "mdh-Latn-PH",
+ "mdr": "mdr-Latn-ID",
+ "men": "men-Latn-SL",
+ "mer": "mer-Latn-KE",
+ "mfa": "mfa-Arab-TH",
+ "mfe": "mfe-Latn-MU",
+ "mg": "mg-Latn-MG",
+ "mgh": "mgh-Latn-MZ",
+ "mgo": "mgo-Latn-CM",
+ "mgp": "mgp-Deva-NP",
+ "mgy": "mgy-Latn-TZ",
+ "mh": "mh-Latn-MH",
+ "mi": "mi-Latn-NZ",
+ "min": "min-Latn-ID",
+ "mk": "mk-Cyrl-MK",
+ "ml": "ml-Mlym-IN",
+ "mn": "mn-Cyrl-MN",
+ "mn-CN": "mn-Mong-CN",
+ "mn-Mong": "mn-Mong-CN",
+ "mni": "mni-Beng-IN",
+ "mnw": "mnw-Mymr-MM",
+ "moe": "moe-Latn-CA",
+ "moh": "moh-Latn-CA",
+ "mos": "mos-Latn-BF",
+ "mr": "mr-Deva-IN",
+ "mrd": "mrd-Deva-NP",
+ "mrj": "mrj-Cyrl-RU",
+ "mru": "mru-Mroo-BD",
+ "ms": "ms-Latn-MY",
+ "ms-CC": "ms-Arab-CC",
+ "ms-ID": "ms-Arab-ID",
+ "mt": "mt-Latn-MT",
+ "mtr": "mtr-Deva-IN",
+ "mua": "mua-Latn-CM",
+ "mus": "mus-Latn-US",
+ "mvy": "mvy-Arab-PK",
+ "mwk": "mwk-Latn-ML",
+ "mwr": "mwr-Deva-IN",
+ "mwv": "mwv-Latn-ID",
+ "mxc": "mxc-Latn-ZW",
+ "my": "my-Mymr-MM",
+ "myv": "myv-Cyrl-RU",
+ "myx": "myx-Latn-UG",
+ "myz": "myz-Mand-IR",
+ "mzn": "mzn-Arab-IR",
+ "na": "na-Latn-NR",
+ "nan": "nan-Hans-CN",
+ "nap": "nap-Latn-IT",
+ "naq": "naq-Latn-NA",
+ "nb": "nb-Latn-NO",
+ "nch": "nch-Latn-MX",
+ "nd": "nd-Latn-ZW",
+ "ndc": "ndc-Latn-MZ",
+ "nds": "nds-Latn-DE",
+ "ne": "ne-Deva-NP",
+ "new": "new-Deva-NP",
+ "ng": "ng-Latn-NA",
+ "ngl": "ngl-Latn-MZ",
+ "nhe": "nhe-Latn-MX",
+ "nhw": "nhw-Latn-MX",
+ "nij": "nij-Latn-ID",
+ "niu": "niu-Latn-NU",
+ "njo": "njo-Latn-IN",
+ "nl": "nl-Latn-NL",
+ "nmg": "nmg-Latn-CM",
+ "nn": "nn-Latn-NO",
+ "nnh": "nnh-Latn-CM",
+ "no": "no-Latn-NO",
+ "nod": "nod-Lana-TH",
+ "noe": "noe-Deva-IN",
+ "non": "non-Runr-SE",
+ "nqo": "nqo-Nkoo-GN",
+ "nr": "nr-Latn-ZA",
+ "nsk": "nsk-Cans-CA",
+ "nso": "nso-Latn-ZA",
+ "nus": "nus-Latn-SD",
+ "nv": "nv-Latn-US",
+ "nxq": "nxq-Latn-CN",
+ "ny": "ny-Latn-MW",
+ "nym": "nym-Latn-TZ",
+ "nyn": "nyn-Latn-UG",
+ "nzi": "nzi-Latn-GH",
+ "oc": "oc-Latn-FR",
+ "om": "om-Latn-ET",
+ "or": "or-Orya-IN",
+ "os": "os-Cyrl-GE",
+ "otk": "otk-Orkh-MN",
+ "pa": "pa-Guru-IN",
+ "pa-Arab": "pa-Arab-PK",
+ "pa-PK": "pa-Arab-PK",
+ "pag": "pag-Latn-PH",
+ "pal": "pal-Phli-IR",
+ "pal-Phlp": "pal-Phlp-CN",
+ "pam": "pam-Latn-PH",
+ "pap": "pap-Latn-AW",
+ "pau": "pau-Latn-PW",
+ "pcd": "pcd-Latn-FR",
+ "pcm": "pcm-Latn-NG",
+ "pdc": "pdc-Latn-US",
+ "pdt": "pdt-Latn-CA",
+ "peo": "peo-Xpeo-IR",
+ "pfl": "pfl-Latn-DE",
+ "phn": "phn-Phnx-LB",
+ "pka": "pka-Brah-IN",
+ "pko": "pko-Latn-KE",
+ "pl": "pl-Latn-PL",
+ "pms": "pms-Latn-IT",
+ "pnt": "pnt-Grek-GR",
+ "pon": "pon-Latn-FM",
+ "pra": "pra-Khar-PK",
+ "prd": "prd-Arab-IR",
+ "prg": "prg-Latn-001",
+ "ps": "ps-Arab-AF",
+ "pt": "pt-Latn-BR",
+ "puu": "puu-Latn-GA",
+ "qu": "qu-Latn-PE",
+ "quc": "quc-Latn-GT",
+ "qug": "qug-Latn-EC",
+ "raj": "raj-Latn-IN",
+ "rcf": "rcf-Latn-RE",
+ "rej": "rej-Latn-ID",
+ "rgn": "rgn-Latn-IT",
+ "ria": "ria-Latn-IN",
+ "rif": "rif-Tfng-MA",
+ "rif-NL": "rif-Latn-NL",
+ "rjs": "rjs-Deva-NP",
+ "rkt": "rkt-Beng-BD",
+ "rm": "rm-Latn-CH",
+ "rmf": "rmf-Latn-FI",
+ "rmo": "rmo-Latn-CH",
+ "rmt": "rmt-Arab-IR",
+ "rmu": "rmu-Latn-SE",
+ "rn": "rn-Latn-BI",
+ "rng": "rng-Latn-MZ",
+ "ro": "ro-Latn-RO",
+ "rob": "rob-Latn-ID",
+ "rof": "rof-Latn-TZ",
+ "rtm": "rtm-Latn-FJ",
+ "ru": "ru-Cyrl-RU",
+ "rue": "rue-Cyrl-UA",
+ "rug": "rug-Latn-SB",
+ "rw": "rw-Latn-RW",
+ "rwk": "rwk-Latn-TZ",
+ "ryu": "ryu-Kana-JP",
+ "sa": "sa-Deva-IN",
+ "saf": "saf-Latn-GH",
+ "sah": "sah-Cyrl-RU",
+ "saq": "saq-Latn-KE",
+ "sas": "sas-Latn-ID",
+ "sat": "sat-Latn-IN",
+ "saz": "saz-Saur-IN",
+ "sbp": "sbp-Latn-TZ",
+ "sc": "sc-Latn-IT",
+ "sck": "sck-Deva-IN",
+ "scn": "scn-Latn-IT",
+ "sco": "sco-Latn-GB",
+ "scs": "scs-Latn-CA",
+ "sd": "sd-Arab-PK",
+ "sd-Deva": "sd-Deva-IN",
+ "sd-Khoj": "sd-Khoj-IN",
+ "sd-Sind": "sd-Sind-IN",
+ "sdc": "sdc-Latn-IT",
+ "se": "se-Latn-NO",
+ "sef": "sef-Latn-CI",
+ "seh": "seh-Latn-MZ",
+ "sei": "sei-Latn-MX",
+ "ses": "ses-Latn-ML",
+ "sg": "sg-Latn-CF",
+ "sga": "sga-Ogam-IE",
+ "sgs": "sgs-Latn-LT",
+ "shi": "shi-Tfng-MA",
+ "shn": "shn-Mymr-MM",
+ "si": "si-Sinh-LK",
+ "sid": "sid-Latn-ET",
+ "sk": "sk-Latn-SK",
+ "skr": "skr-Arab-PK",
+ "sl": "sl-Latn-SI",
+ "sli": "sli-Latn-PL",
+ "sly": "sly-Latn-ID",
+ "sm": "sm-Latn-WS",
+ "sma": "sma-Latn-SE",
+ "smj": "smj-Latn-SE",
+ "smn": "smn-Latn-FI",
+ "smp": "smp-Samr-IL",
+ "sms": "sms-Latn-FI",
+ "sn": "sn-Latn-ZW",
+ "snk": "snk-Latn-ML",
+ "so": "so-Latn-SO",
+ "sou": "sou-Thai-TH",
+ "sq": "sq-Latn-AL",
+ "sr": "sr-Cyrl-RS",
+ "sr-ME": "sr-Latn-ME",
+ "sr-RO": "sr-Latn-RO",
+ "sr-RU": "sr-Latn-RU",
+ "sr-TR": "sr-Latn-TR",
+ "srb": "srb-Sora-IN",
+ "srn": "srn-Latn-SR",
+ "srr": "srr-Latn-SN",
+ "srx": "srx-Deva-IN",
+ "ss": "ss-Latn-ZA",
+ "ssy": "ssy-Latn-ER",
+ "st": "st-Latn-ZA",
+ "stq": "stq-Latn-DE",
+ "su": "su-Latn-ID",
+ "suk": "suk-Latn-TZ",
+ "sus": "sus-Latn-GN",
+ "sv": "sv-Latn-SE",
+ "sw": "sw-Latn-TZ",
+ "swb": "swb-Arab-YT",
+ "swc": "swc-Latn-CD",
+ "swv": "swv-Deva-IN",
+ "sxn": "sxn-Latn-ID",
+ "syl": "syl-Beng-BD",
+ "syr": "syr-Syrc-IQ",
+ "szl": "szl-Latn-PL",
+ "ta": "ta-Taml-IN",
+ "taj": "taj-Deva-NP",
+ "tbw": "tbw-Latn-PH",
+ "tcy": "tcy-Knda-IN",
+ "tdd": "tdd-Tale-CN",
+ "tdg": "tdg-Deva-NP",
+ "tdh": "tdh-Deva-NP",
+ "te": "te-Telu-IN",
+ "tem": "tem-Latn-SL",
+ "teo": "teo-Latn-UG",
+ "tet": "tet-Latn-TL",
+ "tg": "tg-Cyrl-TJ",
+ "tg-Arab": "tg-Arab-PK",
+ "tg-PK": "tg-Arab-PK",
+ "th": "th-Thai-TH",
+ "thl": "thl-Deva-NP",
+ "thq": "thq-Deva-NP",
+ "thr": "thr-Deva-NP",
+ "ti": "ti-Ethi-ET",
+ "tig": "tig-Ethi-ER",
+ "tiv": "tiv-Latn-NG",
+ "tk": "tk-Latn-TM",
+ "tkl": "tkl-Latn-TK",
+ "tkr": "tkr-Latn-AZ",
+ "tkt": "tkt-Deva-NP",
+ "tl": "tl-Latn-PH",
+ "tly": "tly-Latn-AZ",
+ "tmh": "tmh-Latn-NE",
+ "tn": "tn-Latn-ZA",
+ "to": "to-Latn-TO",
+ "tog": "tog-Latn-MW",
+ "tpi": "tpi-Latn-PG",
+ "tr": "tr-Latn-TR",
+ "tru": "tru-Latn-TR",
+ "trv": "trv-Latn-TW",
+ "ts": "ts-Latn-ZA",
+ "tsd": "tsd-Grek-GR",
+ "tsf": "tsf-Deva-NP",
+ "tsg": "tsg-Latn-PH",
+ "tsj": "tsj-Tibt-BT",
+ "tt": "tt-Cyrl-RU",
+ "ttj": "ttj-Latn-UG",
+ "tts": "tts-Thai-TH",
+ "ttt": "ttt-Latn-AZ",
+ "tum": "tum-Latn-MW",
+ "tvl": "tvl-Latn-TV",
+ "twq": "twq-Latn-NE",
+ "ty": "ty-Latn-PF",
+ "tyv": "tyv-Cyrl-RU",
+ "tzm": "tzm-Latn-MA",
+ "udm": "udm-Cyrl-RU",
+ "ug": "ug-Arab-CN",
+ "ug-Cyrl": "ug-Cyrl-KZ",
+ "ug-KZ": "ug-Cyrl-KZ",
+ "ug-MN": "ug-Cyrl-MN",
+ "uga": "uga-Ugar-SY",
+ "uk": "uk-Cyrl-UA",
+ "uli": "uli-Latn-FM",
+ "umb": "umb-Latn-AO",
+ "und": "en-Latn-US",
+ "und-002": "en-Latn-NG",
+ "und-003": "en-Latn-US",
+ "und-005": "pt-Latn-BR",
+ "und-009": "en-Latn-AU",
+ "und-011": "en-Latn-NG",
+ "und-013": "es-Latn-MX",
+ "und-014": "sw-Latn-TZ",
+ "und-015": "ar-Arab-EG",
+ "und-017": "sw-Latn-CD",
+ "und-018": "en-Latn-ZA",
+ "und-019": "en-Latn-US",
+ "und-021": "en-Latn-US",
+ "und-029": "es-Latn-CU",
+ "und-030": "zh-Hans-CN",
+ "und-034": "hi-Deva-IN",
+ "und-035": "id-Latn-ID",
+ "und-039": "it-Latn-IT",
+ "und-053": "en-Latn-AU",
+ "und-054": "en-Latn-PG",
+ "und-057": "en-Latn-GU",
+ "und-061": "sm-Latn-WS",
+ "und-142": "zh-Hans-CN",
+ "und-143": "uz-Latn-UZ",
+ "und-145": "ar-Arab-SA",
+ "und-150": "ru-Cyrl-RU",
+ "und-151": "ru-Cyrl-RU",
+ "und-154": "en-Latn-GB",
+ "und-155": "de-Latn-DE",
+ "und-419": "es-Latn-419",
+ "und-AD": "ca-Latn-AD",
+ "und-AE": "ar-Arab-AE",
+ "und-AF": "fa-Arab-AF",
+ "und-AL": "sq-Latn-AL",
+ "und-AM": "hy-Armn-AM",
+ "und-AO": "pt-Latn-AO",
+ "und-AQ": "und-Latn-AQ",
+ "und-AR": "es-Latn-AR",
+ "und-AS": "sm-Latn-AS",
+ "und-AT": "de-Latn-AT",
+ "und-AW": "nl-Latn-AW",
+ "und-AX": "sv-Latn-AX",
+ "und-AZ": "az-Latn-AZ",
+ "und-Aghb": "lez-Aghb-RU",
+ "und-Arab": "ar-Arab-EG",
+ "und-Arab-CC": "ms-Arab-CC",
+ "und-Arab-CN": "ug-Arab-CN",
+ "und-Arab-GB": "ks-Arab-GB",
+ "und-Arab-ID": "ms-Arab-ID",
+ "und-Arab-IN": "ur-Arab-IN",
+ "und-Arab-KH": "cja-Arab-KH",
+ "und-Arab-MN": "kk-Arab-MN",
+ "und-Arab-MU": "ur-Arab-MU",
+ "und-Arab-NG": "ha-Arab-NG",
+ "und-Arab-PK": "ur-Arab-PK",
+ "und-Arab-TH": "mfa-Arab-TH",
+ "und-Arab-TJ": "fa-Arab-TJ",
+ "und-Arab-YT": "swb-Arab-YT",
+ "und-Armi": "arc-Armi-IR",
+ "und-Armn": "hy-Armn-AM",
+ "und-Avst": "ae-Avst-IR",
+ "und-BA": "bs-Latn-BA",
+ "und-BD": "bn-Beng-BD",
+ "und-BE": "nl-Latn-BE",
+ "und-BF": "fr-Latn-BF",
+ "und-BG": "bg-Cyrl-BG",
+ "und-BH": "ar-Arab-BH",
+ "und-BI": "rn-Latn-BI",
+ "und-BJ": "fr-Latn-BJ",
+ "und-BL": "fr-Latn-BL",
+ "und-BN": "ms-Latn-BN",
+ "und-BO": "es-Latn-BO",
+ "und-BQ": "pap-Latn-BQ",
+ "und-BR": "pt-Latn-BR",
+ "und-BT": "dz-Tibt-BT",
+ "und-BV": "und-Latn-BV",
+ "und-BY": "be-Cyrl-BY",
+ "und-Bali": "ban-Bali-ID",
+ "und-Bamu": "bax-Bamu-CM",
+ "und-Bass": "bsq-Bass-LR",
+ "und-Batk": "bbc-Batk-ID",
+ "und-Beng": "bn-Beng-BD",
+ "und-Bopo": "zh-Bopo-TW",
+ "und-Brah": "pka-Brah-IN",
+ "und-Brai": "fr-Brai-FR",
+ "und-Bugi": "bug-Bugi-ID",
+ "und-Buhd": "bku-Buhd-PH",
+ "und-CD": "sw-Latn-CD",
+ "und-CF": "fr-Latn-CF",
+ "und-CG": "fr-Latn-CG",
+ "und-CH": "de-Latn-CH",
+ "und-CI": "fr-Latn-CI",
+ "und-CL": "es-Latn-CL",
+ "und-CM": "fr-Latn-CM",
+ "und-CN": "zh-Hans-CN",
+ "und-CO": "es-Latn-CO",
+ "und-CP": "und-Latn-CP",
+ "und-CR": "es-Latn-CR",
+ "und-CU": "es-Latn-CU",
+ "und-CV": "pt-Latn-CV",
+ "und-CW": "pap-Latn-CW",
+ "und-CY": "el-Grek-CY",
+ "und-CZ": "cs-Latn-CZ",
+ "und-Cakm": "ccp-Cakm-BD",
+ "und-Cans": "cr-Cans-CA",
+ "und-Cari": "xcr-Cari-TR",
+ "und-Cham": "cjm-Cham-VN",
+ "und-Cher": "chr-Cher-US",
+ "und-Copt": "cop-Copt-EG",
+ "und-Cprt": "grc-Cprt-CY",
+ "und-Cyrl": "ru-Cyrl-RU",
+ "und-Cyrl-AL": "mk-Cyrl-AL",
+ "und-Cyrl-BA": "sr-Cyrl-BA",
+ "und-Cyrl-GE": "ab-Cyrl-GE",
+ "und-Cyrl-GR": "mk-Cyrl-GR",
+ "und-Cyrl-MD": "uk-Cyrl-MD",
+ "und-Cyrl-PL": "be-Cyrl-PL",
+ "und-Cyrl-RO": "bg-Cyrl-RO",
+ "und-Cyrl-SK": "uk-Cyrl-SK",
+ "und-Cyrl-TR": "kbd-Cyrl-TR",
+ "und-Cyrl-XK": "sr-Cyrl-XK",
+ "und-DE": "de-Latn-DE",
+ "und-DJ": "aa-Latn-DJ",
+ "und-DK": "da-Latn-DK",
+ "und-DO": "es-Latn-DO",
+ "und-DZ": "ar-Arab-DZ",
+ "und-Deva": "hi-Deva-IN",
+ "und-Deva-BT": "ne-Deva-BT",
+ "und-Deva-FJ": "hif-Deva-FJ",
+ "und-Deva-MU": "bho-Deva-MU",
+ "und-Deva-PK": "btv-Deva-PK",
+ "und-Dupl": "fr-Dupl-FR",
+ "und-EA": "es-Latn-EA",
+ "und-EC": "es-Latn-EC",
+ "und-EE": "et-Latn-EE",
+ "und-EG": "ar-Arab-EG",
+ "und-EH": "ar-Arab-EH",
+ "und-ER": "ti-Ethi-ER",
+ "und-ES": "es-Latn-ES",
+ "und-ET": "am-Ethi-ET",
+ "und-EU": "en-Latn-GB",
+ "und-Egyp": "egy-Egyp-EG",
+ "und-Elba": "sq-Elba-AL",
+ "und-Ethi": "am-Ethi-ET",
+ "und-FI": "fi-Latn-FI",
+ "und-FO": "fo-Latn-FO",
+ "und-FR": "fr-Latn-FR",
+ "und-GA": "fr-Latn-GA",
+ "und-GE": "ka-Geor-GE",
+ "und-GF": "fr-Latn-GF",
+ "und-GH": "ak-Latn-GH",
+ "und-GL": "kl-Latn-GL",
+ "und-GN": "fr-Latn-GN",
+ "und-GP": "fr-Latn-GP",
+ "und-GQ": "es-Latn-GQ",
+ "und-GR": "el-Grek-GR",
+ "und-GS": "und-Latn-GS",
+ "und-GT": "es-Latn-GT",
+ "und-GW": "pt-Latn-GW",
+ "und-Geor": "ka-Geor-GE",
+ "und-Glag": "cu-Glag-BG",
+ "und-Goth": "got-Goth-UA",
+ "und-Gran": "sa-Gran-IN",
+ "und-Grek": "el-Grek-GR",
+ "und-Grek-TR": "bgx-Grek-TR",
+ "und-Gujr": "gu-Gujr-IN",
+ "und-Guru": "pa-Guru-IN",
+ "und-HK": "zh-Hant-HK",
+ "und-HM": "und-Latn-HM",
+ "und-HN": "es-Latn-HN",
+ "und-HR": "hr-Latn-HR",
+ "und-HT": "ht-Latn-HT",
+ "und-HU": "hu-Latn-HU",
+ "und-Hang": "ko-Hang-KR",
+ "und-Hani": "zh-Hani-CN",
+ "und-Hano": "hnn-Hano-PH",
+ "und-Hans": "zh-Hans-CN",
+ "und-Hant": "zh-Hant-TW",
+ "und-Hebr": "he-Hebr-IL",
+ "und-Hebr-CA": "yi-Hebr-CA",
+ "und-Hebr-GB": "yi-Hebr-GB",
+ "und-Hebr-SE": "yi-Hebr-SE",
+ "und-Hebr-UA": "yi-Hebr-UA",
+ "und-Hebr-US": "yi-Hebr-US",
+ "und-Hira": "ja-Hira-JP",
+ "und-Hmng": "hnj-Hmng-LA",
+ "und-IC": "es-Latn-IC",
+ "und-ID": "id-Latn-ID",
+ "und-IL": "he-Hebr-IL",
+ "und-IN": "hi-Deva-IN",
+ "und-IQ": "ar-Arab-IQ",
+ "und-IR": "fa-Arab-IR",
+ "und-IS": "is-Latn-IS",
+ "und-IT": "it-Latn-IT",
+ "und-Ital": "ett-Ital-IT",
+ "und-JO": "ar-Arab-JO",
+ "und-JP": "ja-Jpan-JP",
+ "und-Java": "jv-Java-ID",
+ "und-Jpan": "ja-Jpan-JP",
+ "und-KE": "sw-Latn-KE",
+ "und-KG": "ky-Cyrl-KG",
+ "und-KH": "km-Khmr-KH",
+ "und-KM": "ar-Arab-KM",
+ "und-KP": "ko-Kore-KP",
+ "und-KR": "ko-Kore-KR",
+ "und-KW": "ar-Arab-KW",
+ "und-KZ": "ru-Cyrl-KZ",
+ "und-Kali": "eky-Kali-MM",
+ "und-Kana": "ja-Kana-JP",
+ "und-Khar": "pra-Khar-PK",
+ "und-Khmr": "km-Khmr-KH",
+ "und-Khoj": "sd-Khoj-IN",
+ "und-Knda": "kn-Knda-IN",
+ "und-Kore": "ko-Kore-KR",
+ "und-Kthi": "bh-Kthi-IN",
+ "und-LA": "lo-Laoo-LA",
+ "und-LB": "ar-Arab-LB",
+ "und-LI": "de-Latn-LI",
+ "und-LK": "si-Sinh-LK",
+ "und-LS": "st-Latn-LS",
+ "und-LT": "lt-Latn-LT",
+ "und-LU": "fr-Latn-LU",
+ "und-LV": "lv-Latn-LV",
+ "und-LY": "ar-Arab-LY",
+ "und-Lana": "nod-Lana-TH",
+ "und-Laoo": "lo-Laoo-LA",
+ "und-Latn-AF": "tk-Latn-AF",
+ "und-Latn-AM": "ku-Latn-AM",
+ "und-Latn-CN": "za-Latn-CN",
+ "und-Latn-CY": "tr-Latn-CY",
+ "und-Latn-DZ": "fr-Latn-DZ",
+ "und-Latn-ET": "en-Latn-ET",
+ "und-Latn-GE": "ku-Latn-GE",
+ "und-Latn-IR": "tk-Latn-IR",
+ "und-Latn-KM": "fr-Latn-KM",
+ "und-Latn-MA": "fr-Latn-MA",
+ "und-Latn-MK": "sq-Latn-MK",
+ "und-Latn-MM": "kac-Latn-MM",
+ "und-Latn-MO": "pt-Latn-MO",
+ "und-Latn-MR": "fr-Latn-MR",
+ "und-Latn-RU": "krl-Latn-RU",
+ "und-Latn-SY": "fr-Latn-SY",
+ "und-Latn-TN": "fr-Latn-TN",
+ "und-Latn-TW": "trv-Latn-TW",
+ "und-Latn-UA": "pl-Latn-UA",
+ "und-Lepc": "lep-Lepc-IN",
+ "und-Limb": "lif-Limb-IN",
+ "und-Lina": "lab-Lina-GR",
+ "und-Linb": "grc-Linb-GR",
+ "und-Lisu": "lis-Lisu-CN",
+ "und-Lyci": "xlc-Lyci-TR",
+ "und-Lydi": "xld-Lydi-TR",
+ "und-MA": "ar-Arab-MA",
+ "und-MC": "fr-Latn-MC",
+ "und-MD": "ro-Latn-MD",
+ "und-ME": "sr-Latn-ME",
+ "und-MF": "fr-Latn-MF",
+ "und-MG": "mg-Latn-MG",
+ "und-MK": "mk-Cyrl-MK",
+ "und-ML": "bm-Latn-ML",
+ "und-MM": "my-Mymr-MM",
+ "und-MN": "mn-Cyrl-MN",
+ "und-MO": "zh-Hant-MO",
+ "und-MQ": "fr-Latn-MQ",
+ "und-MR": "ar-Arab-MR",
+ "und-MT": "mt-Latn-MT",
+ "und-MU": "mfe-Latn-MU",
+ "und-MV": "dv-Thaa-MV",
+ "und-MX": "es-Latn-MX",
+ "und-MY": "ms-Latn-MY",
+ "und-MZ": "pt-Latn-MZ",
+ "und-Mahj": "hi-Mahj-IN",
+ "und-Mand": "myz-Mand-IR",
+ "und-Mani": "xmn-Mani-CN",
+ "und-Mend": "men-Mend-SL",
+ "und-Merc": "xmr-Merc-SD",
+ "und-Mero": "xmr-Mero-SD",
+ "und-Mlym": "ml-Mlym-IN",
+ "und-Modi": "mr-Modi-IN",
+ "und-Mong": "mn-Mong-CN",
+ "und-Mroo": "mru-Mroo-BD",
+ "und-Mtei": "mni-Mtei-IN",
+ "und-Mymr": "my-Mymr-MM",
+ "und-Mymr-IN": "kht-Mymr-IN",
+ "und-Mymr-TH": "mnw-Mymr-TH",
+ "und-NA": "af-Latn-NA",
+ "und-NC": "fr-Latn-NC",
+ "und-NE": "ha-Latn-NE",
+ "und-NI": "es-Latn-NI",
+ "und-NL": "nl-Latn-NL",
+ "und-NO": "nb-Latn-NO",
+ "und-NP": "ne-Deva-NP",
+ "und-Narb": "xna-Narb-SA",
+ "und-Nbat": "arc-Nbat-JO",
+ "und-Nkoo": "man-Nkoo-GN",
+ "und-OM": "ar-Arab-OM",
+ "und-Ogam": "sga-Ogam-IE",
+ "und-Olck": "sat-Olck-IN",
+ "und-Orkh": "otk-Orkh-MN",
+ "und-Orya": "or-Orya-IN",
+ "und-Osma": "so-Osma-SO",
+ "und-PA": "es-Latn-PA",
+ "und-PE": "es-Latn-PE",
+ "und-PF": "fr-Latn-PF",
+ "und-PG": "tpi-Latn-PG",
+ "und-PH": "fil-Latn-PH",
+ "und-PK": "ur-Arab-PK",
+ "und-PL": "pl-Latn-PL",
+ "und-PM": "fr-Latn-PM",
+ "und-PR": "es-Latn-PR",
+ "und-PS": "ar-Arab-PS",
+ "und-PT": "pt-Latn-PT",
+ "und-PW": "pau-Latn-PW",
+ "und-PY": "gn-Latn-PY",
+ "und-Palm": "arc-Palm-SY",
+ "und-Pauc": "ctd-Pauc-MM",
+ "und-Perm": "kv-Perm-RU",
+ "und-Phag": "lzh-Phag-CN",
+ "und-Phli": "pal-Phli-IR",
+ "und-Phlp": "pal-Phlp-CN",
+ "und-Phnx": "phn-Phnx-LB",
+ "und-Plrd": "hmd-Plrd-CN",
+ "und-Prti": "xpr-Prti-IR",
+ "und-QA": "ar-Arab-QA",
+ "und-QO": "en-Latn-IO",
+ "und-RE": "fr-Latn-RE",
+ "und-RO": "ro-Latn-RO",
+ "und-RS": "sr-Cyrl-RS",
+ "und-RU": "ru-Cyrl-RU",
+ "und-RW": "rw-Latn-RW",
+ "und-Rjng": "rej-Rjng-ID",
+ "und-Runr": "non-Runr-SE",
+ "und-SA": "ar-Arab-SA",
+ "und-SC": "fr-Latn-SC",
+ "und-SD": "ar-Arab-SD",
+ "und-SE": "sv-Latn-SE",
+ "und-SI": "sl-Latn-SI",
+ "und-SJ": "nb-Latn-SJ",
+ "und-SK": "sk-Latn-SK",
+ "und-SM": "it-Latn-SM",
+ "und-SN": "fr-Latn-SN",
+ "und-SO": "so-Latn-SO",
+ "und-SR": "nl-Latn-SR",
+ "und-ST": "pt-Latn-ST",
+ "und-SV": "es-Latn-SV",
+ "und-SY": "ar-Arab-SY",
+ "und-Samr": "smp-Samr-IL",
+ "und-Sarb": "xsa-Sarb-YE",
+ "und-Saur": "saz-Saur-IN",
+ "und-Shaw": "en-Shaw-GB",
+ "und-Shrd": "sa-Shrd-IN",
+ "und-Sidd": "sa-Sidd-IN",
+ "und-Sind": "sd-Sind-IN",
+ "und-Sinh": "si-Sinh-LK",
+ "und-Sora": "srb-Sora-IN",
+ "und-Sund": "su-Sund-ID",
+ "und-Sylo": "syl-Sylo-BD",
+ "und-Syrc": "syr-Syrc-IQ",
+ "und-TD": "fr-Latn-TD",
+ "und-TF": "fr-Latn-TF",
+ "und-TG": "fr-Latn-TG",
+ "und-TH": "th-Thai-TH",
+ "und-TJ": "tg-Cyrl-TJ",
+ "und-TK": "tkl-Latn-TK",
+ "und-TL": "pt-Latn-TL",
+ "und-TM": "tk-Latn-TM",
+ "und-TN": "ar-Arab-TN",
+ "und-TO": "to-Latn-TO",
+ "und-TR": "tr-Latn-TR",
+ "und-TV": "tvl-Latn-TV",
+ "und-TW": "zh-Hant-TW",
+ "und-TZ": "sw-Latn-TZ",
+ "und-Tagb": "tbw-Tagb-PH",
+ "und-Takr": "doi-Takr-IN",
+ "und-Tale": "tdd-Tale-CN",
+ "und-Talu": "khb-Talu-CN",
+ "und-Taml": "ta-Taml-IN",
+ "und-Tavt": "blt-Tavt-VN",
+ "und-Telu": "te-Telu-IN",
+ "und-Tfng": "zgh-Tfng-MA",
+ "und-Tglg": "fil-Tglg-PH",
+ "und-Thaa": "dv-Thaa-MV",
+ "und-Thai": "th-Thai-TH",
+ "und-Thai-CN": "lcp-Thai-CN",
+ "und-Thai-KH": "kdt-Thai-KH",
+ "und-Thai-LA": "kdt-Thai-LA",
+ "und-Tibt": "bo-Tibt-CN",
+ "und-Tirh": "mai-Tirh-IN",
+ "und-UA": "uk-Cyrl-UA",
+ "und-UG": "sw-Latn-UG",
+ "und-UY": "es-Latn-UY",
+ "und-UZ": "uz-Latn-UZ",
+ "und-Ugar": "uga-Ugar-SY",
+ "und-VA": "it-Latn-VA",
+ "und-VE": "es-Latn-VE",
+ "und-VN": "vi-Latn-VN",
+ "und-VU": "bi-Latn-VU",
+ "und-Vaii": "vai-Vaii-LR",
+ "und-WF": "fr-Latn-WF",
+ "und-WS": "sm-Latn-WS",
+ "und-Wara": "hoc-Wara-IN",
+ "und-XK": "sq-Latn-XK",
+ "und-Xpeo": "peo-Xpeo-IR",
+ "und-Xsux": "akk-Xsux-IQ",
+ "und-YE": "ar-Arab-YE",
+ "und-YT": "fr-Latn-YT",
+ "und-Yiii": "ii-Yiii-CN",
+ "und-ZW": "sn-Latn-ZW",
+ "unr": "unr-Beng-IN",
+ "unr-Deva": "unr-Deva-NP",
+ "unr-NP": "unr-Deva-NP",
+ "unx": "unx-Beng-IN",
+ "ur": "ur-Arab-PK",
+ "uz": "uz-Latn-UZ",
+ "uz-AF": "uz-Arab-AF",
+ "uz-Arab": "uz-Arab-AF",
+ "uz-CN": "uz-Cyrl-CN",
+ "vai": "vai-Vaii-LR",
+ "ve": "ve-Latn-ZA",
+ "vec": "vec-Latn-IT",
+ "vep": "vep-Latn-RU",
+ "vi": "vi-Latn-VN",
+ "vic": "vic-Latn-SX",
+ "vls": "vls-Latn-BE",
+ "vmf": "vmf-Latn-DE",
+ "vmw": "vmw-Latn-MZ",
+ "vo": "vo-Latn-001",
+ "vot": "vot-Latn-RU",
+ "vro": "vro-Latn-EE",
+ "vun": "vun-Latn-TZ",
+ "wa": "wa-Latn-BE",
+ "wae": "wae-Latn-CH",
+ "wal": "wal-Ethi-ET",
+ "war": "war-Latn-PH",
+ "wbp": "wbp-Latn-AU",
+ "wbq": "wbq-Telu-IN",
+ "wbr": "wbr-Deva-IN",
+ "wls": "wls-Latn-WF",
+ "wo": "wo-Latn-SN",
+ "wtm": "wtm-Deva-IN",
+ "wuu": "wuu-Hans-CN",
+ "xav": "xav-Latn-BR",
+ "xcr": "xcr-Cari-TR",
+ "xh": "xh-Latn-ZA",
+ "xlc": "xlc-Lyci-TR",
+ "xld": "xld-Lydi-TR",
+ "xmf": "xmf-Geor-GE",
+ "xmn": "xmn-Mani-CN",
+ "xmr": "xmr-Merc-SD",
+ "xna": "xna-Narb-SA",
+ "xnr": "xnr-Deva-IN",
+ "xog": "xog-Latn-UG",
+ "xpr": "xpr-Prti-IR",
+ "xsa": "xsa-Sarb-YE",
+ "xsr": "xsr-Deva-NP",
+ "yao": "yao-Latn-MZ",
+ "yap": "yap-Latn-FM",
+ "yav": "yav-Latn-CM",
+ "ybb": "ybb-Latn-CM",
+ "yi": "yi-Hebr-001",
+ "yo": "yo-Latn-NG",
+ "yrl": "yrl-Latn-BR",
+ "yua": "yua-Latn-MX",
+ "za": "za-Latn-CN",
+ "zdj": "zdj-Arab-KM",
+ "zea": "zea-Latn-NL",
+ "zgh": "zgh-Tfng-MA",
+ "zh": "zh-Hans-CN",
+ "zh-AU": "zh-Hant-AU",
+ "zh-BN": "zh-Hant-BN",
+ "zh-Bopo": "zh-Bopo-TW",
+ "zh-GB": "zh-Hant-GB",
+ "zh-GF": "zh-Hant-GF",
+ "zh-HK": "zh-Hant-HK",
+ "zh-Hant": "zh-Hant-TW",
+ "zh-ID": "zh-Hant-ID",
+ "zh-MO": "zh-Hant-MO",
+ "zh-MY": "zh-Hant-MY",
+ "zh-PA": "zh-Hant-PA",
+ "zh-PF": "zh-Hant-PF",
+ "zh-PH": "zh-Hant-PH",
+ "zh-SR": "zh-Hant-SR",
+ "zh-TH": "zh-Hant-TH",
+ "zh-TW": "zh-Hant-TW",
+ "zh-US": "zh-Hant-US",
+ "zh-VN": "zh-Hant-VN",
+ "zmi": "zmi-Latn-MY",
+ "zu": "zu-Latn-ZA",
+ "zza": "zza-Latn-TR"
+ }
+ }
+});
+
+Globalize.load({
+ "supplemental": {
+ "version": {
+ "_unicodeVersion": "7.0.0",
+ "_number": "$Revision: 11318 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $"
+ },
+ "timeData": {
+ "001": {
+ "_allowed": "H h",
+ "_preferred": "H"
+ },
+ "AD": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "AE": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "AG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "AL": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "AM": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "AO": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "AS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "AT": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "AU": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "AW": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "AX": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BB": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BD": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BF": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BH": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BJ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BL": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BN": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BQ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BR": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "BS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BT": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "BW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "CA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "CD": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "CG": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "CI": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "CN": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "CO": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "CP": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "CV": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "CY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "CZ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "DE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "DJ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "DK": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "DM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "DZ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "EE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "EG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "EH": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ER": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ET": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "FI": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "FJ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "FM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "FR": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GA": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GD": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GF": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GH": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GL": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GN": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GP": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GR": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GU": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "GW": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "GY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "HK": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "HR": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "ID": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "IL": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "IN": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "IQ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "IS": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "IT": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "JM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "JO": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "JP": {
+ "_allowed": "H K h",
+ "_preferred": "H"
+ },
+ "KH": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KI": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KN": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KP": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KR": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "KY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "LB": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "LC": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "LR": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "LS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "LY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MC": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "MD": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "MF": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "MH": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ML": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "MO": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MP": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MQ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "MR": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "MZ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "NA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "NC": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "NE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "NG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "NL": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "NZ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "OM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "PG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "PK": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "PM": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "PR": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "PS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "PT": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "PW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "QA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "RE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "RO": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "RU": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SB": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SD": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SE": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SI": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SJ": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SK": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SL": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SM": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SO": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SR": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ST": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "SY": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "SZ": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "TC": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "TD": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "TG": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "TN": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "TR": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "TT": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "TW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "UM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "US": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "VC": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "VG": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "VI": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "VU": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "WF": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "WS": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "YE": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "YT": {
+ "_allowed": "H",
+ "_preferred": "H"
+ },
+ "ZA": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ZM": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ },
+ "ZW": {
+ "_allowed": "H h",
+ "_preferred": "h"
+ }
+ }
+ }
+});
+
+Globalize.load({
+ "supplemental": {
+ "version": {
+ "_unicodeVersion": "7.0.0",
+ "_number": "$Revision: 11318 $"
+ },
+ "generation": {
+ "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $"
+ },
+ "weekData": {
+ "minDays": {
+ "001": "1",
+ "GU": "1",
+ "UM": "1",
+ "US": "1",
+ "VI": "1",
+ "AD": "4",
+ "AN": "4",
+ "AT": "4",
+ "AX": "4",
+ "BE": "4",
+ "BG": "4",
+ "CH": "4",
+ "CZ": "4",
+ "DE": "4",
+ "DK": "4",
+ "EE": "4",
+ "ES": "4",
+ "FI": "4",
+ "FJ": "4",
+ "FO": "4",
+ "FR": "4",
+ "GB": "4",
+ "GF": "4",
+ "GG": "4",
+ "GI": "4",
+ "GP": "4",
+ "GR": "4",
+ "HU": "4",
+ "IE": "4",
+ "IM": "4",
+ "IS": "4",
+ "IT": "4",
+ "JE": "4",
+ "LI": "4",
+ "LT": "4",
+ "LU": "4",
+ "MC": "4",
+ "MQ": "4",
+ "NL": "4",
+ "NO": "4",
+ "PL": "4",
+ "PT": "4",
+ "RE": "4",
+ "SE": "4",
+ "SJ": "4",
+ "SK": "4",
+ "SM": "4",
+ "VA": "4"
+ },
+ "firstDay": {
+ "001": "mon",
+ "AD": "mon",
+ "AI": "mon",
+ "AL": "mon",
+ "AM": "mon",
+ "AN": "mon",
+ "AT": "mon",
+ "AX": "mon",
+ "AZ": "mon",
+ "BA": "mon",
+ "BE": "mon",
+ "BG": "mon",
+ "BM": "mon",
+ "BN": "mon",
+ "BY": "mon",
+ "CH": "mon",
+ "CL": "mon",
+ "CM": "mon",
+ "CR": "mon",
+ "CY": "mon",
+ "CZ": "mon",
+ "DE": "mon",
+ "DK": "mon",
+ "EC": "mon",
+ "EE": "mon",
+ "ES": "mon",
+ "FI": "mon",
+ "FJ": "mon",
+ "FO": "mon",
+ "FR": "mon",
+ "GB": "mon",
+ "GE": "mon",
+ "GF": "mon",
+ "GP": "mon",
+ "GR": "mon",
+ "HR": "mon",
+ "HU": "mon",
+ "IS": "mon",
+ "IT": "mon",
+ "KG": "mon",
+ "KZ": "mon",
+ "LB": "mon",
+ "LI": "mon",
+ "LK": "mon",
+ "LT": "mon",
+ "LU": "mon",
+ "LV": "mon",
+ "MC": "mon",
+ "MD": "mon",
+ "ME": "mon",
+ "MK": "mon",
+ "MN": "mon",
+ "MQ": "mon",
+ "MY": "mon",
+ "NL": "mon",
+ "NO": "mon",
+ "PL": "mon",
+ "PT": "mon",
+ "RE": "mon",
+ "RO": "mon",
+ "RS": "mon",
+ "RU": "mon",
+ "SE": "mon",
+ "SI": "mon",
+ "SK": "mon",
+ "SM": "mon",
+ "TJ": "mon",
+ "TM": "mon",
+ "TR": "mon",
+ "UA": "mon",
+ "UY": "mon",
+ "UZ": "mon",
+ "VA": "mon",
+ "VN": "mon",
+ "XK": "mon",
+ "AE": "sat",
+ "AF": "sat",
+ "BH": "sat",
+ "DJ": "sat",
+ "DZ": "sat",
+ "EG": "sat",
+ "IQ": "sat",
+ "IR": "sat",
+ "JO": "sat",
+ "KW": "sat",
+ "LY": "sat",
+ "MA": "sat",
+ "OM": "sat",
+ "QA": "sat",
+ "SD": "sat",
+ "SY": "sat",
+ "AG": "sun",
+ "AR": "sun",
+ "AS": "sun",
+ "AU": "sun",
+ "BR": "sun",
+ "BS": "sun",
+ "BT": "sun",
+ "BW": "sun",
+ "BZ": "sun",
+ "CA": "sun",
+ "CN": "sun",
+ "CO": "sun",
+ "DM": "sun",
+ "DO": "sun",
+ "ET": "sun",
+ "GT": "sun",
+ "GU": "sun",
+ "HK": "sun",
+ "HN": "sun",
+ "ID": "sun",
+ "IE": "sun",
+ "IL": "sun",
+ "IN": "sun",
+ "JM": "sun",
+ "JP": "sun",
+ "KE": "sun",
+ "KH": "sun",
+ "KR": "sun",
+ "LA": "sun",
+ "MH": "sun",
+ "MM": "sun",
+ "MO": "sun",
+ "MT": "sun",
+ "MX": "sun",
+ "MZ": "sun",
+ "NI": "sun",
+ "NP": "sun",
+ "NZ": "sun",
+ "PA": "sun",
+ "PE": "sun",
+ "PH": "sun",
+ "PK": "sun",
+ "PR": "sun",
+ "PY": "sun",
+ "SA": "sun",
+ "SG": "sun",
+ "SV": "sun",
+ "TH": "sun",
+ "TN": "sun",
+ "TT": "sun",
+ "TW": "sun",
+ "UM": "sun",
+ "US": "sun",
+ "VE": "sun",
+ "VI": "sun",
+ "WS": "sun",
+ "YE": "sun",
+ "ZA": "sun",
+ "ZW": "sun",
+ "BD": "fri",
+ "MV": "fri"
+ },
+ "firstDay-alt-variant": {
+ "GB": "sun"
+ },
+ "weekendStart": {
+ "001": "sat",
+ "AE": "fri",
+ "BH": "fri",
+ "DZ": "fri",
+ "EG": "fri",
+ "IL": "fri",
+ "IQ": "fri",
+ "IR": "fri",
+ "JO": "fri",
+ "KW": "fri",
+ "LY": "fri",
+ "MA": "fri",
+ "OM": "fri",
+ "QA": "fri",
+ "SA": "fri",
+ "SD": "fri",
+ "SY": "fri",
+ "TN": "fri",
+ "YE": "fri",
+ "AF": "thu",
+ "IN": "sun"
+ },
+ "weekendEnd": {
+ "001": "sun",
+ "AE": "sat",
+ "BH": "sat",
+ "DZ": "sat",
+ "EG": "sat",
+ "IL": "sat",
+ "IQ": "sat",
+ "JO": "sat",
+ "KW": "sat",
+ "LY": "sat",
+ "MA": "sat",
+ "OM": "sat",
+ "QA": "sat",
+ "SA": "sat",
+ "SD": "sat",
+ "SY": "sat",
+ "TN": "sat",
+ "YE": "sat",
+ "AF": "fri",
+ "IR": "fri"
+ }
+ }
+ }
+});
+
+return Globalize;
+
+} ) );
diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js
index 47289494c..571621fa4 100644
--- a/tests/lib/bootstrap.js
+++ b/tests/lib/bootstrap.js
@@ -2,8 +2,12 @@
requirejs.config({
paths: {
+ "date": "../../../external/date",
+ "cldr": "../../../external/cldrjs/cldr",
"globalize": "../../../external/globalize/globalize",
- "globalize/ja-JP": "../../../external/globalize/globalize.culture.ja-JP",
+ "globalize-locales": "../../../external/localization",
+ "globalize-old": "../../../external/globalize-old/globalize",
+ "globalize-old/ja-JP": "../../../external/globalize-old/globalize.culture.ja-JP",
"jquery": jqueryUrl(),
"jquery-simulate": "../../../external/jquery-simulate/jquery.simulate",
"jshint": "../../../external/jshint/jshint",
@@ -16,7 +20,8 @@ requirejs.config({
"ui": "../../../ui"
},
shim: {
- "globalize/ja-JP": [ "globalize" ],
+ "date": [ "globalize-locales" ],
+ "globalize-old/ja-JP": [ "globalize-old" ],
"jquery-simulate": [ "jquery" ],
"qunit-assert-close": [ "qunit" ],
"testswarm": [ "qunit" ]
diff --git a/tests/unit/all.html b/tests/unit/all.html
index c8352615a..f06dad6d9 100644
--- a/tests/unit/all.html
+++ b/tests/unit/all.html
@@ -20,6 +20,7 @@
"autocomplete/autocomplete.html",
"button/button.html",
"core/core.html",
+ "calendar/calendar.html",
"datepicker/datepicker.html",
"dialog/dialog.html",
"draggable/draggable.html",
diff --git a/tests/unit/calendar/all.html b/tests/unit/calendar/all.html
new file mode 100644
index 000000000..65f71988b
--- /dev/null
+++ b/tests/unit/calendar/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "calendar" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html
new file mode 100644
index 000000000..0d28b6351
--- /dev/null
+++ b/tests/unit/calendar/calendar.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js" data-modules="core calendar"></script>
+ <script src="../../lib/bootstrap.js" data-widget="datepicker"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+<div id="calendar"></div>
+<div id="calendar2"></div>
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js
new file mode 100644
index 000000000..5dae54464
--- /dev/null
+++ b/tests/unit/calendar/common.js
@@ -0,0 +1,33 @@
+define( [
+ "lib/common",
+ "ui/widgets/calendar",
+ "globalize-locales"
+], function( common ) {
+
+common.testWidget( "calendar", {
+ defaults: {
+ buttons: [],
+ classes: {},
+ disabled: false,
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ showWeek: false,
+ value: null,
+
+ // callbacks
+ create: null,
+ select: null
+ }
+});
+
+} );
diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js
new file mode 100644
index 000000000..23e5da43a
--- /dev/null
+++ b/tests/unit/calendar/core.js
@@ -0,0 +1,392 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: core" );
+
+test( "base structure", function() {
+ expect( 26 );
+
+ var header, title, table, thead, week, child, buttonpane,
+ element = $( "#calendar" ).calendar(),
+ dp = element.calendar( "widget" );
+
+ function step1() {
+ ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" );
+ ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" );
+ equal( dp.children().length, 2, "Structure - child count (header, calendar)" );
+
+ header = dp.children( ":first" );
+ ok( header.is( "div.ui-calendar-header" ), "Structure - header division" );
+ equal( header.children().length, 3, "Structure - header child count" );
+ ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
+ ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
+
+ title = header.children( ":last" ).children( ":first" );
+ ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" );
+ equal( title.children().length, 2, "Structure - title child count" );
+ ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
+ ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
+
+ table = dp.children( ":eq(1)" );
+ ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" );
+ ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
+
+ thead = table.children( ":first" ).children( ":first" );
+ ok( thead.is( "tr" ), "Structure - month table title row" );
+ equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
+ ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
+ ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
+
+ week = table.children( ":eq(1)" ).children( ":first" );
+ ok( week.is( "tr" ), "Structure - month table week row" );
+ equal( week.children().length, 7, "Structure - week child count" );
+
+ step2();
+ }
+
+ function step2() {
+ element.calendar( "option", "buttons", {
+ "test": function() {},
+ "test button": function() {}
+ });
+
+ equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" );
+
+ buttonpane = dp.children( ".ui-calendar-buttonpane" );
+ equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" );
+ equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" );
+ equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" );
+
+ element.calendar( "destroy" );
+ step3();
+ }
+
+ function step3() {
+ // Multi-month 2
+ element = $( "#calendar" ).calendar( { numberOfMonths: 2 } );
+ dp = element.calendar( "widget" );
+
+ ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" );
+ equal( dp.children().length, 3, "Structure multi [2] - child count" );
+
+ child = dp.children( ":eq(2)" );
+ ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" );
+
+ element.calendar( "destroy" );
+ }
+
+ step1();
+});
+
+test( "Localization", function() {
+ expect( 10 );
+
+ var element = $( "#calendar" ),
+ date = new Date( 2014, 0, 1 ),
+ optionsDe = {
+ locale: "de",
+ labels: {
+ "nextText": "Vor",
+ "prevText": "Zurück"
+ }
+ },
+ initCalendar = function( options ) {
+ element
+ .calendar( options )
+ .calendar( "valueAsDate", date );
+ },
+ testLocalization = function( message ) {
+ equal(
+ element.find( ".ui-calendar-month" ).text(),
+ "Januar", message + "titlebar year"
+ );
+ equal(
+ element.find( "thead th:first" ).text(),
+ "Mo.", message + "teader first day"
+ );
+ equal(
+ element.find( "thead th:last" ).text(),
+ "So.", message + "header last day"
+ );
+ equal(
+ element.find( ".ui-calendar-prev" ).text(),
+ "Zurück", message + "header prev"
+ );
+ equal(
+ element.find( ".ui-calendar-next" ).text(),
+ "Vor", message + "header next"
+ );
+ };
+
+ initCalendar( optionsDe );
+ testLocalization( "Init: " );
+ element.calendar( "destroy" );
+
+ initCalendar( {} );
+ element
+ .calendar( "option", optionsDe )
+ .calendar( "refresh" );
+ testLocalization( "After init: " );
+});
+
+asyncTest( "keyboard handling", function() {
+ expect( 10 );
+
+ var element = $( "#calendar" );
+
+ function step1() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper
+ .focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 31 ),
+ "Keystroke left to switch to previous day"
+ );
+ element.calendar( "destroy" );
+ step2();
+ }, 50 );
+ }
+
+ function step2() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 1 - 1, 2 ),
+ "Keystroke right to switch to next day"
+ );
+ step3();
+ }
+
+ function step3() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 25 ),
+ "Keystroke up to move to the previous week"
+ );
+ element.calendar( "destroy" );
+ step4();
+ }, 50 );
+ }
+
+ function step4() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 1 - 1, 8 ),
+ "Keystroke down to move to the next week"
+ );
+ element.calendar( "destroy" );
+ step5();
+ }, 50 );
+ }
+
+ function step5() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 1 ),
+ "Keystroke Page Up moves date to previous month"
+ );
+ element.calendar( "destroy" );
+ step6();
+ }, 50 );
+ }
+
+ function step6() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 1 - 1, 1 ),
+ "Keystroke Page Up + ALT moves date to previous year"
+ );
+ element.calendar( "destroy" );
+ step7();
+ }, 50 );
+ }
+
+ function step7() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 2 - 1, 1 ),
+ "Keystroke Page Down moves date to next month"
+ );
+ element.calendar( "destroy" );
+ step8();
+ }, 50 );
+ }
+
+ function step8() {
+ element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2015, 1 - 1, 1 ),
+ "Keystroke Page Down + ALT moves date to next year"
+ );
+ element.calendar( "destroy" );
+ step9();
+ }, 50 );
+ }
+
+ // Check for moving to short months
+ function step9() {
+ element.calendar({ value: new Date( 2014, 3 - 1, 31 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 2 - 1, 28 ),
+ "Keystroke Page Up and short months"
+ );
+ element.calendar( "destroy" );
+ step10();
+ }, 50 );
+ }
+
+ function step10() {
+ element.calendar({ value: new Date( 2016, 1 - 1, 30 ) });
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2016, 2 - 1, 29 ),
+ "Keystroke Page Down and leap years"
+ );
+ element.calendar( "destroy" );
+ start();
+ }, 50 );
+ }
+
+ step1();
+});
+
+asyncTest( "mouse", function() {
+ expect( 6 );
+
+ var element = $( "#calendar" ).calendar(),
+ date = new Date();
+
+ function step1() {
+ $( "tbody button:contains(10)", element ).simulate( "mousedown" );
+ date.setDate( 10 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date,
+ "Mouse click"
+ );
+
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
+ $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 12 ),
+ "Mouse click - preset"
+ );
+
+ // Previous/next
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
+ $( ".ui-calendar-prev", element ).simulate( "click" );
+ $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 1 - 1, 16 ),
+ "Mouse click - previous"
+ );
+
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
+ $( ".ui-calendar-next", element ).simulate( "click" );
+ $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 3 - 1, 18 ),
+ "Mouse click - next"
+ );
+
+ step2();
+ }
+
+ // Previous/next with minimum/maximum
+ function step2() {
+ element.calendar( "destroy" );
+ element.calendar({
+ value: new Date( 2008, 3 - 1, 4),
+ min: new Date( 2008, 2 - 1, 2 ),
+ max: new Date( 2008, 2 - 1, 26 )
+ });
+
+ $( ".ui-calendar-prev", element ).simulate( "click" );
+ $( "tbody button:contains(16)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 16 ),
+ "Mouse click - previous + min/max"
+ );
+ step3();
+ }
+
+ function step3() {
+ element.calendar( "destroy" );
+ element.calendar({
+ value: new Date( 2008, 1 - 1, 4),
+ min: new Date( 2008, 2 - 1, 2 ),
+ max: new Date( 2008, 2 - 1, 26 )
+ });
+
+ $( ".ui-calendar-next", element ).simulate( "click" );
+ $( "tbody button:contains(18)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 18 ),
+ "Mouse click - next + min/max"
+ );
+ start();
+ }
+
+ step1();
+});
+
+} );
diff --git a/tests/unit/calendar/events.js b/tests/unit/calendar/events.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/unit/calendar/events.js
diff --git a/tests/unit/calendar/helper.js b/tests/unit/calendar/helper.js
new file mode 100644
index 000000000..a82e96705
--- /dev/null
+++ b/tests/unit/calendar/helper.js
@@ -0,0 +1,31 @@
+define( [
+ "jquery",
+ "lib/helper"
+], function( $, helper ) {
+
+return $.extend( helper, {
+ addMonths: function( date, offset ) {
+ var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate();
+ date.setDate( Math.min( date.getDate(), maxDay ) );
+ date.setMonth( date.getMonth() + offset );
+ return date;
+ },
+ equalsDate: function( d1, d2, message ) {
+ if ( !d1 || !d2 ) {
+ ok( false, message + " - missing date" );
+ return;
+ }
+ d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() );
+ d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() );
+ equal( d1.toString(), d2.toString(), message );
+ },
+ focusGrid: function( element ) {
+ element.find( ":tabbable" ).last().simulate( "focus" );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
+
+ return $( document.activeElement );
+ }
+} );
+
+} );
diff --git a/tests/unit/calendar/methods.js b/tests/unit/calendar/methods.js
new file mode 100644
index 000000000..23989860c
--- /dev/null
+++ b/tests/unit/calendar/methods.js
@@ -0,0 +1,145 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: methods" );
+
+test( "destroy", function( assert ) {
+ expect( 1 );
+
+ assert.domEqual( "#calendar", function() {
+ $( "#calendar" ).calendar().calendar( "destroy" );
+ });
+});
+
+test( "enable / disable", function() {
+ expect( 8 );
+
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "disable" );
+ ok( element.calendar( "option", "disabled" ), "disabled option is set" );
+ ok( element.hasClass( "ui-calendar-disabled" ), "has disabled widget class name" );
+ ok( element.hasClass( "ui-state-disabled" ), "has disabled state class name" );
+ equal( element.attr( "aria-disabled" ), "true", "has ARIA disabled" );
+
+ element.calendar( "enable" );
+ ok( !element.calendar( "option", "disabled" ), "enabled after enable() call" );
+ ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" );
+ ok( !element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" );
+ equal( element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" );
+});
+
+test( "widget", function() {
+ expect( 1 );
+
+ var element = $( "#calendar" ).calendar(),
+ widget = element.calendar( "widget" );
+
+ strictEqual( widget[ 0 ], element[ 0 ] );
+});
+
+test( "value", function() {
+ expect( 3 );
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "value", "1/1/14" );
+ ok( element.find( "button[data-timestamp]:first" )
+ .hasClass( "ui-state-active" ),
+ "first day marked as selected"
+ );
+ equal( element.calendar( "value" ), "1/1/14", "getter" );
+
+ element.calendar( "value", "abc" );
+ equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." );
+});
+
+test( "valueAsDate", function() {
+ expect( 11 );
+
+ var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
+ element = $( "#calendar" ).calendar(),
+ date1 = new Date( 2008, 6 - 1, 4 ),
+ date2;
+
+ element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) );
+ ok( element.find( "button[data-timestamp]:first" )
+ .hasClass( "ui-state-active" ),
+ "First day marked as selected"
+ );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
+
+ element.calendar( "destroy" );
+
+ element.calendar();
+ equal( element.calendar( "valueAsDate" ), null, "Set date - default" );
+
+ element.calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" );
+
+ // With minimum/maximum
+ element = $( "#calendar" ).calendar();
+ date1 = new Date( 2008, 1 - 1, 4 );
+ date2 = new Date( 2008, 6 - 1, 4 );
+ minDate = new Date( 2008, 2 - 1, 29 );
+ maxDate = new Date( 2008, 3 - 1, 28 );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date2, "Set date min/max - value > min"
+ );
+
+ element.calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date2,
+ "Set date min/max - value < min"
+ );
+
+ element
+ .calendar( "option", { max: maxDate, min: null } )
+ .calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value < max"
+ );
+
+ element.calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value > max"
+ );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value < min"
+ );
+
+ element.calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1, "Set date min/max - value > max"
+ );
+
+ dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
+ dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
+ element.calendar( "valueAsDate", dateAndTimeToSet );
+ equal(
+ dateAndTimeToSet.getTime(),
+ dateAndTimeClone.getTime(),
+ "Date object passed should not be changed by valueAsDate"
+ );
+});
+
+} );
diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js
new file mode 100644
index 000000000..5af5e479e
--- /dev/null
+++ b/tests/unit/calendar/options.js
@@ -0,0 +1,323 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: options" );
+
+test("buttons", function() {
+ expect( 21 );
+
+ var button, i, newButtons,
+ buttons = {
+ "Ok": function( event ) {
+ ok(true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 0 ], "event target" );
+ },
+ "Cancel": function( event ) {
+ ok( true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 1 ], "event target" );
+ }
+ },
+ element = $( "#calendar" ).calendar({ buttons: buttons });
+
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 2, "number of buttons" );
+
+ i = 0;
+ $.each( buttons, function( key ) {
+ equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
+ i++;
+ });
+
+ ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" );
+ ok(
+ element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ),
+ "calendar wrapper adds class about having buttons"
+ );
+
+ button.trigger( "click" );
+
+ newButtons = {
+ "Close": function( event ) {
+ ok( true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 0 ], "event target" );
+ }
+ };
+
+ deepEqual(
+ element.calendar( "option", "buttons" ),
+ buttons,
+ ".calendar('option', 'buttons') getter"
+ );
+ element.calendar( "option", "buttons", newButtons );
+ deepEqual(
+ element.calendar( "option", "buttons" ),
+ newButtons,
+ ".calendar('option', 'buttons', ...) setter"
+ );
+
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 1, "number of buttons after setter" );
+ button.trigger( "click" );
+
+ i = 0;
+ $.each( newButtons, function( key ) {
+ equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
+ i += 1;
+ });
+
+ element.calendar( "option", "buttons", null );
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 0, "all buttons have been removed" );
+ equal( element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" );
+ equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" );
+
+ element.remove();
+});
+
+test( "buttons - advanced", function() {
+ expect( 7 );
+
+ var buttons,
+ element = $( "#calendar" ).calendar({
+ buttons: [{
+ text: "a button",
+ "class": "additional-class",
+ id: "my-button-id",
+ click: function() {
+ equal( this, element[ 0 ], "correct context" );
+ },
+ icons: {
+ primary: "ui-icon-cancel"
+ },
+ showText: false
+ }]
+ });
+
+ buttons = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( buttons.length, 1, "correct number of buttons" );
+ equal( buttons.attr( "id" ), "my-button-id", "correct id" );
+ equal ( buttons.text(), "a button", "correct label" );
+ ok( buttons.hasClass( "additional-class" ), "additional classes added" );
+ deepEqual( buttons.button( "option", "icons" ), { primary: "ui-icon-cancel", secondary: null } );
+ equal( buttons.button( "option", "text" ), false );
+ buttons.click();
+
+ element.remove();
+});
+
+test( "dateFormat", function() {
+ expect( 2 );
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "value", "1/1/14" );
+
+ element.calendar( "widget" ).find( "td[id]:first button" ).trigger( "mousedown" );
+ equal( element.calendar( "value" ), "1/1/14", "default formatting" );
+
+ element.calendar( "option", "dateFormat", { date: "full" } );
+ equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" );
+});
+
+test( "eachDay", function() {
+ expect( 5 );
+ var timestamp,
+ input = $( "#calendar" ).calendar(),
+ picker = input.calendar( "widget" ),
+ firstCell = picker.find( "td[id]:first" );
+
+ equal( firstCell.find( "button" ).length, 1, "days are selectable by default" );
+ timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 );
+ equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" );
+
+ // Do not render the 1st of the month
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.render = false;
+ }
+ });
+ firstCell = picker.find( "td[id]:first" );
+ timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 );
+ equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" );
+
+ // Display the 1st of the month but make it not selectable.
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.selectable = false;
+ }
+ });
+ firstCell = picker.find( "td[id]:first" );
+ ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" );
+
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.extraClasses = "ui-custom";
+ }
+ });
+ ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" );
+
+ input.calendar( "destroy" );
+});
+
+test( "showWeek", function() {
+ expect( 7 );
+ var input = $( "#calendar" ).calendar(),
+ container = input.calendar( "widget" );
+
+ equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" );
+ equal( container.find( ".ui-calendar-week-col" ).length, 0,
+ "no week column cells present" );
+ input.calendar( "destroy" );
+
+ input = $( "#calendar" ).calendar({ showWeek: true });
+ container = input.calendar( "widget" );
+ equal( container.find( "thead th" ).length, 8, "7 days + a column cell" );
+ ok( container.find( "thead th:first" ).is( ".ui-calendar-week-col" ),
+ "first cell should have ui-datepicker-week-col class name" );
+ equal( container.find( ".ui-calendar-week-col" ).length,
+ container.find( "tr" ).length, "one week cell for each week" );
+ input.calendar( "destroy" );
+
+ input = $( "#calendar" ).calendar();
+ container = input.calendar( "widget" );
+ equal( container.find( "thead th" ).length, 7, "no week column" );
+ input.calendar( "option", "showWeek", true );
+ equal( container.find( "thead th" ).length, 8, "supports changing option after init" );
+});
+
+test( "min / max", function() {
+ expect( 7 );
+
+ // With existing date
+ var element = $( "#calendar" ).calendar(),
+ minDate = new Date( 2008, 2 - 1, 29 ),
+ maxDate = new Date( 2008, 12 - 1, 7 );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "value", "6/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "value", "1/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" );
+
+ element
+ .calendar( "option", { min: null } )
+ .calendar( "value", "6/4/08" )
+ .calendar( "option", { max: maxDate } );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" );
+
+ element
+ .calendar( "option", { max: maxDate } )
+ .calendar( "value", "1/4/09" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > max" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "1/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "6/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "1/4/09" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" );});
+
+/*
+// TODO: Move this to $.date, Globalize or calendar widget
+test( "daylightSaving", function() {
+ expect( 25 );
+ var inp = testHelper.init( "#inp" ),
+ dp = $( "#ui-datepicker-div" );
+ ok(true, "Daylight saving - " + new Date());
+ // Australia, Sydney - AM change, southern hemisphere
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" );
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" );
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" );
+ // Brasil, Brasilia - midnight change, southern hemisphere
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(20) a", dp).simulate( "click" );
+ equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" );
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(21) a", dp).simulate( "click" );
+ equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" );
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(22) a", dp).simulate( "click" );
+ equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
+ equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
+ equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
+ equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" );
+ // Lebanon, Beirut - midnight change, northern hemisphere
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(34) a", dp).simulate( "click" );
+ equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(35) a", dp).simulate( "click" );
+ equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(36) a", dp).simulate( "click" );
+ equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(27) a", dp).simulate( "click" );
+ equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(28) a", dp).simulate( "click" );
+ equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(29) a", dp).simulate( "click" );
+ equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" );
+ // US, Eastern - AM change, northern hemisphere
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
+ equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
+ equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
+ equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" );
+ });
+ */
+
+} );
diff --git a/tests/unit/date/all.html b/tests/unit/date/all.html
new file mode 100644
index 000000000..5248d7ace
--- /dev/null
+++ b/tests/unit/date/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Date Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "date" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js
new file mode 100644
index 000000000..d5895a91d
--- /dev/null
+++ b/tests/unit/date/core.js
@@ -0,0 +1,197 @@
+define( [
+ "jquery",
+ "globalize",
+ "date"
+], function( $, Globalize ) {
+
+module( "date: core" );
+
+test( "Instantiation", function() {
+ expect( 2 );
+ ok( new $.date() instanceof $.date, "constructor function" );
+ ok( $.date() instanceof $.date, "instantiation without new" );
+});
+
+test( "Check Sets and Gets", 6, function() {
+ var date = $.date();
+ equal( date.setYear( 2012 ).year(), 2012, "Set year and retrieve" );
+ equal( date.setMonth( 9 ).month(), 9, "Set month and retrieve" );
+ equal( date.setDay( 15 ).day(), 15, "Set day and retrieve" );
+ equal( date.setFullDate( 2012, 9, 15 ).year(), 2012, "Set full date and retrieve year" );
+ equal( date.month(), 9, "Set full date and retrieve month" );
+ equal( date.day(), 15, "Set full date and retrieve day" );
+});
+
+test( "Date Adjustments - Normal Use Cases", 10, function() {
+ var date = $.date();
+
+ // Use October 15, 2012
+ date.setFullDate( 2012, 9, 15 );
+ equal( date.adjust( "D", 1 ).day(), 16, "Add 1 day" );
+ equal( date.adjust( "D", -1 ).day(), 15, "Subtract 1 day" );
+ equal( date.adjust( "M", 1 ).month(), 10, "Add 1 month" );
+ equal( date.adjust( "M", -1 ).month(), 9, "Subtract 1 month" );
+ equal( date.adjust( "Y", 1 ).year(), 2013, "Add 1 year" );
+ equal( date.adjust( "Y", -1 ).year(), 2012, "Subtract 1 year" );
+
+ // Check changing one value impact another. Ex: Day impacts month
+ // Use April 30th 2012
+ date.setFullDate( 2012, 3, 30 );
+ equal( date.adjust( "D", 1 ).month(), 4, "Add 1 day to change month from April to May" );
+ equal( date.adjust( "D", -1 ).month(), 3, "Subtract 1 day to change month from May to April" );
+
+ // Use December 31st 2012
+ date.setFullDate( 2012, 11, 31 );
+ equal( date.adjust( "D", 1 ).year(), 2013, "Add 1 day to change year from 2012 to 2013" );
+ equal( date.adjust( "D", -1 ).year(), 2012,
+ "Subtract 1 day to change month from 2013 to 2012" );
+});
+
+test( "Date Adjustments - Month Overflow Edge Cases", 2, function() {
+ var date = $.date();
+
+ // Use May 31 2012
+ date.setFullDate( 2012, 4, 31 );
+ equal( date.adjust( "M", 1 ).day(), 30,
+ "Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)" );
+ equal( date.adjust( "M", -1 ).day(), 30,
+ "Subtract 1 month from June to May sets days to 30 in May" );
+});
+
+test( "Date Adjustments - Leap Year Edge Cases", 1, function() {
+ var date = $.date();
+
+ // Use February 29 2012 a Leap year
+ date.setFullDate( 2012, 1, 29 );
+ equal( date.adjust( "Y", 1 ).day(), 28,
+ "Feb 29 2012, add a year to convert to Feb 28, 2013" );
+});
+
+test( "List days of Week", 2, function() {
+ var date = $.date(),
+ offset0 = [
+ { "fullname": "Sunday", "shortname": "Su" },
+ { "fullname": "Monday", "shortname": "Mo" },
+ { "fullname": "Tuesday", "shortname": "Tu" },
+ { "fullname": "Wednesday", "shortname": "We" },
+ { "fullname": "Thursday", "shortname": "Th" },
+ { "fullname": "Friday", "shortname": "Fr" },
+ { "fullname": "Saturday", "shortname": "Sa" }
+ ],
+ offset1 = [
+ { "fullname": "Montag", "shortname": "Mo." },
+ { "fullname": "Dienstag", "shortname": "Di." },
+ { "fullname": "Mittwoch", "shortname": "Mi." },
+ { "fullname": "Donnerstag", "shortname": "Do." },
+ { "fullname": "Freitag", "shortname": "Fr." },
+ { "fullname": "Samstag", "shortname": "Sa." },
+ { "fullname": "Sonntag", "shortname": "So." }
+ ];
+
+ deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" );
+ Globalize.locale( "de" );
+ deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" );
+
+ // Revert Globalize changes back to English
+ Globalize.locale( "en" );
+});
+
+test( "Leap Year Check", 8, function() {
+ var date = $.date();
+ ok( date.setYear( 2008 ).isLeapYear(), "2008 is a Leap Year" );
+ ok( !date.setYear( 2009 ).isLeapYear(), "2009 is not a Leap Year" );
+ ok( !date.setYear( 2010 ).isLeapYear(), "2010 is not a Leap Year" );
+ ok( !date.setYear( 2011 ).isLeapYear(), "2011 is not a Leap Year" );
+ ok( date.isLeapYear( 2012 ), "2012 is a Leap Year" );
+ ok( !date.isLeapYear( 2013 ), "2013 is not a Leap Year" );
+ ok( !date.isLeapYear( 2014 ), "2014 is not a Leap year" );
+ ok( !date.isLeapYear( 2015 ), "2015 is not a Leap year" );
+});
+
+test( "Days in Month", 3, function() {
+ var date = $.date();
+ date.setFullDate( 2012, 1, 1 );
+ equal( date.daysInMonth(), 29, "Leap Year implicit check for 29 days" );
+ equal( date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days" );
+ equal( date.daysInMonth( 2011, 3 ), 30, "April has 30 days" );
+});
+
+test( "Month Name", 2, function() {
+ var date = $.date();
+ equal( date.setMonth( 3 ).monthName(), "April", "Month name return April (English)" );
+ Globalize.locale( "de" );
+ equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" );
+ Globalize.locale( "en" );
+});
+
+test( "Clone", 2, function() {
+ var date = $.date(),
+ date2 = date.clone();
+ ok( date2, "Created cloned object" );
+ notEqual( date.adjust( "Y", 1 ).year(), date2.year(), "Object manipulated independently" );
+});
+
+test( "Days", 1, function() {
+ //TODO needs work
+ var date = $.date();
+ date.eachDay = function( day ) {
+ if ( day.lead && day.date > 20 ) {
+ day.selectable = false;
+ day.render = true;
+ day.title = "These are the days of last month";
+ day.extraClasses = "ui-state-disabled";
+ }
+ if ( day.lead && day.date < 3 ) {
+ day.selectable = true;
+ day.render = true;
+ day.extraClasses = "ui-state-disabled";
+ }
+ if ( day.date === 1 ) {
+ day.extraClasses = "ui-state-error";
+ day.title = "Something bad explaining the error highlight";
+ }
+ if ( day.today ) {
+ day.title = "A good day!";
+ }
+ };
+ ok( date.days(), "Date days() returns");
+});
+
+test( "Months", 5, function(){
+ var date = $.date(),
+ firstMonth = date.months( 1 )[ 0 ],
+ lastMonth = date.months( 1 )[ 1 ];
+
+ ok( firstMonth.first );
+ ok( !lastMonth.first );
+ ok( lastMonth.last );
+ ok( !lastMonth.first );
+
+ ok( firstMonth.month() === lastMonth.month() - 1 );
+});
+
+test( "Equal", 4, function() {
+ var date = $.date();
+ date.setFullDate( 2012, 9, 16 );
+ ok( date.equal( new Date( 2012, 9, 16 ) ), "Does date equal provide date" );
+ ok( !date.equal( new Date( 2011, 9, 16 ) ), "Does date year not equal provide date" );
+ ok( !date.equal( new Date( 2012, 8, 16 ) ), "Does date month not equal provide date" );
+ ok( !date.equal( new Date( 2012, 9, 15 ) ), "Does date day not equal provide date" );
+});
+
+test( "Date", 1, function() {
+ var date = $.date();
+ ok( date.date() instanceof Date, "Date returned" );
+});
+
+test( "Format", 4, function() {
+ var date = $.date();
+ date.setFullDate( 2012, 9, 16 );
+ equal( date.format({ date: "short" }), "10/16/12", "Checking default US format" );
+ equal( date.format({ pattern: "yyyy/MM/dd" }), "2012/10/16", "Checking yyyy/MM/dd format" );
+ equal( date.format({ pattern: "yy/dd/MM" }), "12/16/10", "Checking yy/dd/MM format" );
+ equal( date.format({ pattern: "MMMM dd, yyyy" }), "October 16, 2012",
+ "Checking MMMM dd, yyyy format" );
+});
+
+} );
diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html
new file mode 100644
index 000000000..1d9ee6c1f
--- /dev/null
+++ b/tests/unit/date/date.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Date Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js"></script>
+ <script src="../../lib/bootstrap.js" data-modules="core"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+ <div><input type="text" id="inp"><input type="text" id="alt"><div id="inl"></div></div>
+ <p><input type="text" id="inp2"></p>
+</div>
+</body>
+</html>
diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js
index 1eecc85cb..61c7ace43 100644
--- a/tests/unit/datepicker/common.js
+++ b/tests/unit/datepicker/common.js
@@ -1,7 +1,42 @@
-/*
-TestHelpers.commonWidgetTests( "datepicker", {
+define( [
+ "lib/common",
+ "ui/widgets/datepicker",
+ "globalize-locales"
+], function( common ) {
+
+common.testWidget( "datepicker", {
defaults: {
- disabled: false
+ appendTo: null,
+ buttons: [],
+ classes: {},
+ disabled: false,
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ position: {
+ my: "left top",
+ at: "left bottom"
+ },
+ show: true,
+ showWeek: false,
+ hide: true,
+
+ // callbacks
+ beforeOpen: null,
+ close: null,
+ create: null,
+ open: null,
+ select: null
}
});
-*/
+
+} );
diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js
index 43d5e2243..2a8910875 100644
--- a/tests/unit/datepicker/core.js
+++ b/tests/unit/datepicker/core.js
@@ -1,530 +1,173 @@
define( [
"jquery",
- "lib/common",
"./helper",
- "ui/widgets/datepicker",
- "ui/i18n/datepicker-he"
-], function( $, common, testHelper ) {
+ "ui/widgets/datepicker"
+], function( $, testHelper ) {
-module( "datepicker: core", {
- setup: function() {
- $( "body" ).trigger( "focus" );
- }
-});
-
-common.testJshint( "datepicker" );
-
-test("initialization - Reinitialization after body had been emptied.", function() {
- expect( 1 );
- var bodyContent = $("body").children(), inp = $("#inp");
- $("#inp").datepicker();
- $("body").empty().append(inp);
- $("#inp").datepicker();
- ok( $("#"+$.datepicker._mainDivId).length===1, "Datepicker container added" );
- $("body").empty().append(bodyContent); // Returning to initial state for later tests
-});
-
-test( "widget method - empty collection", function() {
- expect( 1 );
- $( "#nonExist" ).datepicker(); // should create nothing
- ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" );
-});
-
-test("widget method", function() {
- expect( 1 );
- var actual = $("#inp").datepicker().datepicker("widget")[0];
- deepEqual($("body > #ui-datepicker-div:last-child")[0], actual);
-});
-
-asyncTest( "baseStructure", function() {
- expect( 58 );
- var header, title, table, thead, week, panel, inl, child,
- inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- function step1() {
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Structure - datepicker visible" );
- ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" );
- ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" );
- equal( dp.children().length, 2, "Structure - child count" );
-
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" );
- equal( header.children().length, 3, "Structure - header child count" );
- ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
- ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
-
- title = header.children( ":last" );
- ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" );
- equal( title.children().length, 2, "Structure - title child count" );
- ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
- ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
-
- table = dp.children( ":eq(1)" );
- ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" );
- ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
-
- thead = table.children( ":first" ).children( ":first" );
- ok( thead.is( "tr" ), "Structure - month table title row" );
- equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
- ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
- ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
-
- week = table.children( ":eq(1)" ).children( ":first" );
- ok( week.is( "tr" ), "Structure - month table week row" );
- equal( week.children().length, 7, "Structure - week child count" );
- ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" );
- ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step2();
- });
- }
-
- function step2() {
- // Editable month/year and button panel
- inp = testHelper.initNewInput({
- changeMonth: true,
- changeYear: true,
- showButtonPanel: true
- });
- testHelper.onFocus( inp, function() {
- title = dp.find( "div.ui-datepicker-title" );
- ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" );
- ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" );
-
- panel = dp.children( ":last" );
- ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" );
- equal( panel.children().length, 2, "Structure - button panel child count" );
- ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" );
- ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step3();
- });
- }
-
- function step3() {
- // Multi-month 2
- inp = testHelper.initNewInput({ numberOfMonths: 2 });
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" );
- equal( dp.children().length, 3, "Structure multi [2] - child count" );
-
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" );
-
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" );
-
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" );
- ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step4();
- });
- }
-
- function step4() {
- // Multi-month 3
- inp = testHelper.initNewInput({ numberOfMonths: 3 });
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" );
- ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step5();
- });
- }
+module( "datepicker: core" );
- function step5() {
- // Multi-month [2, 2]
- inp = testHelper.initNewInput({ numberOfMonths: [ 2, 2 ] });
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" );
- equal( dp.children().length, 6, "Structure multi [2,2] - child count" );
+test( "input's value determines starting date", function() {
+ expect( 3 );
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" );
+ var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(),
+ picker = input.datepicker( "widget" );
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" );
+ input.datepicker( "open" );
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
+ equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" );
+ equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" );
+ equal( picker.find( ".ui-state-active" ).html(), "1", "correct day highlighted" );
- child = dp.children( ":eq(3)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" );
-
- child = dp.children( ":eq(4)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" );
-
- child = dp.children( ":eq(5)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- // Inline
- inl = testHelper.init( "#inl" );
- dp = inl.children();
-
- ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" );
- ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" );
- ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" );
- equal( dp.children().length, 2, "Structure inline - child count" );
-
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" );
- equal( header.children().length, 3, "Structure inline - header child count" );
-
- table = dp.children( ":eq(1)" );
- ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" );
- ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" );
- ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" );
-
- inl.datepicker( "destroy" );
-
- // Inline multi-month
- inl = testHelper.init( "#inl", { numberOfMonths: 2 } );
- dp = inl.children();
+ input.val( "" ).datepicker( "destroy" );
+});
- ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" );
- equal( dp.children().length, 3, "Structure inline multi - child count" );
+asyncTest( "base structure", function() {
+ expect( 5 );
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" );
+ var input = testHelper.initNewInput(),
+ widget = input.datepicker( "widget" );
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" );
+ input.focus();
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" );
+ setTimeout(function() {
+ ok( widget.is( ":visible" ), "Datepicker visible" );
+ equal( widget.children().length, 2, "Child count" );
+ ok( widget.is( ".ui-calendar" ), "Class ui-calendar" );
+ ok( widget.is( ".ui-datepicker" ), "Class ui-datepicker" );
+ ok( widget.is( ".ui-front" ), "Class ui-front" );
- inl.datepicker( "destroy" );
- start();
- });
- }
-
- step1();
+ input.datepicker( "close" );
+ start();
+ }, 50 );
});
-asyncTest( "customStructure", function() {
- expect( 20 );
- var header, panel, title, thead,
- inp = testHelper.initNewInput( $.datepicker.regional.he ),
- dp = $( "#ui-datepicker-div" );
+asyncTest( "Keyboard handling: input", function() {
+ expect( 10 );
+ var picker, instance,
+ input = $( "#datepicker" ).datepicker();
function step1() {
- inp.datepicker( "option", "showButtonPanel", true );
-
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" );
+ testHelper.init( input );
+ picker = input.datepicker( "widget" );
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" );
- equal( header.children().length, 3, "Structure RTL - header child count" );
- ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" );
- ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" );
+ ok( !picker.is( ":visible" ), "datepicker closed" );
- panel = dp.children( ":last" );
- ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" );
- equal( panel.children().length, 2, "Structure RTL - button panel child count" );
- ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" );
- ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
+ input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout(function() {
+ ok( picker.is( ":visible" ), "Keystroke down opens datepicker" );
+ input.datepicker( "destroy" );
step2();
- });
+ }, 100 );
}
- // Hide prev/next
function step2() {
- inp = testHelper.initNewInput({
- hideIfNoPrevNext: true,
- minDate: new Date( 2008, 2 - 1, 4 ),
- maxDate: new Date( 2008, 2 - 1, 14 )
- });
- inp.val( "02/10/2008" );
-
- testHelper.onFocus( inp, function() {
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" );
- equal( header.children().length, 1, "Structure hide prev/next - links child count" );
- ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step3();
- });
- }
-
- // Changeable Month with read-only year
- function step3() {
- inp = testHelper.initNewInput({ changeMonth: true });
-
- testHelper.onFocus( inp, function() {
- title = dp.children( ":first" ).children( ":last" );
- equal( title.children().length, 2, "Structure changeable month - title child count" );
- ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" );
- ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step4();
- });
- }
-
- // Changeable year with read-only month
- function step4() {
- inp = testHelper.initNewInput({ changeYear: true });
+ testHelper.init( input );
+ picker = input.datepicker( "widget" );
- testHelper.onFocus( inp, function() {
- title = dp.children( ":first" ).children( ":last" );
- equal( title.children().length, 2, "Structure changeable year - title child count" );
- ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" );
- ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" );
+ ok( !picker.is( ":visible" ), "datepicker closed" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step5();
- });
+ input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+ setTimeout(function() {
+ ok( picker.is( ":visible" ), "Keystroke up opens datepicker" );
+ input.datepicker( "destroy" );
+ step3();
+ }, 100 );
}
- // Read-only first day of week
- function step5() {
- inp = testHelper.initNewInput({ changeFirstDay: false });
-
- testHelper.onFocus( inp, function() {
- thead = dp.find( ".ui-datepicker-calendar thead tr" );
- equal( thead.children().length, 7, "Structure read-only first day - thead child count" );
- equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- start();
- });
+ function step3() {
+ testHelper.init( input );
+ instance = input.datepicker( "instance" );
+
+ // Enter = Select preset date
+ input
+ .val( "1/1/14" )
+ .datepicker( "refresh" )
+ .datepicker( "open" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke enter - preset" );
+
+ input
+ .val( "" )
+ .datepicker( "open" );
+ ok( instance.isOpen, "datepicker is open before escape" );
+
+ input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ ok( !instance.isOpen, "escape closes the datepicker" );
+
+ input
+ .val( "1/1/14" )
+ .datepicker( "open" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke esc - preset" );
+
+ input
+ .val( "1/1/14" )
+ .datepicker( "open" )
+ .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke esc - abandoned" );
+
+ input
+ .val( "1/2/14" )
+ .simulate( "keyup" );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ),
+ "Picker updated as user types into input" );
+
+ input.datepicker( "destroy" );
+ start();
}
- // TODO: figure out why this setTimeout is needed in IE,
- // it only is necessary when the previous baseStructure tests runs first
- // Support: IE
- setTimeout( step1 );
+ step1();
});
-test("keystrokes", function() {
- expect( 26 );
- var inp = testHelper.init("#inp"),
- date = new Date();
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke enter");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Keystroke enter - preset");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+home");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END});
- ok(inp.datepicker("getDate") == null, "Keystroke ctrl+end");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- ok(inp.datepicker("getDate") == null, "Keystroke esc");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Keystroke esc - preset");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Keystroke esc - abandoned");
- // Moving by day or week
- inp.val("").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.LEFT}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+left");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.LEFT}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke left");
- inp.val("").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+right");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.RIGHT}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke right");
- inp.val("").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 7);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+up");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 7);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke up");
- inp.val("").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 7);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+down");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 7);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke down");
- // Moving by month or year
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 4),
- "Keystroke pgup");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 4),
- "Keystroke pgdn");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 4),
- "Keystroke ctrl+pgup");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 4),
- "Keystroke ctrl+pgdn");
- // Check for moving to short months
- inp.val("03/31/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29),
- "Keystroke pgup - Feb");
- inp.val("01/30/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29),
- "Keystroke pgdn - Feb");
- inp.val("02/29/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 28),
- "Keystroke ctrl+pgup - Feb");
- inp.val("02/29/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 28),
- "Keystroke ctrl+pgdn - Feb");
- // Goto current
- inp.datepicker("option", {gotoCurrent: true}).
- datepicker("hide").val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Keystroke ctrl+home");
- // Change steps
- inp.datepicker("option", {stepMonths: 2, gotoCurrent: false}).
- datepicker("hide").val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 12 - 1, 4),
- "Keystroke pgup step 2");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 4 - 1, 4),
- "Keystroke pgdn step 2");
+// TODO: implement
+test( "ARIA", function() {
+ expect( 0 );
});
-test("mouse", function() {
- expect( 15 );
- var inl,
- inp = testHelper.init("#inp"),
- dp = $("#ui-datepicker-div"),
- date = new Date();
- inp.val("").datepicker("show");
- $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {});
- date.setDate(10);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click");
- inp.val("02/04/2008").datepicker("show");
- $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 12),
- "Mouse click - preset");
- inp.val("02/04/2008").datepicker("show");
- inp.val("").datepicker("show");
- $("button.ui-datepicker-close", dp).simulate("click", {});
- ok(inp.datepicker("getDate") == null, "Mouse click - close");
- inp.val("02/04/2008").datepicker("show");
- $("button.ui-datepicker-close", dp).simulate("click", {});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Mouse click - close + preset");
- inp.val("02/04/2008").datepicker("show");
- $("a.ui-datepicker-prev", dp).simulate("click", {});
- $("button.ui-datepicker-close", dp).simulate("click", {});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4),
- "Mouse click - abandoned");
- // Current/previous/next
- inp.val("02/04/2008").datepicker("option", {showButtonPanel: true}).datepicker("show");
- $(".ui-datepicker-current", dp).simulate("click", {});
- $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {});
- date.setDate(14);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click - current");
- inp.val("02/04/2008").datepicker("show");
- $(".ui-datepicker-prev", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click");
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 16),
- "Mouse click - previous");
- inp.val("02/04/2008").datepicker("show");
- $(".ui-datepicker-next", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click");
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 18),
- "Mouse click - next");
- // Previous/next with minimum/maximum
- inp.datepicker("option", {minDate: new Date(2008, 2 - 1, 2),
- maxDate: new Date(2008, 2 - 1, 26)}).val("02/04/2008").datepicker("show");
- $(".ui-datepicker-prev", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click");
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 16),
- "Mouse click - previous + min/max");
- inp.val("02/04/2008").datepicker("show");
- $(".ui-datepicker-next", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click");
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 18),
- "Mouse click - next + min/max");
- // Inline
- inl = testHelper.init("#inl");
- dp = $(".ui-datepicker-inline", inl);
- date = new Date();
- inl.datepicker("setDate", date);
- $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {});
- date.setDate(10);
- testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline");
- inl.datepicker("option", {showButtonPanel: true}).datepicker("setDate", new Date(2008, 2 - 1, 4));
- $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {});
- testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 2 - 1, 12), "Mouse click inline - preset");
- inl.datepicker("option", {showButtonPanel: true});
- $(".ui-datepicker-current", dp).simulate("click", {});
- $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {});
- date.setDate(14);
- testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline - current");
- inl.datepicker("setDate", new Date(2008, 2 - 1, 4));
- $(".ui-datepicker-prev", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click");
- testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 1 - 1, 16),
- "Mouse click inline - previous");
- inl.datepicker("setDate", new Date(2008, 2 - 1, 4));
- $(".ui-datepicker-next", dp).simulate("click");
- $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click");
- testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 3 - 1, 18),
- "Mouse click inline - next");
+asyncTest( "mouse", function() {
+ expect( 4 );
+
+ var input = testHelper.init( $( "#datepicker" ).val( "" ) ),
+ picker = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+
+ setTimeout(function() {
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 12 ),
+ "Mouse click - preset"
+ );
+
+ input.val( "" ).datepicker( "refresh" );
+ input.simulate( "click" );
+ strictEqual( input.datepicker( "valueAsDate" ), null, "Mouse click - close" );
+
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ input.simulate( "click" );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 4 ),
+ "Mouse click - close + preset"
+ );
+
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ picker.find( "a.ui-calendar-prev" ).simulate( "click" );
+ input.simulate( "click" );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 4 ),
+ "Mouse click - abandoned"
+ );
+
+ start();
+ }, 100 );
});
} );
diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html
index 26d8de3e0..3b20272b1 100644
--- a/tests/unit/datepicker/datepicker.html
+++ b/tests/unit/datepicker/datepicker.html
@@ -5,7 +5,7 @@
<title>jQuery UI Datepicker Test Suite</title>
<script src="../../../external/requirejs/require.js"></script>
- <script src="../../lib/css.js" data-modules="core datepicker"></script>
+ <script src="../../lib/css.js" data-modules="core calendar datepicker"></script>
<script src="../../lib/bootstrap.js" data-widget="datepicker"></script>
</head>
<body>
@@ -13,8 +13,8 @@
<div id="qunit"></div>
<div id="qunit-fixture">
-<div><input type="text" id="inp"><input type="text" id="alt"><div id="inl"></div></div>
-<p><input type="text" id="inp2"></p>
+<input type="text" id="datepicker">
+<input type="text" id="datepicker2">
</div>
</body>
diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js
index f33351b57..833316ce4 100644
--- a/tests/unit/datepicker/events.js
+++ b/tests/unit/datepicker/events.js
@@ -4,151 +4,135 @@ define( [
"ui/widgets/datepicker"
], function( $, testHelper ) {
-module("datepicker: events");
-
-var selectedThis = null,
-selectedDate = null,
-selectedInst = null;
-
-function callback(date, inst) {
- selectedThis = this;
- selectedDate = date;
- selectedInst = inst;
-}
-
-function callback2(year, month, inst) {
- selectedThis = this;
- selectedDate = year + "/" + month;
- selectedInst = inst;
-}
-
-test("events", function() {
- expect( 26 );
- var dateStr, newMonthYear, inp2,
- inp = testHelper.init("#inp", {onSelect: callback}),
- date = new Date();
- // onSelect
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(selectedThis, inp[0], "Callback selected this");
- equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback selected inst");
- equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date),
- "Callback selected date");
- inp.val("").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 7);
- equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date),
- "Callback selected date - ctrl+down");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date),
- "Callback selected date - esc");
- dateStr = "02/04/2008";
- inp.val(dateStr).datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(dateStr, selectedDate,
- "onSelect is called after enter keydown");
- // onChangeMonthYear
- inp.datepicker("option", {onChangeMonthYear: callback2, onSelect: null}).
- val("").datepicker("show");
- newMonthYear = function(date) {
- return date.getFullYear() + "/" + (date.getMonth() + 1);
- };
- date = new Date();
- date.setDate(1);
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP});
- date.setMonth(date.getMonth() - 1);
- equal(selectedThis, inp[0], "Callback change month/year this");
- equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback change month/year inst");
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year date - pgup");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN});
- date.setMonth(date.getMonth() + 1);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year date - pgdn");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP});
- date.setFullYear(date.getFullYear() - 1);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year date - ctrl+pgup");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME});
- date.setFullYear(date.getFullYear() + 1);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year date - ctrl+home");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN});
- date.setFullYear(date.getFullYear() + 1);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year date - ctrl+pgdn");
- inp.datepicker("setDate", new Date(2007, 1 - 1, 26));
- equal(selectedDate, "2007/1", "Callback change month/year date - setDate");
- selectedDate = null;
- inp.datepicker("setDate", new Date(2007, 1 - 1, 12));
- ok(selectedDate == null, "Callback change month/year date - setDate no change");
- // onChangeMonthYear step by 2
- inp.datepicker("option", {stepMonths: 2}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP});
- date.setMonth(date.getMonth() - 14);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year by 2 date - pgup");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP});
- date.setMonth(date.getMonth() - 12);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year by 2 date - ctrl+pgup");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN});
- date.setMonth(date.getMonth() + 2);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year by 2 date - pgdn");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN});
- date.setMonth(date.getMonth() + 12);
- equal(selectedDate, newMonthYear(date),
- "Callback change month/year by 2 date - ctrl+pgdn");
- // onClose
- inp.datepicker("option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}).
- val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- equal(selectedThis, inp[0], "Callback close this");
- equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback close inst");
- equal(selectedDate, "", "Callback close date - esc");
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", new Date()),
- "Callback close date - enter");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- equal(selectedDate, "02/04/2008", "Callback close date - preset");
- inp.val("02/04/2008").datepicker("show").
- simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END});
- equal(selectedDate, "", "Callback close date - ctrl+end");
-
- inp2 = testHelper.init("#inp2");
- inp2.datepicker().datepicker("option", {onClose: callback}).datepicker("show");
- inp.datepicker("show");
- equal(selectedThis, inp2[0], "Callback close this");
-});
+module( "datepicker: events" );
-test("beforeShowDay-getDate", function() {
+test( "beforeOpen", function() {
expect( 3 );
- var inp = testHelper.init("#inp", {beforeShowDay: function() { inp.datepicker("getDate"); return [true, ""]; }}),
- dp = $("#ui-datepicker-div");
- inp.val("01/01/2010").datepicker("show");
- // contains non-breaking space
- equal($("div.ui-datepicker-title").text(),
- // support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>January&#xa0;2010</span>" ).text(), "Initial month");
- $("a.ui-datepicker-next", dp).trigger( "click" );
- $("a.ui-datepicker-next", dp).trigger( "click" );
- // contains non-breaking space
- equal($("div.ui-datepicker-title").text(),
- $( "<span>March&#xa0;2010</span>" ).text(), "After next clicks");
- inp.datepicker("hide").datepicker("show");
- $("a.ui-datepicker-prev", dp).trigger( "click" );
- $("a.ui-datepicker-prev", dp).trigger( "click" );
- // contains non-breaking space
- equal($("div.ui-datepicker-title").text(),
- $( "<span>November&#xa0;2009</span>" ).text(), "After prev clicks");
- inp.datepicker("hide");
+
+ var input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
+ ok( true, "beforeOpen event fired before open" );
+ ok( input.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" );
+ },
+ open: function() {
+ ok( input.datepicker( "widget" ).is( ":visible" ), "calendar open on open" );
+ }
+ });
+
+ input
+ .datepicker( "open" )
+ .datepicker( "close" )
+ .datepicker( "option", {
+ beforeOpen: function() {
+ return false;
+ },
+ open: function() {
+ ok( false, "calendar should not open when openBefore is canceled" );
+ }
+ })
+ .datepicker( "open" );
+});
+
+test( "close", function() {
+ expect( 4 );
+
+ var shouldFire,
+ input = testHelper.init( "#datepicker", {
+ close: function() {
+ ok( shouldFire, "close event fired" );
+ }
+ });
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.datepicker( "close" );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ $( "body" ).trigger( "mousedown" );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" );
+});
+
+test( "open", function() {
+ expect( 2 );
+
+ var input = testHelper.init( "#datepicker", {
+ open: function() {
+ ok( true, "open event fired on open" );
+ ok( widget.is( ":visible" ), "calendar open on open" );
+ }
+ }),
+ widget = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+});
+
+asyncTest( "select", function() {
+ expect( 4 );
+
+ var input = testHelper.init( "#datepicker", {
+ select: function( event ) {
+ ok( true, "select event fired " + message );
+ equal(
+ event.originalEvent.type,
+ "calendarselect",
+ "select originalEvent " + message
+ );
+ }
+ }),
+ widget = input.datepicker( "widget" ),
+ message = "";
+
+ function step1() {
+ message = "on calendar cell click";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout(function() {
+ widget.find( "tbody tr:first button:first" ).simulate( "mousedown" );
+ input.datepicker( "close" );
+ step2();
+ }, 100 );
+ }
+
+ function step2() {
+ message = "on calendar cell enter";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout(function() {
+ $( document.activeElement )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ input.datepicker( "close" );
+ step3();
+ }, 100 );
+ }
+
+ function step3() {
+ message = "on calendar escape (not expected)";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout(function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ input.datepicker( "close" );
+ start();
+ }, 100 );
+ }
+
+ step1();
});
} );
diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js
index a9753a89a..81fdd9d00 100644
--- a/tests/unit/datepicker/helper.js
+++ b/tests/unit/datepicker/helper.js
@@ -5,34 +5,30 @@ define( [
], function( $, helper ) {
return $.extend( helper, {
- addMonths: function(date, offset) {
- var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate();
- date.setDate(Math.min(date.getDate(), maxDay));
- date.setMonth(date.getMonth() + offset);
+ addMonths: function( date, offset ) {
+ var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate();
+ date.setDate( Math.min( date.getDate(), maxDay ) );
+ date.setMonth( date.getMonth() + offset );
return date;
},
-
- equalsDate: function(d1, d2, message) {
- if (!d1 || !d2) {
- ok(false, message + " - missing date");
+ equalsDate: function( d1, d2, message ) {
+ if ( !d1 || !d2 ) {
+ ok( false, message + " - missing date" );
return;
}
- d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate());
- d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
- equal(d1.toString(), d2.toString(), message);
+ d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() );
+ d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() );
+ equal( d1.toString(), d2.toString(), message );
},
-
init: function( id, options ) {
- $.datepicker.setDefaults( $.datepicker.regional[ "" ] );
- return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) );
+ options = $.extend( { show: false, hide: false }, options || {} );
+ return $( id ).datepicker( options );
},
-
initNewInput: function( options ) {
- var id = $( "<input>" ).appendTo( "#qunit-fixture" );
- return this.init( id, options );
- },
-
- PROP_NAME: "datepicker"
+ options = $.extend( { show: false, hide: false }, options || {} );
+ return $( "<input>" ).datepicker( options )
+ .appendTo( "#qunit-fixture" );
+ }
} );
} );
diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js
index 571b4cb98..f05958af0 100644
--- a/tests/unit/datepicker/methods.js
+++ b/tests/unit/datepicker/methods.js
@@ -4,123 +4,125 @@ define( [
"ui/widgets/datepicker"
], function( $, testHelper ) {
-module("datepicker: methods");
-
-test("destroy", function() {
- expect( 33 );
- var inl,
- inp = testHelper.init("#inp");
- ok(inp.is(".hasDatepicker"), "Default - marker class set");
- ok($.data(inp[0], testHelper.PROP_NAME), "Default - instance present");
- ok(inp.next().is("#alt"), "Default - button absent");
- inp.datepicker("destroy");
- inp = $("#inp");
- ok(!inp.is(".hasDatepicker"), "Default - marker class cleared");
- ok(!$.data(inp[0], testHelper.PROP_NAME), "Default - instance absent");
- ok(inp.next().is("#alt"), "Default - button absent");
- // With button
- inp= testHelper.init("#inp", {showOn: "both"});
- ok(inp.is(".hasDatepicker"), "Button - marker class set");
- ok($.data(inp[0], testHelper.PROP_NAME), "Button - instance present");
- ok(inp.next().text() === "...", "Button - button added");
- inp.datepicker("destroy");
- inp = $("#inp");
- ok(!inp.is(".hasDatepicker"), "Button - marker class cleared");
- ok(!$.data(inp[0], testHelper.PROP_NAME), "Button - instance absent");
- ok(inp.next().is("#alt"), "Button - button removed");
- // With append text
- inp = testHelper.init("#inp", {appendText: "Testing"});
- ok(inp.is(".hasDatepicker"), "Append - marker class set");
- ok($.data(inp[0], testHelper.PROP_NAME), "Append - instance present");
- ok(inp.next().text() === "Testing", "Append - append text added");
- inp.datepicker("destroy");
- inp = $("#inp");
- ok(!inp.is(".hasDatepicker"), "Append - marker class cleared");
- ok(!$.data(inp[0], testHelper.PROP_NAME), "Append - instance absent");
- ok(inp.next().is("#alt"), "Append - append text removed");
- // With both
- inp= testHelper.init("#inp", {showOn: "both", buttonImageOnly: true,
- buttonImage: "images/calendar.gif", appendText: "Testing"});
- ok(inp.is(".hasDatepicker"), "Both - marker class set");
- ok($.data(inp[0], testHelper.PROP_NAME), "Both - instance present");
- ok(inp.next()[0].nodeName.toLowerCase() === "img", "Both - button added");
- ok(inp.next().next().text() === "Testing", "Both - append text added");
- inp.datepicker("destroy");
- inp = $("#inp");
- ok(!inp.is(".hasDatepicker"), "Both - marker class cleared");
- ok(!$.data(inp[0], testHelper.PROP_NAME), "Both - instance absent");
- ok(inp.next().is("#alt"), "Both - button and append text absent");
- // Inline
- inl = testHelper.init("#inl");
- ok(inl.is(".hasDatepicker"), "Inline - marker class set");
- ok(inl.html() !== "", "Inline - datepicker present");
- ok($.data(inl[0], testHelper.PROP_NAME), "Inline - instance present");
- ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent");
- inl.datepicker("destroy");
- inl = $("#inl");
- ok(!inl.is(".hasDatepicker"), "Inline - marker class cleared");
- ok(inl.html() === "", "Inline - datepicker absent");
- ok(!$.data(inl[0], testHelper.PROP_NAME), "Inline - instance absent");
- ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent");
+module( "datepicker: methods" );
+
+test( "destroy", function( assert ) {
+ expect( 3 );
+
+ var input = $( "#datepicker" );
+ assert.domEqual( input, function() {
+ input.datepicker();
+ ok( input.attr( "aria-owns" ), "aria-owns attribute added" );
+ ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" );
+ input.datepicker( "destroy" );
+ });
+});
+
+test( "enable / disable", function() {
+ expect( 10 );
+
+ var input = testHelper.init( "#datepicker" ),
+ calendar = input.datepicker( "widget" );
+
+ input.datepicker( "disable" );
+ ok( input.datepicker( "option", "disabled" ), "disabled option is set" );
+ ok( calendar.hasClass( "ui-datepicker-disabled" ), "has disabled widget class name" );
+ ok( input.hasClass( "ui-state-disabled" ), "has disabled state class name" );
+ equal( input.attr( "aria-disabled" ), "true", "has ARIA disabled" );
+ equal( input.attr( "disabled" ), "disabled", "input disabled" );
+
+ input.datepicker( "enable" );
+ ok( !input.datepicker( "option", "disabled" ), "enabled after enable() call" );
+ ok( !calendar.hasClass( "ui-datepicker-disabled" ), "no longer has disabled widget class name" );
+ ok( !input.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" );
+ equal( input.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" );
+ equal( input.attr( "disabled" ), undefined, "input no longer disabled" );
+});
+
+test( "widget", function() {
+ expect( 1 );
+
+ var actual = $( "#datepicker" ).datepicker().datepicker( "widget" );
+ deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] );
+ actual.remove();
+});
+
+test( "open / close", function() {
+ expect( 7 );
+
+ var input = testHelper.initNewInput({ show: false, hide: false }),
+ calendar = input.datepicker( "widget" );
+
+ ok( calendar.is( ":hidden" ), "calendar hidden on init" );
+
+ input.datepicker( "open" );
+ ok( calendar.is( ":visible" ), "open: calendar visible" );
+ equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" );
+ equal( calendar.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" );
+
+ input.datepicker( "close" );
+ ok( !calendar.is( ":visible" ), "close: calendar hidden" );
+ equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" );
+ equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" );
});
-test("enableDisable", function() {
- expect( 33 );
- var inl, dp,
- inp = testHelper.init("#inp");
- ok(!inp.datepicker("isDisabled"), "Enable/disable - initially marked as enabled");
- ok(!inp[0].disabled, "Enable/disable - field initially enabled");
- inp.datepicker("disable");
- ok(inp.datepicker("isDisabled"), "Enable/disable - now marked as disabled");
- ok(inp[0].disabled, "Enable/disable - field now disabled");
- inp.datepicker("enable");
- ok(!inp.datepicker("isDisabled"), "Enable/disable - now marked as enabled");
- ok(!inp[0].disabled, "Enable/disable - field now enabled");
- inp.datepicker("destroy");
- // With a button
- inp = testHelper.init("#inp", {showOn: "button"});
- ok(!inp.datepicker("isDisabled"), "Enable/disable button - initially marked as enabled");
- ok(!inp[0].disabled, "Enable/disable button - field initially enabled");
- ok(!inp.next("button")[0].disabled, "Enable/disable button - button initially enabled");
- inp.datepicker("disable");
- ok(inp.datepicker("isDisabled"), "Enable/disable button - now marked as disabled");
- ok(inp[0].disabled, "Enable/disable button - field now disabled");
- ok(inp.next("button")[0].disabled, "Enable/disable button - button now disabled");
- inp.datepicker("enable");
- ok(!inp.datepicker("isDisabled"), "Enable/disable button - now marked as enabled");
- ok(!inp[0].disabled, "Enable/disable button - field now enabled");
- ok(!inp.next("button")[0].disabled, "Enable/disable button - button now enabled");
- inp.datepicker("destroy");
- // With an image button
- inp = testHelper.init("#inp", {showOn: "button", buttonImageOnly: true,
- buttonImage: "images/calendar.gif"});
- ok(!inp.datepicker("isDisabled"), "Enable/disable image - initially marked as enabled");
- ok(!inp[0].disabled, "Enable/disable image - field initially enabled");
- ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image initially enabled");
- inp.datepicker("disable");
- ok(inp.datepicker("isDisabled"), "Enable/disable image - now marked as disabled");
- ok(inp[0].disabled, "Enable/disable image - field now disabled");
- ok(parseFloat(inp.next("img").css("opacity")) !== 1, "Enable/disable image - image now disabled");
- inp.datepicker("enable");
- ok(!inp.datepicker("isDisabled"), "Enable/disable image - now marked as enabled");
- ok(!inp[0].disabled, "Enable/disable image - field now enabled");
- ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image now enabled");
- inp.datepicker("destroy");
- // Inline
- inl = testHelper.init("#inl", {changeYear: true});
- dp = $(".ui-datepicker-inline", inl);
- ok(!inl.datepicker("isDisabled"), "Enable/disable inline - initially marked as enabled");
- ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visually disabled initially");
- ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled initially");
- inl.datepicker("disable");
- ok(inl.datepicker("isDisabled"), "Enable/disable inline - now marked as disabled");
- ok(dp.children().is(".ui-state-disabled"), "Enable/disable inline - visually disabled");
- ok(dp.find("select").prop("disabled"), "Enable/disable inline - form element disabled");
- inl.datepicker("enable");
- ok(!inl.datepicker("isDisabled"), "Enable/disable inline - now marked as enabled");
- ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visiually disabled");
- ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled");
- inl.datepicker("destroy");
+test( "value", function() {
+ expect( 4 );
+
+ var input = $( "#datepicker" ).datepicker(),
+ picker = input.datepicker( "widget" );
+
+ input.datepicker( "value", "1/1/14" );
+ equal( input.val(), "1/1/14", "input's value set" );
+
+ input.datepicker( "open" );
+ ok(
+ picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ),
+ "first day marked as selected"
+ );
+ equal( input.datepicker( "value" ), "1/1/14", "getter" );
+
+ input.val( "abc" );
+ strictEqual( input.datepicker( "value" ), null, "Invalid values should return null." );
+});
+
+test( "valueAsDate", function() {
+ expect( 6 );
+
+ var input = testHelper.init( "#datepicker" ),
+ picker = input.datepicker( "widget" ),
+ date1 = new Date( 2008, 6 - 1, 4 );
+
+ input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) );
+ equal( input.val(), "1/1/14", "Input's value set" );
+ ok(
+ picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ),
+ "First day marked as selected"
+ );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
+
+ input.val( "a/b/c" );
+ equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" );
+
+ input.val( "" ).datepicker( "destroy" );
+ input = testHelper.init( "#datepicker" );
+
+ strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" );
+ input.datepicker( "valueAsDate", date1 );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" );
+});
+
+test( "isValid", function() {
+ expect( 2 );
+ var input = $( "#datepicker" ).datepicker();
+
+ input.val( "1/1/14" );
+ ok( input.datepicker( "isValid" ) );
+
+ input.val( "1/1/abc" );
+ ok( !input.datepicker( "isValid" ) );
+
+ input.datepicker( "destroy" );
});
} );
diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js
index 3a6c15c6d..75d745460 100644
--- a/tests/unit/datepicker/options.js
+++ b/tests/unit/datepicker/options.js
@@ -1,1127 +1,141 @@
define( [
"jquery",
"./helper",
- "ui/widgets/datepicker",
- "ui/i18n/datepicker-fr",
- "ui/i18n/datepicker-he",
- "ui/i18n/datepicker-zh-CN"
+ "ui/widgets/datepicker"
], function( $, testHelper ) {
-module("datepicker: options");
-
-test("setDefaults", function() {
- expect( 3 );
- testHelper.init("#inp");
- equal($.datepicker._defaults.showOn, "focus", "Initial showOn");
- $.datepicker.setDefaults({showOn: "button"});
- equal($.datepicker._defaults.showOn, "button", "Change default showOn");
- $.datepicker.setDefaults({showOn: "focus"});
- equal($.datepicker._defaults.showOn, "focus", "Restore showOn");
-});
-
-test("option", function() {
- expect( 17 );
- var inp = testHelper.init("#inp"),
- inst = $.data(inp[0], testHelper.PROP_NAME);
- // Set option
- equal(inst.settings.showOn, null, "Initial setting showOn");
- equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Initial default showOn");
- inp.datepicker("option", "showOn", "button");
- equal(inst.settings.showOn, "button", "Change setting showOn");
- equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
- inp.datepicker("option", {showOn: "both"});
- equal(inst.settings.showOn, "both", "Change setting showOn");
- equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
- inp.datepicker("option", "showOn", undefined);
- equal(inst.settings.showOn, null, "Clear setting showOn");
- equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
- // Get option
- inp = testHelper.init("#inp");
- equal(inp.datepicker("option", "showOn"), "focus", "Initial setting showOn");
- inp.datepicker("option", "showOn", "button");
- equal(inp.datepicker("option", "showOn"), "button", "Change instance showOn");
- inp.datepicker("option", "showOn", undefined);
- equal(inp.datepicker("option", "showOn"), "focus", "Reset instance showOn");
- deepEqual(inp.datepicker("option", "all"), {showAnim: ""}, "Get instance settings");
- deepEqual(inp.datepicker("option", "defaults"), $.datepicker._defaults,
- "Get default settings");
-});
-
-test( "disabled", function() {
- expect(8);
- var inp = testHelper.init("#inp");
- ok(!inp.datepicker("isDisabled"), "Initially marked as enabled");
- ok(!inp[0].disabled, "Field initially enabled");
- inp.datepicker("option", "disabled", true);
- ok(inp.datepicker("isDisabled"), "Marked as disabled");
- ok(inp[0].disabled, "Field now disabled");
- inp.datepicker("option", "disabled", false);
- ok(!inp.datepicker("isDisabled"), "Marked as enabled");
- ok(!inp[0].disabled, "Field now enabled");
- inp.datepicker("destroy");
-
- inp = testHelper.init("#inp", { disabled: true });
- ok(inp.datepicker("isDisabled"), "Initially marked as disabled");
- ok(inp[0].disabled, "Field initially disabled");
-});
-
-test("change", function() {
- expect( 12 );
- var inp = testHelper.init("#inp"),
- inst = $.data(inp[0], testHelper.PROP_NAME);
- equal(inst.settings.showOn, null, "Initial setting showOn");
- equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Initial default showOn");
- inp.datepicker("change", "showOn", "button");
- equal(inst.settings.showOn, "button", "Change setting showOn");
- equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
- inp.datepicker("change", {showOn: "both"});
- equal(inst.settings.showOn, "both", "Change setting showOn");
- equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
- inp.datepicker("change", "showOn", undefined);
- equal(inst.settings.showOn, null, "Clear setting showOn");
- equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn");
- equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
-});
-
-(function() {
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) );
-
- // TODO: This test occassionally fails in IE in TestSwarm
- if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) {
- return;
- }
-
- asyncTest( "invocation", function() {
- var button, image,
- isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ),
- body = $( "body" );
-
- expect( isOldIE ? 25 : 29 );
-
- function step0() {
- var inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- button = inp.siblings( "button" );
- ok( button.length === 0, "Focus - button absent" );
- image = inp.siblings( "img" );
- ok( image.length === 0, "Focus - image absent" );
-
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Focus - rendered on focus" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- ok( !dp.is( ":visible" ), "Focus - hidden on exit" );
- step1();
- });
- }
-
- function step1() {
-
- var inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Focus - rendered on focus" );
- body.simulate( "mousedown", {} );
- ok( !dp.is( ":visible" ), "Focus - hidden on external click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step2();
- });
- }
-
- function step2() {
- var inp = testHelper.initNewInput({
- showOn: "button",
- buttonText: "Popup"
- }),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Button - initially hidden" );
- button = inp.siblings( "button" );
- image = inp.siblings( "img" );
- ok( button.length === 1, "Button - button present" );
- ok( image.length === 0, "Button - image absent" );
- equal( button.text(), "Popup", "Button - button text" );
-
- testHelper.onFocus( inp, function() {
- ok( !dp.is( ":visible" ), "Button - not rendered on focus" );
- button.trigger( "click" );
- ok( dp.is( ":visible" ), "Button - rendered on button click" );
- button.trigger( "click" );
- ok( !dp.is( ":visible" ), "Button - hidden on second button click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step3();
- });
- }
-
- function step3() {
- var inp = testHelper.initNewInput({
- showOn: "button",
- buttonImageOnly: true,
- buttonImage: "images/calendar.gif",
- buttonText: "Cal"
- }),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Image button - initially hidden" );
- button = inp.siblings( "button" );
- ok( button.length === 0, "Image button - button absent" );
- image = inp.siblings( "img" );
- ok( image.length === 1, "Image button - image present" );
- ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" );
- equal( image.attr( "title" ), "Cal", "Image button - image text" );
-
- testHelper.onFocus( inp, function() {
- ok( !dp.is( ":visible" ), "Image button - not rendered on focus" );
- image.trigger( "click" );
- ok( dp.is( ":visible" ), "Image button - rendered on image click" );
- image.trigger( "click" );
- ok( !dp.is( ":visible" ), "Image button - hidden on second image click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step4();
- });
+module( "datepicker: options" );
+
+test( "appendTo", function() {
+ expect( 6 );
+ var container,
+ detached = $( "<div>" ),
+ input = $( "#datepicker" );
+
+ input.datepicker();
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, document.body, "defaults to body" );
+ input.datepicker( "destroy" );
+
+ input.datepicker({ appendTo: "#qunit-fixture" });
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" );
+ input.datepicker( "destroy" );
+
+ input.datepicker({ appendTo: "#does-not-exist" });
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, document.body, "set to body if element does not exist" );
+ input.datepicker( "destroy" );
+
+ input.datepicker()
+ .datepicker( "option", "appendTo", "#qunit-fixture" );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" );
+ input.datepicker( "destroy" );
+
+ input.datepicker({ appendTo: detached });
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, detached[ 0 ], "detached jQuery object" );
+ input.datepicker( "destroy" );
+
+ input.datepicker({ appendTo: detached[ 0 ] });
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, detached[ 0 ], "detached DOM element" );
+ input.datepicker( "destroy" );
+});
+
+test( "Pass-through options", function() {
+ expect( 11 );
+
+ var options = {
+ buttons: { "Test": $.noop },
+ dateFormat: { date: "full" },
+ disabled: true,
+ eachDay: function( day ) { day; },
+ locale: "de",
+ max: new Date( 2000, 0, 1 ),
+ min: new Date( 2000, 0, 2 ),
+ numberOfMonths: 3,
+ showWeek: true
+ },
+ input = $( "#datepicker" ).val( "1/1/14" ).datepicker(),
+ datepickerInstance = input.datepicker( "instance" );
+
+ $.each( options, function( key, value ) {
+ input.datepicker( "option", key, value );
+
+ deepEqual(
+ datepickerInstance.calendar.calendar( "option", key ),
+ value,
+ "option " + key + ": correct value"
+ );
+
+ if ( key === "dateFormat" ) {
+ equal( input.val(), "Wednesday, January 1, 2014", "option " + key + ": updated format" );
}
- function step4() {
- var inp = testHelper.initNewInput({
- showOn: "both",
- buttonImage: "images/calendar.gif"
- }),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Both - initially hidden" );
- button = inp.siblings( "button" );
- ok( button.length === 1, "Both - button present" );
- image = inp.siblings( "img" );
- ok( image.length === 0, "Both - image absent" );
- image = button.children( "img" );
- ok( image.length === 1, "Both - button image present" );
-
- // TODO: This test occasionally fails to focus in IE8 in BrowserStack
- if ( !isOldIE ) {
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Both - rendered on focus" );
- body.simulate( "mousedown", {} );
- ok( !dp.is( ":visible" ), "Both - hidden on external click" );
- button.trigger( "click" );
- ok( dp.is( ":visible" ), "Both - rendered on button click" );
- button.trigger( "click" );
- ok( !dp.is( ":visible" ), "Both - hidden on second button click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- start();
- });
- } else {
- start();
- }
+ if ( key === "locale" ) {
+ equal( input.val(), "Mittwoch, 1. Januar 2014", "option " + key + ": updated locale" );
}
-
- step0();
});
-})();
-
-test("otherMonths", function() {
- expect( 8 );
- var inp = testHelper.init("#inp"),
- pop = $("#ui-datepicker-div");
- inp.val("06/01/2009").datepicker("show");
- equal(pop.find("tbody").text(),
- // support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0</span>" ).text(),
- "Other months - none");
- ok(pop.find("td:last *").length === 0, "Other months - no content");
- inp.datepicker("hide").datepicker("option", "showOtherMonths", true).datepicker("show");
- equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234",
- "Other months - show");
- ok(pop.find("td:last span").length === 1, "Other months - span content");
- inp.datepicker("hide").datepicker("option", "selectOtherMonths", true).datepicker("show");
- equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234",
- "Other months - select");
- ok(pop.find("td:last a").length === 1, "Other months - link content");
- inp.datepicker("hide").datepicker("option", "showOtherMonths", false).datepicker("show");
- equal(pop.find("tbody").text(),
- // support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0</span>" ).text(),
- "Other months - none");
- ok(pop.find("td:last *").length === 0, "Other months - no content");
-});
-
-test("defaultDate", function() {
- expect( 16 );
- var inp = testHelper.init("#inp"),
- date = new Date();
- inp.val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date null");
-
- // Numeric values
- inp.datepicker("option", {defaultDate: -2}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 2);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2");
-
- date = new Date();
- inp.datepicker("option", {defaultDate: 3}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 3);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 3");
-
- date = new Date();
- inp.datepicker("option", {defaultDate: 1 / "a"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date NaN");
-
- // String offset values
- inp.datepicker("option", {defaultDate: "-1d"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1d");
- inp.datepicker("option", {defaultDate: "+3D"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 4);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +3D");
- inp.datepicker("option", {defaultDate: " -2 w "}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = new Date();
- date.setDate(date.getDate() - 14);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2 w");
- inp.datepicker("option", {defaultDate: "+1 W"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 21);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 W");
- inp.datepicker("option", {defaultDate: " -1 m "}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = testHelper.addMonths(new Date(), -1);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1 m");
- inp.datepicker("option", {defaultDate: "+2M"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = testHelper.addMonths(new Date(), 2);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +2M");
- inp.datepicker("option", {defaultDate: "-2y"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = new Date();
- date.setFullYear(date.getFullYear() - 2);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2y");
- inp.datepicker("option", {defaultDate: "+1 Y "}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date.setFullYear(date.getFullYear() + 3);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 Y");
- inp.datepicker("option", {defaultDate: "+1M +10d"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = testHelper.addMonths(new Date(), 1);
- date.setDate(date.getDate() + 10);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1M +10d");
- // String date values
- inp.datepicker("option", {defaultDate: "07/04/2007"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = new Date(2007, 7 - 1, 4);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 07/04/2007");
- inp.datepicker("option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = new Date(2007, 4 - 1, 2);
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 2007-04-02");
- // Date value
- date = new Date(2007, 1 - 1, 26);
- inp.datepicker("option", {dateFormat: "mm/dd/yy", defaultDate: date}).
- datepicker("hide").val("").datepicker("show").
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 01/26/2007");
-});
-
-test("miscellaneous", function() {
- expect( 19 );
- var curYear, longNames, shortNames, date,
- dp = $("#ui-datepicker-div"),
- inp = testHelper.init("#inp");
- // Year range
- function genRange(start, offset) {
- var i = start,
- range = "";
- for (; i < start + offset; i++) {
- range += i;
- }
- return range;
- }
- curYear = new Date().getFullYear();
- inp.val("02/04/2008").datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), "2008", "Year range - read-only default");
- inp.datepicker("hide").datepicker("option", {changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 10, 21), "Year range - changeable default");
- inp.datepicker("hide").datepicker("option", {yearRange: "c-6:c+2", changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 6, 9), "Year range - c-6:c+2");
- inp.datepicker("hide").datepicker("option", {yearRange: "2000:2010", changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(2000, 11), "Year range - 2000:2010");
- inp.datepicker("hide").datepicker("option", {yearRange: "-5:+3", changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(curYear - 5, 9), "Year range - -5:+3");
- inp.datepicker("hide").datepicker("option", {yearRange: "2000:-5", changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(2000, curYear - 2004), "Year range - 2000:-5");
- inp.datepicker("hide").datepicker("option", {yearRange: "", changeYear: true}).datepicker("show");
- equal(dp.find(".ui-datepicker-year").text(), genRange(curYear, 1), "Year range - -6:+2");
-
- // Navigation as date format
- inp.datepicker("option", {showButtonPanel: true});
- equal(dp.find(".ui-datepicker-prev").text(), "Prev", "Navigation prev - default");
- equal(dp.find(".ui-datepicker-current").text(), "Today", "Navigation current - default");
- equal(dp.find(".ui-datepicker-next").text(), "Next", "Navigation next - default");
- inp.datepicker("hide").datepicker("option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}).
- val("02/04/2008").datepicker("show");
- longNames = $.datepicker.regional[""].monthNames;
- shortNames = $.datepicker.regional[""].monthNamesShort;
- date = new Date();
- equal(dp.find(".ui-datepicker-prev").text(), "< " + shortNames[0], "Navigation prev - as date format");
- equal(dp.find(".ui-datepicker-current").text(),
- longNames[date.getMonth()], "Navigation current - as date format");
- equal(dp.find(".ui-datepicker-next").text(),
- shortNames[2] + " >", "Navigation next - as date format");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN});
- equal(dp.find(".ui-datepicker-prev").text(),
- "< " + shortNames[1], "Navigation prev - as date format + pgdn");
- equal(dp.find(".ui-datepicker-current").text(),
- longNames[date.getMonth()], "Navigation current - as date format + pgdn");
- equal(dp.find(".ui-datepicker-next").text(),
- shortNames[3] + " >", "Navigation next - as date format + pgdn");
- inp.datepicker("hide").datepicker("option", {gotoCurrent: true}).
- val("02/04/2008").datepicker("show");
- equal(dp.find(".ui-datepicker-prev").text(),
- "< " + shortNames[0], "Navigation prev - as date format + goto current");
- equal(dp.find(".ui-datepicker-current").text(),
- longNames[1], "Navigation current - as date format + goto current");
- equal(dp.find(".ui-datepicker-next").text(),
- shortNames[2] + " >", "Navigation next - as date format + goto current");
});
-test("minMax", function() {
- expect( 23 );
- var date,
- inp = testHelper.init("#inp"),
- dp = $("#ui-datepicker-div"),
- lastYear = new Date(2007, 6 - 1, 4),
- nextYear = new Date(2009, 6 - 1, 4),
- minDate = new Date(2008, 2 - 1, 29),
- maxDate = new Date(2008, 12 - 1, 7);
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), lastYear,
- "Min/max - null, null - ctrl+pgup");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), nextYear,
- "Min/max - null, null - ctrl+pgdn");
- inp.datepicker("option", {minDate: minDate}).
- datepicker("hide").val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), minDate,
- "Min/max - 02/29/2008, null - ctrl+pgup");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), nextYear,
- "Min/max - 02/29/2008, null - ctrl+pgdn");
- inp.datepicker("option", {maxDate: maxDate}).
- datepicker("hide").val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), minDate,
- "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate,
- "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn");
- inp.datepicker("option", {minDate: null}).
- datepicker("hide").val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), lastYear,
- "Min/max - null, 12/07/2008 - ctrl+pgup");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate,
- "Min/max - null, 12/07/2008 - ctrl+pgdn");
- // Relative dates
- date = new Date();
- date.setDate(date.getDate() - 7);
- inp.datepicker("option", {minDate: "-1w", maxDate: "+1 M +10 D "}).
- datepicker("hide").val("").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date,
- "Min/max - -1w, +1 M +10 D - ctrl+pgup");
- date = testHelper.addMonths(new Date(), 1);
- date.setDate(date.getDate() + 10);
- inp.val("").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- testHelper.equalsDate(inp.datepicker("getDate"), date,
- "Min/max - -1w, +1 M +10 D - ctrl+pgdn");
- // With existing date
- inp = testHelper.init("#inp");
- inp.val("06/04/2008").datepicker("option", {minDate: minDate});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min");
- inp.datepicker("option", {minDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate});
- testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min");
- inp.datepicker("option", {minDate: null}).val("06/04/2008").datepicker("option", {maxDate: maxDate});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate < max");
- inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {maxDate: maxDate});
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max");
- inp.datepicker("option", {maxDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate});
- testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min");
- inp.datepicker("option", {maxDate: null}).val("06/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate});
- testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max");
- inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {minDate: minDate, maxDate: maxDate});
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max");
-
- inp.datepicker("option", {yearRange: "-0:+1"}).val("01/01/" + new Date().getFullYear());
- ok(dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - previous button disabled at 1/1/minYear");
- inp.datepicker("setDate", "12/30/" + new Date().getFullYear());
- ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled at 12/30/maxYear");
-
- inp.datepicker("option", {
- minDate: new Date(1900, 0, 1),
- maxDate: "-7Y",
- yearRange: "1900:-7"
- }).val( "" );
- ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - relative - next button disabled");
- ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - relative - prev button enabled");
-
- inp.datepicker("option", {
- minDate: new Date(1900, 0, 1),
- maxDate: "1/25/2007",
- yearRange: "1900:2007"
- }).val( "" );
- ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - absolute - next button disabled");
- ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - absolute - prev button enabled");
-});
-
-test("setDate", function() {
- expect( 24 );
- var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
- inp = testHelper.init("#inp"),
- date1 = new Date(2008, 6 - 1, 4),
- date2 = new Date();
- ok(inp.datepicker("getDate") == null, "Set date - default");
- inp.datepicker("setDate", date1);
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - 2008-06-04");
- date1 = new Date();
- date1.setDate(date1.getDate() + 7);
- inp.datepicker("setDate", +7);
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - +7");
- date2.setFullYear(date2.getFullYear() + 2);
- inp.datepicker("setDate", "+2y");
- testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date - +2y");
- inp.datepicker("setDate", date1, date2);
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - two dates");
- inp.datepicker("setDate");
- ok(inp.datepicker("getDate") == null, "Set date - null");
- // Relative to current date
- date1 = new Date();
- date1.setDate(date1.getDate() + 7);
- inp.datepicker("setDate", "c +7");
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c +7");
- date1.setDate(date1.getDate() + 7);
- inp.datepicker("setDate", "c+7");
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c+7");
- date1.setDate(date1.getDate() - 21);
- inp.datepicker("setDate", "c -3 w");
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c -3 w");
- // Inline
- inl = testHelper.init("#inl");
- date1 = new Date(2008, 6 - 1, 4);
- date2 = new Date();
- testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - default");
- inl.datepicker("setDate", date1);
- testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - 2008-06-04");
- date1 = new Date();
- date1.setDate(date1.getDate() + 7);
- inl.datepicker("setDate", +7);
- testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - +7");
- date2.setFullYear(date2.getFullYear() + 2);
- inl.datepicker("setDate", "+2y");
- testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - +2y");
- inl.datepicker("setDate", date1, date2);
- testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - two dates");
- inl.datepicker("setDate");
- ok(inl.datepicker("getDate") == null, "Set date inline - null");
- // Alternate field
- alt = $("#alt");
- inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"});
- date1 = new Date(2008, 6 - 1, 4);
- inp.datepicker("setDate", date1);
- equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008");
- equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04");
- // With minimum/maximum
- inp = testHelper.init("#inp");
- date1 = new Date(2008, 1 - 1, 4);
- date2 = new Date(2008, 6 - 1, 4);
- minDate = new Date(2008, 2 - 1, 29);
- maxDate = new Date(2008, 3 - 1, 28);
- inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date2);
- testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date min/max - setDate > min");
- inp.datepicker("setDate", date1);
- testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min");
- inp.val("").datepicker("option", {maxDate: maxDate, minDate: null}).datepicker("setDate", date1);
- testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date min/max - setDate < max");
- inp.datepicker("setDate", date2);
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max");
- inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date1);
- testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min");
- inp.datepicker("setDate", date2);
- testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max");
- dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0);
- dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0);
- inp.datepicker("setDate", dateAndTimeToSet);
- equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate");
-});
-
-test("altField", function() {
- expect( 10 );
- var inp = testHelper.init("#inp"),
- alt = $("#alt");
- // No alternate field set
- alt.val("");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(inp.val(), "06/04/2008", "Alt field - dp - enter");
- equal(alt.val(), "", "Alt field - alt not set");
- // Alternate field set
- alt.val("");
- inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}).
- val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(inp.val(), "06/04/2008", "Alt field - dp - enter");
- equal(alt.val(), "2008-06-04", "Alt field - alt - enter");
- // Move from initial date
- alt.val("");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn");
- equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn");
- // Alternate field set - closed
- alt.val("");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}).
- simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc");
- equal(alt.val(), "", "Alt field - alt - pgdn/esc");
- // Clear date and alternate
- alt.val("");
- inp.val("06/04/2008").datepicker("show");
- inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END});
- equal(inp.val(), "", "Alt field - dp - ctrl+end");
- equal(alt.val(), "", "Alt field - alt - ctrl+end");
-});
-
-test("autoSize", function() {
- expect( 15 );
- var inp = testHelper.init("#inp");
- equal(inp.prop("size"), 20, "Auto size - default");
- inp.datepicker("option", "autoSize", true);
- equal(inp.prop("size"), 10, "Auto size - mm/dd/yy");
- inp.datepicker("option", "dateFormat", "m/d/yy");
- equal(inp.prop("size"), 10, "Auto size - m/d/yy");
- inp.datepicker("option", "dateFormat", "D M d yy");
- equal(inp.prop("size"), 15, "Auto size - D M d yy");
- inp.datepicker("option", "dateFormat", "DD, MM dd, yy");
- equal(inp.prop("size"), 29, "Auto size - DD, MM dd, yy");
-
- // French
- inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.fr));
- equal(inp.prop("size"), 29, "Auto size - fr - default");
- inp.datepicker("option", "autoSize", true);
- equal(inp.prop("size"), 10, "Auto size - fr - dd/mm/yy");
- inp.datepicker("option", "dateFormat", "m/d/yy");
- equal(inp.prop("size"), 10, "Auto size - fr - m/d/yy");
- inp.datepicker("option", "dateFormat", "D M d yy");
- equal(inp.prop("size"), 18, "Auto size - fr - D M d yy");
- inp.datepicker("option", "dateFormat", "DD, MM dd, yy");
- equal(inp.prop("size"), 28, "Auto size - fr - DD, MM dd, yy");
-
- // Hebrew
- inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.he));
- equal(inp.prop("size"), 28, "Auto size - he - default");
- inp.datepicker("option", "autoSize", true);
- equal(inp.prop("size"), 10, "Auto size - he - dd/mm/yy");
- inp.datepicker("option", "dateFormat", "m/d/yy");
- equal(inp.prop("size"), 10, "Auto size - he - m/d/yy");
- inp.datepicker("option", "dateFormat", "D M d yy");
- equal(inp.prop("size"), 16, "Auto size - he - D M d yy");
- inp.datepicker("option", "dateFormat", "DD, MM dd, yy");
- equal(inp.prop("size"), 23, "Auto size - he - DD, MM dd, yy");
-});
-
-test("daylightSaving", function() {
- expect( 25 );
- var inp = testHelper.init("#inp"),
- dp = $("#ui-datepicker-div");
- ok(true, "Daylight saving - " + new Date());
- // Australia, Sydney - AM change, southern hemisphere
- inp.val("04/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click");
- equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008");
- inp.val("04/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click");
- equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008");
- inp.val("04/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click");
- equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click");
- equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click");
- equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click");
- equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008");
- // Brasil, Brasilia - midnight change, southern hemisphere
- inp.val("02/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(20) a", dp).simulate("click");
- equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008");
- inp.val("02/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(21) a", dp).simulate("click");
- equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008");
- inp.val("02/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(22) a", dp).simulate("click");
- equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click");
- equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click");
- equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click");
- equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008");
- // Lebanon, Beirut - midnight change, northern hemisphere
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(34) a", dp).simulate("click");
- equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008");
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(35) a", dp).simulate("click");
- equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008");
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(36) a", dp).simulate("click");
- equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(27) a", dp).simulate("click");
- equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(28) a", dp).simulate("click");
- equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008");
- inp.val("10/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(29) a", dp).simulate("click");
- equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008");
- // US, Eastern - AM change, northern hemisphere
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click");
- equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008");
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click");
- equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008");
- inp.val("03/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click");
- equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008");
- inp.val("11/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click");
- equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008");
- inp.val("11/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click");
- equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008");
- inp.val("11/01/2008").datepicker("show");
- $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click");
- equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008");
-});
-
-var beforeShowThis = null,
- beforeShowInput = null,
- beforeShowInst = null,
- beforeShowDayThis = null,
- beforeShowDayOK = true;
-
-function beforeAll(input, inst) {
- beforeShowThis = this;
- beforeShowInput = input;
- beforeShowInst = inst;
- return {currentText: "Current"};
-}
-
-function beforeDay(date) {
- beforeShowDayThis = this;
- beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) &&
- date < new Date(2008, 3 - 1, 6));
- return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : ""),
- (date.getDate() % 3 === 0 ? "Divisble by 3" : "")];
-}
-
-test("callbacks", function() {
- expect( 13 );
- // Before show
- var dp, day20, day21,
- inp = testHelper.init("#inp", {beforeShow: beforeAll}),
- inst = $.data(inp[0], "datepicker");
- equal($.datepicker._get(inst, "currentText"), "Today", "Before show - initial");
- inp.val("02/04/2008").datepicker("show");
- equal($.datepicker._get(inst, "currentText"), "Current", "Before show - changed");
- ok(beforeShowThis.id === inp[0].id, "Before show - this OK");
- ok(beforeShowInput.id === inp[0].id, "Before show - input OK");
- deepEqual(beforeShowInst, inst, "Before show - inst OK");
- inp.datepicker("hide").datepicker("destroy");
- // Before show day
- inp = testHelper.init("#inp", {beforeShowDay: beforeDay});
- dp = $("#ui-datepicker-div");
- inp.val("02/04/2008").datepicker("show");
- ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK");
- ok(beforeShowDayOK, "Before show day - dates OK");
- day20 = dp.find(".ui-datepicker-calendar td:contains('20')");
- day21 = dp.find(".ui-datepicker-calendar td:contains('21')");
- ok(!day20.is(".ui-datepicker-unselectable"), "Before show day - unselectable 20");
- ok(day21.is(".ui-datepicker-unselectable"), "Before show day - unselectable 21");
- ok(day20.is(".day10"), "Before show day - CSS 20");
- ok(!day21.is(".day10"), "Before show day - CSS 21");
- ok(!day20.attr("title"), "Before show day - title 20");
- ok(day21.attr("title") === "Divisble by 3", "Before show day - title 21");
- inp.datepicker("hide").datepicker("destroy");
-});
-
-test("beforeShowDay - tooltips with quotes", function() {
- expect( 1 );
- var inp, dp;
- inp = testHelper.init("#inp", {
- beforeShowDay: function() {
- return [ true, "", "'" ];
- }
- });
- dp = $("#ui-datepicker-div");
-
- inp.datepicker("show");
- equal( dp.find( ".ui-datepicker-calendar td:contains('9')").attr( "title" ), "'" );
- inp.datepicker("hide").datepicker("destroy");
-});
-
-test("localisation", function() {
- expect( 24 );
- var dp, month, day, date,
- inp = testHelper.init("#inp", $.datepicker.regional.fr);
- inp.datepicker("option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val("").datepicker("show");
- dp = $("#ui-datepicker-div");
- equal($(".ui-datepicker-close", dp).text(), "Fermer", "Localisation - close");
- $(".ui-datepicker-close", dp).simulate("mouseover");
- equal($(".ui-datepicker-prev", dp).text(), "Précédent", "Localisation - previous");
- equal($(".ui-datepicker-current", dp).text(), "Aujourd'hui", "Localisation - current");
- equal($(".ui-datepicker-next", dp).text(), "Suivant", "Localisation - next");
- month = 0;
- $(".ui-datepicker-month option", dp).each(function() {
- equal($(this).text(), $.datepicker.regional.fr.monthNamesShort[month],
- "Localisation - month " + month);
- month++;
- });
- day = 1;
- $(".ui-datepicker-calendar th", dp).each(function() {
- equal($(this).text(), $.datepicker.regional.fr.dayNamesMin[day],
- "Localisation - day " + day);
- day = (day + 1) % 7;
+asyncTest( "position", function(assert) {
+ expect( 3 );
+ var input = $( "<input>" ).datepicker().appendTo( "body" ).css({
+ position: "absolute",
+ top: 0,
+ left: 0
+ }),
+ container = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+ setTimeout(function() {
+ assert.close( input.offset().left, container.offset().left, 1, "left sides line up by default" );
+ assert.close( container.offset().top, input.offset().top + input.outerHeight(), 1,
+ "datepicker directly under input by default" );
+
+ // Change the position option using option()
+ input.datepicker( "option", "position", {
+ my: "left top",
+ at: "right bottom"
+ });
+ assert.close( container.offset().left, input.offset().left + input.outerWidth(), 1,
+ "datepicker on right hand side of input after position change" );
+
+ input.remove();
+ start();
});
- inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER});
- date = new Date();
- equal(inp.val(), $.datepicker.regional.fr.dayNames[date.getDay()] + ", " +
- date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] +
- " " + date.getFullYear(), "Localisation - formatting");
-});
-
-test("noWeekends", function() {
- expect( 31 );
- var i, date;
- for (i = 1; i <= 31; i++) {
- date = new Date(2001, 1 - 1, i);
- deepEqual($.datepicker.noWeekends(date), [(i + 1) % 7 >= 2, ""],
- "No weekends " + date);
- }
-});
-
-test("iso8601Week", function() {
- expect( 12 );
- var date = new Date(2000, 12 - 1, 31);
- equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date);
- date = new Date(2001, 1 - 1, 1);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
- date = new Date(2001, 1 - 1, 7);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
- date = new Date(2001, 1 - 1, 8);
- equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date);
- date = new Date(2003, 12 - 1, 28);
- equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date);
- date = new Date(2003, 12 - 1, 29);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
- date = new Date(2004, 1 - 1, 4);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
- date = new Date(2004, 1 - 1, 5);
- equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date);
- date = new Date(2009, 12 - 1, 28);
- equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date);
- date = new Date(2010, 1 - 1, 3);
- equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date);
- date = new Date(2010, 1 - 1, 4);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
- date = new Date(2010, 1 - 1, 10);
- equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date);
});
-test("parseDate", function() {
- expect( 26 );
- testHelper.init("#inp");
- var currentYear, gmtDate, fr, settings, zh;
- ok($.datepicker.parseDate("d m y", "") == null, "Parse date empty");
- testHelper.equalsDate($.datepicker.parseDate("d m y", "3 2 01"),
- new Date(2001, 2 - 1, 3), "Parse date d m y");
- testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "03 02 2001"),
- new Date(2001, 2 - 1, 3), "Parse date dd mm yy");
- testHelper.equalsDate($.datepicker.parseDate("d m y", "13 12 01"),
- new Date(2001, 12 - 1, 13), "Parse date d m y");
- testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "13 12 2001"),
- new Date(2001, 12 - 1, 13), "Parse date dd mm yy");
- testHelper.equalsDate($.datepicker.parseDate("y-o", "01-34"),
- new Date(2001, 2 - 1, 3), "Parse date y-o");
- testHelper.equalsDate($.datepicker.parseDate("yy-oo", "2001-347"),
- new Date(2001, 12 - 1, 13), "Parse date yy-oo");
- testHelper.equalsDate($.datepicker.parseDate("oo yy", "348 2004"),
- new Date(2004, 12 - 1, 13), "Parse date oo yy");
- testHelper.equalsDate($.datepicker.parseDate("D d M y", "Sat 3 Feb 01"),
- new Date(2001, 2 - 1, 3), "Parse date D d M y");
- testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "3 February Saturday 2001"),
- new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy");
- testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Saturday, February 3, 2001"),
- new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy");
- testHelper.equalsDate($.datepicker.parseDate("'day' d 'of' MM (''DD''), yy",
- "day 3 of February ('Saturday'), 2001"), new Date(2001, 2 - 1, 3),
- "Parse date 'day' d 'of' MM (''DD''), yy");
- currentYear = new Date().getFullYear();
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000) + "-02-03"),
- new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 10) + "-02-03"),
- new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 11) + "-02-03"),
- new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", "80-02-03", {shortYearCutoff: 80}),
- new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", "81-02-03", {shortYearCutoff: 80}),
- new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}),
- new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60");
- testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}),
- new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60");
- gmtDate = new Date(2001, 2 - 1, 3);
- gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset());
- testHelper.equalsDate($.datepicker.parseDate("@", "981158400000"), gmtDate, "Parse date @");
- testHelper.equalsDate($.datepicker.parseDate("!", "631167552000000000"), gmtDate, "Parse date !");
-
- fr = $.datepicker.regional.fr;
- settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
- testHelper.equalsDate($.datepicker.parseDate("D d M y", "Lun. 9 avr. 01", settings),
- new Date(2001, 4 - 1, 9), "Parse date D M y with settings");
- testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "9 Avril Lundi 2001", settings),
- new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings");
- testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Lundi, Avril 9, 2001", settings),
- new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings");
- testHelper.equalsDate($.datepicker.parseDate("'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings),
- new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings");
-
- zh = $.datepicker.regional["zh-CN"];
- testHelper.equalsDate($.datepicker.parseDate("yy M d", "2011 十一月 22", zh),
- new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN");
-});
-
-test("parseDateErrors", function() {
- expect( 18 );
- testHelper.init("#inp");
- var fr, settings;
- function expectError(expr, value, error) {
- try {
- expr();
- ok(false, "Parsed error " + value);
- }
- catch (e) {
- equal(e, error, "Parsed error " + value);
- }
- }
- expectError(function() { $.datepicker.parseDate(null, "Sat 2 01"); },
- "Sat 2 01", "Invalid arguments");
- expectError(function() { $.datepicker.parseDate("d m y", null); },
- "null", "Invalid arguments");
- expectError(function() { $.datepicker.parseDate("d m y", "Sat 2 01"); },
- "Sat 2 01 - d m y", "Missing number at position 0");
- expectError(function() { $.datepicker.parseDate("dd mm yy", "Sat 2 01"); },
- "Sat 2 01 - dd mm yy", "Missing number at position 0");
- expectError(function() { $.datepicker.parseDate("d m y", "3 Feb 01"); },
- "3 Feb 01 - d m y", "Missing number at position 2");
- expectError(function() { $.datepicker.parseDate("dd mm yy", "3 Feb 01"); },
- "3 Feb 01 - dd mm yy", "Missing number at position 2");
- expectError(function() { $.datepicker.parseDate("mm dd yy", "2 1 01"); },
- "2 1 01 - dd mm yy", "Missing number at position 4");
- expectError(function() { $.datepicker.parseDate("d m y", "3 2 AD01"); },
- "3 2 AD01 - d m y", "Missing number at position 4");
- expectError(function() { $.datepicker.parseDate("d m yy", "3 2 AD01"); },
- "3 2 AD01 - dd mm yy", "Missing number at position 4");
- expectError(function() { $.datepicker.parseDate("y-o", "01-D01"); },
- "2001-D01 - y-o", "Missing number at position 3");
- expectError(function() { $.datepicker.parseDate("yy-oo", "2001-D01"); },
- "2001-D01 - yy-oo", "Missing number at position 5");
- expectError(function() { $.datepicker.parseDate("D d M y", "D7 3 Feb 01"); },
- "D7 3 Feb 01 - D d M y", "Unknown name at position 0");
- expectError(function() { $.datepicker.parseDate("D d M y", "Sat 3 M2 01"); },
- "Sat 3 M2 01 - D d M y", "Unknown name at position 6");
- expectError(function() { $.datepicker.parseDate("DD, MM d, yy", "Saturday- Feb 3, 2001"); },
- "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8");
- expectError(function() { $.datepicker.parseDate("'day' d 'of' MM (''DD''), yy",
- "day 3 of February (\"Saturday\"), 2001"); },
- "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19");
- expectError(function() { $.datepicker.parseDate("d m y", "29 2 01"); },
- "29 2 01 - d m y", "Invalid date");
- fr = $.datepicker.regional.fr;
- settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
- expectError(function() { $.datepicker.parseDate("D d M y", "Mon 9 Avr 01", settings); },
- "Mon 9 Avr 01 - D d M y", "Unknown name at position 0");
- expectError(function() { $.datepicker.parseDate("D d M y", "Lun. 9 Apr 01", settings); },
- "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7");
-});
-
-test("Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() {
- expect( 4 );
- var date;
- try{
- date = $.datepicker.parseDate("dd/mm/yy", "18/04/19881");
- ok(false, "Did not properly detect an invalid date");
- }catch(e){
- ok("invalid date detected");
- }
-
- try {
- date = $.datepicker.parseDate("dd/mm/yy", "18/04/1988 @ 2:43 pm");
- equal(date.getDate(), 18);
- equal(date.getMonth(), 3);
- equal(date.getFullYear(), 1988);
- } catch(e) {
- ok(false, "Did not properly parse date with extra text separated by whitespace");
- }
-});
-
-test("formatDate", function() {
- expect( 16 );
- testHelper.init("#inp");
- var gmtDate, fr, settings;
- equal($.datepicker.formatDate("d m y", new Date(2001, 2 - 1, 3)),
- "3 2 01", "Format date d m y");
- equal($.datepicker.formatDate("dd mm yy", new Date(2001, 2 - 1, 3)),
- "03 02 2001", "Format date dd mm yy");
- equal($.datepicker.formatDate("d m y", new Date(2001, 12 - 1, 13)),
- "13 12 01", "Format date d m y");
- equal($.datepicker.formatDate("dd mm yy", new Date(2001, 12 - 1, 13)),
- "13 12 2001", "Format date dd mm yy");
- equal($.datepicker.formatDate("yy-o", new Date(2001, 2 - 1, 3)),
- "2001-34", "Format date yy-o");
- equal($.datepicker.formatDate("yy-oo", new Date(2001, 2 - 1, 3)),
- "2001-034", "Format date yy-oo");
- equal($.datepicker.formatDate("D M y", new Date(2001, 2 - 1, 3)),
- "Sat Feb 01", "Format date D M y");
- equal($.datepicker.formatDate("DD MM yy", new Date(2001, 2 - 1, 3)),
- "Saturday February 2001", "Format date DD MM yy");
- equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 2 - 1, 3)),
- "Saturday, February 3, 2001", "Format date DD, MM d, yy");
- equal($.datepicker.formatDate("'day' d 'of' MM (''DD''), yy",
- new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001",
- "Format date 'day' d 'of' MM ('DD'), yy");
- gmtDate = new Date(2001, 2 - 1, 3);
- gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset());
- equal($.datepicker.formatDate("@", gmtDate), "981158400000", "Format date @");
- equal($.datepicker.formatDate("!", gmtDate), "631167552000000000", "Format date !");
- fr = $.datepicker.regional.fr;
- settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
- equal($.datepicker.formatDate("D M y", new Date(2001, 4 - 1, 9), settings),
- "lun. avr. 01", "Format date D M y with settings");
- equal($.datepicker.formatDate("DD MM yy", new Date(2001, 4 - 1, 9), settings),
- "lundi avril 2001", "Format date DD MM yy with settings");
- equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 4 - 1, 9), settings),
- "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings");
- equal($.datepicker.formatDate("'jour' d 'de' MM (''DD''), yy",
- new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001",
- "Format date 'jour' d 'de' MM (''DD''), yy with settings");
-});
-
-// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos
-// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){
-// expect( 1 );
-// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT"));
-// equal(time, "089");
-// });
-
-test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() {
+test( "Stop datepicker from appearing with beforeOpen event handler", function() {
expect( 3 );
- var inp, dp;
-
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
- }
+ var input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {}
});
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "block", "beforeShow returns nothing" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
+ input.datepicker( "open" );
+ ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" );
+ input.datepicker( "close" ).datepicker( "destroy" );
+
+ input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
return true;
}
});
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "block", "beforeShow returns true" );
- inp.datepicker( "hide" );
- inp.datepicker( "destroy" );
+ input.datepicker( "open" );
+ ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" );
+ input.datepicker( "close" ).datepicker( "destroy" );
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
+ input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
return false;
}
});
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "none","beforeShow returns false" );
- inp.datepicker( "destroy" );
+ input.datepicker( "open" );
+ ok( !input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" );
+ input.datepicker( "destroy" );
});
} );
diff --git a/tests/unit/index.html b/tests/unit/index.html
index 418cfd34c..d6c214fa5 100644
--- a/tests/unit/index.html
+++ b/tests/unit/index.html
@@ -39,6 +39,7 @@
<ul>
<li><a href="accordion/accordion.html">Accordion</a></li>
<li><a href="autocomplete/autocomplete.html">Autocomplete</a></li>
+ <li><a href="calendar/calendar.html">Calendar</a></li>
<li><a href="button/button.html">Button</a></li>
<li><a href="datepicker/datepicker.html">Datepicker</a></li>
<li><a href="dialog/dialog.html">Dialog</a></li>
diff --git a/tests/unit/spinner/options.js b/tests/unit/spinner/options.js
index d43c968cd..6a9d3e9b7 100644
--- a/tests/unit/spinner/options.js
+++ b/tests/unit/spinner/options.js
@@ -1,8 +1,8 @@
define( [
"jquery",
"ui/widgets/spinner",
- "globalize",
- "globalize/ja-JP"
+ "globalize-old",
+ "globalize-old/ja-JP"
], function( $ ) {
module( "spinner: options" );
diff --git a/tests/visual/compound/datepicker_dialog.html b/tests/visual/compound/datepicker_dialog.html
index 52c91a083..374b2aeb5 100644
--- a/tests/visual/compound/datepicker_dialog.html
+++ b/tests/visual/compound/datepicker_dialog.html
@@ -6,6 +6,9 @@
<link rel="stylesheet" href="../visual.css">
<link rel="stylesheet" href="../../../themes/base/all.css">
<script src="../../../external/jquery/jquery.js"></script>
+ <script src="../../../external/globalize/globalize.js"></script>
+ <script src="../../../external/date.js"></script>
+ <script src="../../../external/localization.js"></script>
<script src="../../../ui/core.js"></script>
<script src="../../../ui/widget.js"></script>
<script src="../../../ui/mouse.js"></script>
@@ -13,6 +16,7 @@
<script src="../../../ui/resizable.js"></script>
<script src="../../../ui/draggable.js"></script>
<script src="../../../ui/button.js"></script>
+ <script src="../../../ui/calendar.js"></script>
<script src="../../../ui/datepicker.js"></script>
<script src="../../../ui/dialog.js"></script>
<script>
diff --git a/tests/visual/compound/dialog_widgets.html b/tests/visual/compound/dialog_widgets.html
index 2258231e9..0f6396d9d 100644
--- a/tests/visual/compound/dialog_widgets.html
+++ b/tests/visual/compound/dialog_widgets.html
@@ -6,6 +6,9 @@
<link rel="stylesheet" href="../visual.css">
<link rel="stylesheet" href="../../../themes/base/all.css">
<script src="../../../external/jquery/jquery.js"></script>
+ <script src="../../../external/globalize/globalize.js"></script>
+ <script src="../../../external/date.js"></script>
+ <script src="../../../external/localization.js"></script>
<script src="../../../ui/core.js"></script>
<script src="../../../ui/widget.js"></script>
<script src="../../../ui/mouse.js"></script>
@@ -16,6 +19,7 @@
<script src="../../../ui/accordion.js"></script>
<script src="../../../ui/autocomplete.js"></script>
<script src="../../../ui/button.js"></script>
+ <script src="../../../ui/calendar.js"></script>
<script src="../../../ui/datepicker.js"></script>
<script src="../../../ui/dialog.js"></script>
<script src="../../../ui/progressbar.js"></script>
diff --git a/tests/visual/dialog/complex-dialogs.html b/tests/visual/dialog/complex-dialogs.html
index 9a6209be9..59844c6a9 100644
--- a/tests/visual/dialog/complex-dialogs.html
+++ b/tests/visual/dialog/complex-dialogs.html
@@ -15,6 +15,10 @@
<script src="../../../ui/dialog.js"></script>
<!-- stuff needed to make things complex -->
+ <script src="../../../external/globalize/globalize.js"></script>
+ <script src="../../../external/date.js"></script>
+ <script src="../../../external/localization.js"></script>
+ <script src="../../../ui/calendar.js"></script>
<script src="../../../ui/datepicker.js"></script>
<script src="../../../ui/menu.js"></script>
<script src="../../../ui/autocomplete.js"></script>
diff --git a/themes/base/base.css b/themes/base/base.css
index 3ed02661f..aa8e6d157 100644
--- a/themes/base/base.css
+++ b/themes/base/base.css
@@ -13,6 +13,7 @@
@import url("accordion.css");
@import url("autocomplete.css");
@import url("button.css");
+@import url("calendar.css");
@import url("datepicker.css");
@import url("dialog.css");
@import url("draggable.css");
diff --git a/themes/base/calendar.css b/themes/base/calendar.css
new file mode 100644
index 000000000..def9fe4ff
--- /dev/null
+++ b/themes/base/calendar.css
@@ -0,0 +1,158 @@
+/*!
+ * jQuery UI Calendar @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/calendar/#theming
+ */
+.ui-calendar {
+ width: 17em;
+ padding: .2em .2em 0;
+}
+
+/* calendar header */
+.ui-calendar .ui-calendar-header {
+ position: relative;
+ padding: .2em 0;
+}
+.ui-calendar .ui-calendar-prev,
+.ui-calendar .ui-calendar-next {
+ cursor: pointer;
+ position: absolute;
+ top: 2px;
+ width: 36px;
+ height: 31px;
+}
+.ui-calendar .ui-calendar-prev:not(.ui-state-hover):not(.ui-state-focus),
+.ui-calendar .ui-calendar-next:not(.ui-state-hover):not(.ui-state-focus) {
+ background: none;
+ border: none;
+}
+.ui-calendar .ui-calendar-prev {
+ left: 2px;
+}
+.ui-calendar .ui-calendar-next {
+ right: 2px;
+}
+.ui-calendar .ui-calendar-prev .ui-icon,
+.ui-calendar .ui-calendar-next .ui-icon {
+ display: block;
+ position: absolute;
+ left: 50%;
+ margin-left: -8px;
+ top: 50%;
+ margin-top: -8px;
+}
+.ui-calendar .ui-calendar-title {
+ line-height: 1.8em;
+ text-align: center;
+}
+
+/* calendar grid */
+.ui-calendar table {
+ width: 100%;
+ font-size: .9em;
+ border-collapse: collapse;
+ margin: 0 0 .4em;
+}
+.ui-calendar th {
+ padding: .7em .3em;
+ text-align: center;
+ font-weight: bold;
+ border: 0;
+}
+.ui-calendar td {
+ border: 0;
+ padding: 1px;
+}
+.ui-calendar td button {
+ display: block;
+ padding: .2em;
+ text-align: right;
+ cursor: pointer;
+ width: 100%;
+}
+.ui-calendar td button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+.ui-calendar .ui-state-disabled button {
+ cursor: default;
+}
+
+/* button pane */
+.ui-calendar .ui-calendar-buttonpane {
+ background-image: none;
+ margin: .7em 0 0 0;
+ padding: 0 .2em;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+.ui-calendar .ui-calendar-buttonpane button {
+ float: right;
+ margin: .5em .2em .4em;
+ cursor: pointer;
+ padding: .2em .6em .3em .6em;
+ width: auto;
+ overflow: visible;
+}
+.ui-calendar .ui-calendar-buttonpane button.ui-calendar-current {
+ float: left;
+}
+
+/* with multiple calendars */
+.ui-calendar-multi {
+ width: auto;
+ display: inline-block;
+}
+.ui-calendar-multi .ui-calendar-group {
+ width: 17em;
+ float: left;
+}
+.ui-calendar-multi .ui-calendar-group table {
+ width: 95%;
+ margin: 0 2.5% .4em;
+}
+.ui-calendar-multi .ui-calendar-buttonpane {
+ clear: left;
+}
+.ui-calendar-row-break {
+ clear: both;
+ width: 100%;
+ font-size: 0;
+}
+
+/* RTL support */
+.ui-calendar-rtl {
+ direction: rtl;
+}
+.ui-calendar-rtl .ui-calendar-prev {
+ right: 2px;
+ left: auto;
+}
+.ui-calendar-rtl .ui-calendar-next {
+ left: 2px;
+ right: auto;
+}
+.ui-calendar-rtl .ui-calendar-prev:hover {
+ right: 1px;
+ left: auto;
+}
+.ui-calendar-rtl .ui-calendar-next:hover {
+ left: 1px;
+ right: auto;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane {
+ clear: right;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane button {
+ float: left;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane button.ui-calendar-current,
+.ui-calendar-rtl .ui-calendar-group {
+ float: right;
+}
diff --git a/themes/base/datepicker.css b/themes/base/datepicker.css
index a77eab7b2..b19f5bda8 100644
--- a/themes/base/datepicker.css
+++ b/themes/base/datepicker.css
@@ -9,167 +9,7 @@
* http://api.jqueryui.com/datepicker/#theming
*/
.ui-datepicker {
- width: 17em;
- padding: .2em .2em 0;
display: none;
-}
-.ui-datepicker .ui-datepicker-header {
- position: relative;
- padding: .2em 0;
-}
-.ui-datepicker .ui-datepicker-prev,
-.ui-datepicker .ui-datepicker-next {
- position: absolute;
- top: 2px;
- width: 1.8em;
- height: 1.8em;
-}
-.ui-datepicker .ui-datepicker-prev-hover,
-.ui-datepicker .ui-datepicker-next-hover {
- top: 1px;
-}
-.ui-datepicker .ui-datepicker-prev {
- left: 2px;
-}
-.ui-datepicker .ui-datepicker-next {
- right: 2px;
-}
-.ui-datepicker .ui-datepicker-prev-hover {
- left: 1px;
-}
-.ui-datepicker .ui-datepicker-next-hover {
- right: 1px;
-}
-.ui-datepicker .ui-datepicker-prev span,
-.ui-datepicker .ui-datepicker-next span {
- display: block;
position: absolute;
- left: 50%;
- margin-left: -8px;
- top: 50%;
- margin-top: -8px;
-}
-.ui-datepicker .ui-datepicker-title {
- margin: 0 2.3em;
- line-height: 1.8em;
- text-align: center;
-}
-.ui-datepicker .ui-datepicker-title select {
- font-size: 1em;
- margin: 1px 0;
-}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year {
- width: 45%;
-}
-.ui-datepicker table {
- width: 100%;
- font-size: .9em;
- border-collapse: collapse;
- margin: 0 0 .4em;
-}
-.ui-datepicker th {
- padding: .7em .3em;
- text-align: center;
- font-weight: bold;
- border: 0;
-}
-.ui-datepicker td {
- border: 0;
- padding: 1px;
-}
-.ui-datepicker td span,
-.ui-datepicker td a {
- display: block;
- padding: .2em;
- text-align: right;
- text-decoration: none;
-}
-.ui-datepicker .ui-datepicker-buttonpane {
- background-image: none;
- margin: .7em 0 0 0;
- padding: 0 .2em;
- border-left: 0;
- border-right: 0;
- border-bottom: 0;
-}
-.ui-datepicker .ui-datepicker-buttonpane button {
- float: right;
- margin: .5em .2em .4em;
- cursor: pointer;
- padding: .2em .6em .3em .6em;
- width: auto;
- overflow: visible;
-}
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
- float: left;
}
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi {
- width: auto;
-}
-.ui-datepicker-multi .ui-datepicker-group {
- float: left;
-}
-.ui-datepicker-multi .ui-datepicker-group table {
- width: 95%;
- margin: 0 auto .4em;
-}
-.ui-datepicker-multi-2 .ui-datepicker-group {
- width: 50%;
-}
-.ui-datepicker-multi-3 .ui-datepicker-group {
- width: 33.3%;
-}
-.ui-datepicker-multi-4 .ui-datepicker-group {
- width: 25%;
-}
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
- border-left-width: 0;
-}
-.ui-datepicker-multi .ui-datepicker-buttonpane {
- clear: left;
-}
-.ui-datepicker-row-break {
- clear: both;
- width: 100%;
- font-size: 0;
-}
-
-/* RTL support */
-.ui-datepicker-rtl {
- direction: rtl;
-}
-.ui-datepicker-rtl .ui-datepicker-prev {
- right: 2px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next {
- left: 2px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-prev:hover {
- right: 1px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next:hover {
- left: 1px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane {
- clear: right;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button {
- float: left;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
-.ui-datepicker-rtl .ui-datepicker-group {
- float: right;
-}
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
- border-right-width: 0;
- border-left-width: 1px;
-}
diff --git a/ui/i18n/datepicker-af.js b/ui/i18n/datepicker-af.js
deleted file mode 100644
index 6c5355696..000000000
--- a/ui/i18n/datepicker-af.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Afrikaans initialisation for the jQuery UI date picker plugin. */
-/* Written by Renier Pretorius. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['af'] = {
- closeText: 'Selekteer',
- prevText: 'Vorige',
- nextText: 'Volgende',
- currentText: 'Vandag',
- monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie',
- 'Julie','Augustus','September','Oktober','November','Desember'],
- monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
- dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'],
- dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'],
- dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['af']);
-
-return datepicker.regional['af'];
-
-}));
diff --git a/ui/i18n/datepicker-ar-DZ.js b/ui/i18n/datepicker-ar-DZ.js
deleted file mode 100644
index ff003c998..000000000
--- a/ui/i18n/datepicker-ar-DZ.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/
-/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */
-
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ar-DZ'] = {
- closeText: 'إغلاق',
- prevText: '&#x3C;السابق',
- nextText: 'التالي&#x3E;',
- currentText: 'اليوم',
- monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان',
- 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'],
- monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
- dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
- dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
- dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
- weekHeader: 'أسبوع',
- dateFormat: 'dd/mm/yy',
- firstDay: 6,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ar-DZ']);
-
-return datepicker.regional['ar-DZ'];
-
-}));
diff --git a/ui/i18n/datepicker-ar.js b/ui/i18n/datepicker-ar.js
deleted file mode 100644
index 73ed1dfe0..000000000
--- a/ui/i18n/datepicker-ar.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Arabic Translation for jQuery UI date picker plugin. */
-/* Used in most of Arab countries, primarily in Bahrain, Kuwait, Oman, Qatar, Saudi Arabia and the United Arab Emirates, Egypt, Sudan and Yemen. */
-/* Written by Mohammed Alshehri -- m@dralshehri.com */
-
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ar'] = {
- closeText: 'إغلاق',
- prevText: '&#x3C;السابق',
- nextText: 'التالي&#x3E;',
- currentText: 'اليوم',
- monthNames: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو',
- 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
- monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
- dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
- dayNamesShort: ['أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة', 'سبت'],
- dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'],
- weekHeader: 'أسبوع',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ar']);
-
-return datepicker.regional['ar'];
-
-}));
diff --git a/ui/i18n/datepicker-az.js b/ui/i18n/datepicker-az.js
deleted file mode 100644
index 2ab92b1a5..000000000
--- a/ui/i18n/datepicker-az.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Jamil Najafov (necefov33@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['az'] = {
- closeText: 'Bağla',
- prevText: '&#x3C;Geri',
- nextText: 'İrəli&#x3E;',
- currentText: 'Bugün',
- monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun',
- 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
- monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun',
- 'İyul','Avq','Sen','Okt','Noy','Dek'],
- dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'],
- dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'],
- dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'],
- weekHeader: 'Hf',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['az']);
-
-return datepicker.regional['az'];
-
-}));
diff --git a/ui/i18n/datepicker-be.js b/ui/i18n/datepicker-be.js
deleted file mode 100644
index 8cb24592a..000000000
--- a/ui/i18n/datepicker-be.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Belarusian initialisation for the jQuery UI date picker plugin. */
-/* Written by Pavel Selitskas <p.selitskas@gmail.com> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['be'] = {
- closeText: 'Зачыніць',
- prevText: '&larr;Папяр.',
- nextText: 'Наст.&rarr;',
- currentText: 'Сёньня',
- monthNames: ['Студзень','Люты','Сакавік','Красавік','Травень','Чэрвень',
- 'Ліпень','Жнівень','Верасень','Кастрычнік','Лістапад','Сьнежань'],
- monthNamesShort: ['Сту','Лют','Сак','Кра','Тра','Чэр',
- 'Ліп','Жні','Вер','Кас','Ліс','Сьн'],
- dayNames: ['нядзеля','панядзелак','аўторак','серада','чацьвер','пятніца','субота'],
- dayNamesShort: ['ндз','пнд','аўт','срд','чцв','птн','сбт'],
- dayNamesMin: ['Нд','Пн','Аў','Ср','Чц','Пт','Сб'],
- weekHeader: 'Тд',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['be']);
-
-return datepicker.regional['be'];
-
-}));
diff --git a/ui/i18n/datepicker-bg.js b/ui/i18n/datepicker-bg.js
deleted file mode 100644
index c2db5e679..000000000
--- a/ui/i18n/datepicker-bg.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Bulgarian initialisation for the jQuery UI date picker plugin. */
-/* Written by Stoyan Kyosev (http://svest.org). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['bg'] = {
- closeText: 'затвори',
- prevText: '&#x3C;назад',
- nextText: 'напред&#x3E;',
- nextBigText: '&#x3E;&#x3E;',
- currentText: 'днес',
- monthNames: ['Януари','Февруари','Март','Април','Май','Юни',
- 'Юли','Август','Септември','Октомври','Ноември','Декември'],
- monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни',
- 'Юли','Авг','Сеп','Окт','Нов','Дек'],
- dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'],
- dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'],
- dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'],
- weekHeader: 'Wk',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['bg']);
-
-return datepicker.regional['bg'];
-
-}));
diff --git a/ui/i18n/datepicker-bs.js b/ui/i18n/datepicker-bs.js
deleted file mode 100644
index 3b83064f4..000000000
--- a/ui/i18n/datepicker-bs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Bosnian i18n for the jQuery UI date picker plugin. */
-/* Written by Kenan Konjo. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['bs'] = {
- closeText: 'Zatvori',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Danas',
- monthNames: ['Januar','Februar','Mart','April','Maj','Juni',
- 'Juli','August','Septembar','Oktobar','Novembar','Decembar'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Aug','Sep','Okt','Nov','Dec'],
- dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
- dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
- dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
- weekHeader: 'Wk',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['bs']);
-
-return datepicker.regional['bs'];
-
-}));
diff --git a/ui/i18n/datepicker-ca.js b/ui/i18n/datepicker-ca.js
deleted file mode 100644
index c35fa08a1..000000000
--- a/ui/i18n/datepicker-ca.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */
-/* Writers: (joan.leon@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ca'] = {
- closeText: 'Tanca',
- prevText: 'Anterior',
- nextText: 'Següent',
- currentText: 'Avui',
- monthNames: ['gener','febrer','març','abril','maig','juny',
- 'juliol','agost','setembre','octubre','novembre','desembre'],
- monthNamesShort: ['gen','feb','març','abr','maig','juny',
- 'jul','ag','set','oct','nov','des'],
- dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'],
- dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'],
- dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'],
- weekHeader: 'Set',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ca']);
-
-return datepicker.regional['ca'];
-
-}));
diff --git a/ui/i18n/datepicker-cs.js b/ui/i18n/datepicker-cs.js
deleted file mode 100644
index cb6dfe095..000000000
--- a/ui/i18n/datepicker-cs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Czech initialisation for the jQuery UI date picker plugin. */
-/* Written by Tomas Muller (tomas@tomas-muller.net). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['cs'] = {
- closeText: 'Zavřít',
- prevText: '&#x3C;Dříve',
- nextText: 'Později&#x3E;',
- currentText: 'Nyní',
- monthNames: ['leden','únor','březen','duben','květen','červen',
- 'červenec','srpen','září','říjen','listopad','prosinec'],
- monthNamesShort: ['led','úno','bře','dub','kvě','čer',
- 'čvc','srp','zář','říj','lis','pro'],
- dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
- dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
- dayNamesMin: ['ne','po','út','st','čt','pá','so'],
- weekHeader: 'Týd',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['cs']);
-
-return datepicker.regional['cs'];
-
-}));
diff --git a/ui/i18n/datepicker-cy-GB.js b/ui/i18n/datepicker-cy-GB.js
deleted file mode 100644
index 0935bd034..000000000
--- a/ui/i18n/datepicker-cy-GB.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Welsh/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by William Griffiths. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['cy-GB'] = {
- closeText: 'Done',
- prevText: 'Prev',
- nextText: 'Next',
- currentText: 'Today',
- monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin',
- 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'],
- monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh',
- 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'],
- dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'],
- dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'],
- dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'],
- weekHeader: 'Wy',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['cy-GB']);
-
-return datepicker.regional['cy-GB'];
-
-}));
diff --git a/ui/i18n/datepicker-da.js b/ui/i18n/datepicker-da.js
deleted file mode 100644
index 4c9f4b727..000000000
--- a/ui/i18n/datepicker-da.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Danish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jan Christensen ( deletestuff@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['da'] = {
- closeText: 'Luk',
- prevText: '&#x3C;Forrige',
- nextText: 'Næste&#x3E;',
- currentText: 'Idag',
- monthNames: ['Januar','Februar','Marts','April','Maj','Juni',
- 'Juli','August','September','Oktober','November','December'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Aug','Sep','Okt','Nov','Dec'],
- dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
- dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
- dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
- weekHeader: 'Uge',
- dateFormat: 'dd-mm-yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['da']);
-
-return datepicker.regional['da'];
-
-}));
diff --git a/ui/i18n/datepicker-de.js b/ui/i18n/datepicker-de.js
deleted file mode 100644
index 7de94e531..000000000
--- a/ui/i18n/datepicker-de.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* German initialisation for the jQuery UI date picker plugin. */
-/* Written by Milian Wolff (mail@milianw.de). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['de'] = {
- closeText: 'Schließen',
- prevText: '&#x3C;Zurück',
- nextText: 'Vor&#x3E;',
- currentText: 'Heute',
- monthNames: ['Januar','Februar','März','April','Mai','Juni',
- 'Juli','August','September','Oktober','November','Dezember'],
- monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
- 'Jul','Aug','Sep','Okt','Nov','Dez'],
- dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
- dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
- dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
- weekHeader: 'KW',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['de']);
-
-return datepicker.regional['de'];
-
-}));
diff --git a/ui/i18n/datepicker-el.js b/ui/i18n/datepicker-el.js
deleted file mode 100644
index 648a90631..000000000
--- a/ui/i18n/datepicker-el.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Greek (el) initialisation for the jQuery UI date picker plugin. */
-/* Written by Alex Cicovic (http://www.alexcicovic.com) */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['el'] = {
- closeText: 'Κλείσιμο',
- prevText: 'Προηγούμενος',
- nextText: 'Επόμενος',
- currentText: 'Σήμερα',
- monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος',
- 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'],
- monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν',
- 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'],
- dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'],
- dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'],
- dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'],
- weekHeader: 'Εβδ',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['el']);
-
-return datepicker.regional['el'];
-
-}));
diff --git a/ui/i18n/datepicker-en-AU.js b/ui/i18n/datepicker-en-AU.js
deleted file mode 100644
index c1f6b249f..000000000
--- a/ui/i18n/datepicker-en-AU.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/Australia initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['en-AU'] = {
- closeText: 'Done',
- prevText: 'Prev',
- nextText: 'Next',
- currentText: 'Today',
- monthNames: ['January','February','March','April','May','June',
- 'July','August','September','October','November','December'],
- monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
- dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['en-AU']);
-
-return datepicker.regional['en-AU'];
-
-}));
diff --git a/ui/i18n/datepicker-en-GB.js b/ui/i18n/datepicker-en-GB.js
deleted file mode 100644
index 0db301547..000000000
--- a/ui/i18n/datepicker-en-GB.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by Stuart. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['en-GB'] = {
- closeText: 'Done',
- prevText: 'Prev',
- nextText: 'Next',
- currentText: 'Today',
- monthNames: ['January','February','March','April','May','June',
- 'July','August','September','October','November','December'],
- monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
- dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['en-GB']);
-
-return datepicker.regional['en-GB'];
-
-}));
diff --git a/ui/i18n/datepicker-en-NZ.js b/ui/i18n/datepicker-en-NZ.js
deleted file mode 100644
index d40e15960..000000000
--- a/ui/i18n/datepicker-en-NZ.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/New Zealand initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['en-NZ'] = {
- closeText: 'Done',
- prevText: 'Prev',
- nextText: 'Next',
- currentText: 'Today',
- monthNames: ['January','February','March','April','May','June',
- 'July','August','September','October','November','December'],
- monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
- dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['en-NZ']);
-
-return datepicker.regional['en-NZ'];
-
-}));
diff --git a/ui/i18n/datepicker-eo.js b/ui/i18n/datepicker-eo.js
deleted file mode 100644
index d65a34237..000000000
--- a/ui/i18n/datepicker-eo.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Esperanto initialisation for the jQuery UI date picker plugin. */
-/* Written by Olivier M. (olivierweb@ifrance.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['eo'] = {
- closeText: 'Fermi',
- prevText: '&#x3C;Anta',
- nextText: 'Sekv&#x3E;',
- currentText: 'Nuna',
- monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio',
- 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Aŭg','Sep','Okt','Nov','Dec'],
- dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'],
- dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'],
- dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'],
- weekHeader: 'Sb',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['eo']);
-
-return datepicker.regional['eo'];
-
-}));
diff --git a/ui/i18n/datepicker-es.js b/ui/i18n/datepicker-es.js
deleted file mode 100644
index 79830c5f9..000000000
--- a/ui/i18n/datepicker-es.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Inicialización en español para la extensión 'UI date picker' para jQuery. */
-/* Traducido por Vester (xvester@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['es'] = {
- closeText: 'Cerrar',
- prevText: '&#x3C;Ant',
- nextText: 'Sig&#x3E;',
- currentText: 'Hoy',
- monthNames: ['enero','febrero','marzo','abril','mayo','junio',
- 'julio','agosto','septiembre','octubre','noviembre','diciembre'],
- monthNamesShort: ['ene','feb','mar','abr','may','jun',
- 'jul','ago','sep','oct','nov','dic'],
- dayNames: ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],
- dayNamesShort: ['dom','lun','mar','mié','jue','vie','sáb'],
- dayNamesMin: ['D','L','M','X','J','V','S'],
- weekHeader: 'Sm',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['es']);
-
-return datepicker.regional['es'];
-
-}));
diff --git a/ui/i18n/datepicker-et.js b/ui/i18n/datepicker-et.js
deleted file mode 100644
index ebffcdbd3..000000000
--- a/ui/i18n/datepicker-et.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Estonian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['et'] = {
- closeText: 'Sulge',
- prevText: 'Eelnev',
- nextText: 'Järgnev',
- currentText: 'Täna',
- monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni',
- 'Juuli','August','September','Oktoober','November','Detsember'],
- monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni',
- 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'],
- dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'],
- dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'],
- dayNamesMin: ['P','E','T','K','N','R','L'],
- weekHeader: 'näd',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['et']);
-
-return datepicker.regional['et'];
-
-}));
diff --git a/ui/i18n/datepicker-eu.js b/ui/i18n/datepicker-eu.js
deleted file mode 100644
index 6f15f3402..000000000
--- a/ui/i18n/datepicker-eu.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Karrikas-ek itzulia (karrikas@karrikas.com) */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['eu'] = {
- closeText: 'Egina',
- prevText: '&#x3C;Aur',
- nextText: 'Hur&#x3E;',
- currentText: 'Gaur',
- monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina',
- 'uztaila','abuztua','iraila','urria','azaroa','abendua'],
- monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.',
- 'uzt.','abu.','ira.','urr.','aza.','abe.'],
- dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'],
- dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'],
- dayNamesMin: ['ig','al','ar','az','og','ol','lr'],
- weekHeader: 'As',
- dateFormat: 'yy-mm-dd',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['eu']);
-
-return datepicker.regional['eu'];
-
-}));
diff --git a/ui/i18n/datepicker-fa.js b/ui/i18n/datepicker-fa.js
deleted file mode 100644
index 89abc5be1..000000000
--- a/ui/i18n/datepicker-fa.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */
-/* Javad Mowlanezhad -- jmowla@gmail.com */
-/* Jalali calendar should supported soon! (Its implemented but I have to test it) */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fa'] = {
- closeText: 'بستن',
- prevText: '&#x3C;قبلی',
- nextText: 'بعدی&#x3E;',
- currentText: 'امروز',
- monthNames: [
- 'ژانویه',
- 'فوریه',
- 'مارس',
- 'آوریل',
- 'مه',
- 'ژوئن',
- 'ژوئیه',
- 'اوت',
- 'سپتامبر',
- 'اکتبر',
- 'نوامبر',
- 'دسامبر'
- ],
- monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
- dayNames: [
- 'يکشنبه',
- 'دوشنبه',
- 'سه‌شنبه',
- 'چهارشنبه',
- 'پنجشنبه',
- 'جمعه',
- 'شنبه'
- ],
- dayNamesShort: [
- 'ی',
- 'د',
- 'س',
- 'چ',
- 'پ',
- 'ج',
- 'ش'
- ],
- dayNamesMin: [
- 'ی',
- 'د',
- 'س',
- 'چ',
- 'پ',
- 'ج',
- 'ش'
- ],
- weekHeader: 'هف',
- dateFormat: 'yy/mm/dd',
- firstDay: 6,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['fa']);
-
-return datepicker.regional['fa'];
-
-}));
diff --git a/ui/i18n/datepicker-fi.js b/ui/i18n/datepicker-fi.js
deleted file mode 100644
index a9964cfdd..000000000
--- a/ui/i18n/datepicker-fi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Finnish initialisation for the jQuery UI date picker plugin. */
-/* Written by Harri Kilpiö (harrikilpio@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fi'] = {
- closeText: 'Sulje',
- prevText: '&#xAB;Edellinen',
- nextText: 'Seuraava&#xBB;',
- currentText: 'Tänään',
- monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu',
- 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'],
- monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä',
- 'Heinä','Elo','Syys','Loka','Marras','Joulu'],
- dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'],
- dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'],
- dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'],
- weekHeader: 'Vk',
- dateFormat: 'd.m.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['fi']);
-
-return datepicker.regional['fi'];
-
-}));
diff --git a/ui/i18n/datepicker-fo.js b/ui/i18n/datepicker-fo.js
deleted file mode 100644
index 7b76db428..000000000
--- a/ui/i18n/datepicker-fo.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Faroese initialisation for the jQuery UI date picker plugin */
-/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fo'] = {
- closeText: 'Lat aftur',
- prevText: '&#x3C;Fyrra',
- nextText: 'Næsta&#x3E;',
- currentText: 'Í dag',
- monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni',
- 'Juli','August','September','Oktober','November','Desember'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
- 'Jul','Aug','Sep','Okt','Nov','Des'],
- dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'],
- dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'],
- dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'],
- weekHeader: 'Vk',
- dateFormat: 'dd-mm-yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['fo']);
-
-return datepicker.regional['fo'];
-
-}));
diff --git a/ui/i18n/datepicker-fr-CA.js b/ui/i18n/datepicker-fr-CA.js
deleted file mode 100644
index c3262b718..000000000
--- a/ui/i18n/datepicker-fr-CA.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Canadian-French initialisation for the jQuery UI date picker plugin. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fr-CA'] = {
- closeText: 'Fermer',
- prevText: 'Précédent',
- nextText: 'Suivant',
- currentText: 'Aujourd\'hui',
- monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
- 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
- monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin',
- 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
- dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
- dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
- dayNamesMin: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
- weekHeader: 'Sem.',
- dateFormat: 'yy-mm-dd',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''
-};
-datepicker.setDefaults(datepicker.regional['fr-CA']);
-
-return datepicker.regional['fr-CA'];
-
-}));
diff --git a/ui/i18n/datepicker-fr-CH.js b/ui/i18n/datepicker-fr-CH.js
deleted file mode 100644
index 727a79107..000000000
--- a/ui/i18n/datepicker-fr-CH.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Swiss-French initialisation for the jQuery UI date picker plugin. */
-/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fr-CH'] = {
- closeText: 'Fermer',
- prevText: '&#x3C;Préc',
- nextText: 'Suiv&#x3E;',
- currentText: 'Courant',
- monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
- 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
- monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin',
- 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
- dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
- dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
- dayNamesMin: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
- weekHeader: 'Sm',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['fr-CH']);
-
-return datepicker.regional['fr-CH'];
-
-}));
diff --git a/ui/i18n/datepicker-fr.js b/ui/i18n/datepicker-fr.js
deleted file mode 100644
index e4cb3f5af..000000000
--- a/ui/i18n/datepicker-fr.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* French initialisation for the jQuery UI date picker plugin. */
-/* Written by Keith Wood (kbwood{at}iinet.com.au),
- Stéphane Nahmani (sholby@sholby.net),
- Stéphane Raimbault <stephane.raimbault@gmail.com> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['fr'] = {
- closeText: 'Fermer',
- prevText: 'Précédent',
- nextText: 'Suivant',
- currentText: 'Aujourd\'hui',
- monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
- 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
- monthNamesShort: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',
- 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
- dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
- dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
- dayNamesMin: ['D','L','M','M','J','V','S'],
- weekHeader: 'Sem.',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['fr']);
-
-return datepicker.regional['fr'];
-
-}));
diff --git a/ui/i18n/datepicker-gl.js b/ui/i18n/datepicker-gl.js
deleted file mode 100644
index 45e94fcb9..000000000
--- a/ui/i18n/datepicker-gl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Galician localization for 'UI date picker' jQuery extension. */
-/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['gl'] = {
- closeText: 'Pechar',
- prevText: '&#x3C;Ant',
- nextText: 'Seg&#x3E;',
- currentText: 'Hoxe',
- monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño',
- 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'],
- monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ',
- 'Xul','Ago','Set','Out','Nov','Dec'],
- dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'],
- dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'],
- dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'],
- weekHeader: 'Sm',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['gl']);
-
-return datepicker.regional['gl'];
-
-}));
diff --git a/ui/i18n/datepicker-he.js b/ui/i18n/datepicker-he.js
deleted file mode 100644
index eeb9a2f7d..000000000
--- a/ui/i18n/datepicker-he.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Hebrew initialisation for the UI Datepicker extension. */
-/* Written by Amir Hardon (ahardon at gmail dot com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['he'] = {
- closeText: 'סגור',
- prevText: '&#x3C;הקודם',
- nextText: 'הבא&#x3E;',
- currentText: 'היום',
- monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני',
- 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'],
- monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני',
- 'יולי','אוג','ספט','אוק','נוב','דצמ'],
- dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'],
- dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
- dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['he']);
-
-return datepicker.regional['he'];
-
-}));
diff --git a/ui/i18n/datepicker-hi.js b/ui/i18n/datepicker-hi.js
deleted file mode 100644
index 78e2a9a63..000000000
--- a/ui/i18n/datepicker-hi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Hindi initialisation for the jQuery UI date picker plugin. */
-/* Written by Michael Dawart. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['hi'] = {
- closeText: 'बंद',
- prevText: 'पिछला',
- nextText: 'अगला',
- currentText: 'आज',
- monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून',
- 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'],
- monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून',
- 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'],
- dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'],
- dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
- dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
- weekHeader: 'हफ्ता',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['hi']);
-
-return datepicker.regional['hi'];
-
-}));
diff --git a/ui/i18n/datepicker-hr.js b/ui/i18n/datepicker-hr.js
deleted file mode 100644
index 7c278168e..000000000
--- a/ui/i18n/datepicker-hr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Croatian i18n for the jQuery UI date picker plugin. */
-/* Written by Vjekoslav Nesek. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['hr'] = {
- closeText: 'Zatvori',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Danas',
- monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj',
- 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'],
- monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip',
- 'Srp','Kol','Ruj','Lis','Stu','Pro'],
- dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
- dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
- dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
- weekHeader: 'Tje',
- dateFormat: 'dd.mm.yy.',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['hr']);
-
-return datepicker.regional['hr'];
-
-}));
diff --git a/ui/i18n/datepicker-hu.js b/ui/i18n/datepicker-hu.js
deleted file mode 100644
index 8d28e1aa6..000000000
--- a/ui/i18n/datepicker-hu.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Hungarian initialisation for the jQuery UI date picker plugin. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['hu'] = {
- closeText: 'bezár',
- prevText: 'vissza',
- nextText: 'előre',
- currentText: 'ma',
- monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június',
- 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],
- monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún',
- 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'],
- dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
- dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'],
- dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
- weekHeader: 'Hét',
- dateFormat: 'yy.mm.dd.',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['hu']);
-
-return datepicker.regional['hu'];
-
-}));
diff --git a/ui/i18n/datepicker-hy.js b/ui/i18n/datepicker-hy.js
deleted file mode 100644
index 69fb79fd1..000000000
--- a/ui/i18n/datepicker-hy.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['hy'] = {
- closeText: 'Փակել',
- prevText: '&#x3C;Նախ.',
- nextText: 'Հաջ.&#x3E;',
- currentText: 'Այսօր',
- monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս',
- 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'],
- monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս',
- 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'],
- dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'],
- dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
- dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
- weekHeader: 'ՇԲՏ',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['hy']);
-
-return datepicker.regional['hy'];
-
-}));
diff --git a/ui/i18n/datepicker-id.js b/ui/i18n/datepicker-id.js
deleted file mode 100644
index 135c8620e..000000000
--- a/ui/i18n/datepicker-id.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Indonesian initialisation for the jQuery UI date picker plugin. */
-/* Written by Deden Fathurahman (dedenf@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['id'] = {
- closeText: 'Tutup',
- prevText: '&#x3C;mundur',
- nextText: 'maju&#x3E;',
- currentText: 'hari ini',
- monthNames: ['Januari','Februari','Maret','April','Mei','Juni',
- 'Juli','Agustus','September','Oktober','Nopember','Desember'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
- 'Jul','Agus','Sep','Okt','Nop','Des'],
- dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'],
- dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'],
- dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'],
- weekHeader: 'Mg',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['id']);
-
-return datepicker.regional['id'];
-
-}));
diff --git a/ui/i18n/datepicker-is.js b/ui/i18n/datepicker-is.js
deleted file mode 100644
index 76fce6374..000000000
--- a/ui/i18n/datepicker-is.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Icelandic initialisation for the jQuery UI date picker plugin. */
-/* Written by Haukur H. Thorsson (haukur@eskill.is). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['is'] = {
- closeText: 'Loka',
- prevText: '&#x3C; Fyrri',
- nextText: 'Næsti &#x3E;',
- currentText: 'Í dag',
- monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní',
- 'Júlí','Ágúst','September','Október','Nóvember','Desember'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún',
- 'Júl','Ágú','Sep','Okt','Nóv','Des'],
- dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'],
- dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'],
- dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'],
- weekHeader: 'Vika',
- dateFormat: 'dd.mm.yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['is']);
-
-return datepicker.regional['is'];
-
-}));
diff --git a/ui/i18n/datepicker-it-CH.js b/ui/i18n/datepicker-it-CH.js
deleted file mode 100644
index 7f4473025..000000000
--- a/ui/i18n/datepicker-it-CH.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Italian initialisation for the jQuery UI date picker plugin. */
-/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['it-CH'] = {
- closeText: 'Chiudi',
- prevText: '&#x3C;Prec',
- nextText: 'Succ&#x3E;',
- currentText: 'Oggi',
- monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
- 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
- monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
- 'Lug','Ago','Set','Ott','Nov','Dic'],
- dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'],
- dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
- dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
- weekHeader: 'Sm',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['it-CH']);
-
-return datepicker.regional['it-CH'];
-
-}));
diff --git a/ui/i18n/datepicker-it.js b/ui/i18n/datepicker-it.js
deleted file mode 100644
index 24dff6ee6..000000000
--- a/ui/i18n/datepicker-it.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Italian initialisation for the jQuery UI date picker plugin. */
-/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['it'] = {
- closeText: 'Chiudi',
- prevText: '&#x3C;Prec',
- nextText: 'Succ&#x3E;',
- currentText: 'Oggi',
- monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
- 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
- monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
- 'Lug','Ago','Set','Ott','Nov','Dic'],
- dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'],
- dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
- dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
- weekHeader: 'Sm',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['it']);
-
-return datepicker.regional['it'];
-
-}));
diff --git a/ui/i18n/datepicker-ja.js b/ui/i18n/datepicker-ja.js
deleted file mode 100644
index 8806d194b..000000000
--- a/ui/i18n/datepicker-ja.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Japanese initialisation for the jQuery UI date picker plugin. */
-/* Written by Kentaro SATO (kentaro@ranvis.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ja'] = {
- closeText: '閉じる',
- prevText: '&#x3C;前',
- nextText: '次&#x3E;',
- currentText: '今日',
- monthNames: ['1月','2月','3月','4月','5月','6月',
- '7月','8月','9月','10月','11月','12月'],
- monthNamesShort: ['1月','2月','3月','4月','5月','6月',
- '7月','8月','9月','10月','11月','12月'],
- dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
- dayNamesShort: ['日','月','火','水','木','金','土'],
- dayNamesMin: ['日','月','火','水','木','金','土'],
- weekHeader: '週',
- dateFormat: 'yy/mm/dd',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: '年'};
-datepicker.setDefaults(datepicker.regional['ja']);
-
-return datepicker.regional['ja'];
-
-}));
diff --git a/ui/i18n/datepicker-ka.js b/ui/i18n/datepicker-ka.js
deleted file mode 100644
index e3dd2f0c4..000000000
--- a/ui/i18n/datepicker-ka.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Lado Lomidze (lado.lomidze@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ka'] = {
- closeText: 'დახურვა',
- prevText: '&#x3c; წინა',
- nextText: 'შემდეგი &#x3e;',
- currentText: 'დღეს',
- monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'],
- monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'],
- dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'],
- dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'],
- dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'],
- weekHeader: 'კვირა',
- dateFormat: 'dd-mm-yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ka']);
-
-return datepicker.regional['ka'];
-
-}));
diff --git a/ui/i18n/datepicker-kk.js b/ui/i18n/datepicker-kk.js
deleted file mode 100644
index a4d2d5c4b..000000000
--- a/ui/i18n/datepicker-kk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['kk'] = {
- closeText: 'Жабу',
- prevText: '&#x3C;Алдыңғы',
- nextText: 'Келесі&#x3E;',
- currentText: 'Бүгін',
- monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым',
- 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'],
- monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау',
- 'Шіл','Там','Қыр','Қаз','Қар','Жел'],
- dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'],
- dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'],
- dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'],
- weekHeader: 'Не',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['kk']);
-
-return datepicker.regional['kk'];
-
-}));
diff --git a/ui/i18n/datepicker-km.js b/ui/i18n/datepicker-km.js
deleted file mode 100644
index 48e35a147..000000000
--- a/ui/i18n/datepicker-km.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Khmer initialisation for the jQuery calendar extension. */
-/* Written by Chandara Om (chandara.teacher@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['km'] = {
- closeText: 'ធ្វើ​រួច',
- prevText: 'មុន',
- nextText: 'បន្ទាប់',
- currentText: 'ថ្ងៃ​នេះ',
- monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា',
- 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'],
- monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា',
- 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'],
- dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'],
- dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'],
- dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'],
- weekHeader: 'សប្ដាហ៍',
- dateFormat: 'dd-mm-yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['km']);
-
-return datepicker.regional['km'];
-
-}));
diff --git a/ui/i18n/datepicker-ko.js b/ui/i18n/datepicker-ko.js
deleted file mode 100644
index 2c9010258..000000000
--- a/ui/i18n/datepicker-ko.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Korean initialisation for the jQuery calendar extension. */
-/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ko'] = {
- closeText: '닫기',
- prevText: '이전달',
- nextText: '다음달',
- currentText: '오늘',
- monthNames: ['1월','2월','3월','4월','5월','6월',
- '7월','8월','9월','10월','11월','12월'],
- monthNamesShort: ['1월','2월','3월','4월','5월','6월',
- '7월','8월','9월','10월','11월','12월'],
- dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'],
- dayNamesShort: ['일','월','화','수','목','금','토'],
- dayNamesMin: ['일','월','화','수','목','금','토'],
- weekHeader: 'Wk',
- dateFormat: 'yy-mm-dd',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: '년'};
-datepicker.setDefaults(datepicker.regional['ko']);
-
-return datepicker.regional['ko'];
-
-}));
diff --git a/ui/i18n/datepicker-ky.js b/ui/i18n/datepicker-ky.js
deleted file mode 100644
index 4fa84be89..000000000
--- a/ui/i18n/datepicker-ky.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Sergey Kartashov (ebishkek@yandex.ru). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ky'] = {
- closeText: 'Жабуу',
- prevText: '&#x3c;Мур',
- nextText: 'Кий&#x3e;',
- currentText: 'Бүгүн',
- monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
- 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
- monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
- 'Июл','Авг','Сен','Окт','Ноя','Дек'],
- dayNames: ['жекшемби', 'дүйшөмбү', 'шейшемби', 'шаршемби', 'бейшемби', 'жума', 'ишемби'],
- dayNamesShort: ['жек', 'дүй', 'шей', 'шар', 'бей', 'жум', 'ише'],
- dayNamesMin: ['Жк','Дш','Шш','Шр','Бш','Жм','Иш'],
- weekHeader: 'Жум',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''
-};
-datepicker.setDefaults(datepicker.regional['ky']);
-
-return datepicker.regional['ky'];
-
-}));
diff --git a/ui/i18n/datepicker-lb.js b/ui/i18n/datepicker-lb.js
deleted file mode 100644
index 024656550..000000000
--- a/ui/i18n/datepicker-lb.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Luxembourgish initialisation for the jQuery UI date picker plugin. */
-/* Written by Michel Weimerskirch <michel@weimerskirch.net> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['lb'] = {
- closeText: 'Fäerdeg',
- prevText: 'Zréck',
- nextText: 'Weider',
- currentText: 'Haut',
- monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni',
- 'Juli','August','September','Oktober','November','Dezember'],
- monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
- dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'],
- dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'],
- dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'],
- weekHeader: 'W',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['lb']);
-
-return datepicker.regional['lb'];
-
-}));
diff --git a/ui/i18n/datepicker-lt.js b/ui/i18n/datepicker-lt.js
deleted file mode 100644
index 2f5a67e1d..000000000
--- a/ui/i18n/datepicker-lt.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas@avalon.lt> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['lt'] = {
- closeText: 'Uždaryti',
- prevText: '&#x3C;Atgal',
- nextText: 'Pirmyn&#x3E;',
- currentText: 'Šiandien',
- monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis',
- 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'],
- monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir',
- 'Lie','Rugp','Rugs','Spa','Lap','Gru'],
- dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'],
- dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'],
- dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'],
- weekHeader: 'SAV',
- dateFormat: 'yy-mm-dd',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['lt']);
-
-return datepicker.regional['lt'];
-
-}));
diff --git a/ui/i18n/datepicker-lv.js b/ui/i18n/datepicker-lv.js
deleted file mode 100644
index 20dda0acb..000000000
--- a/ui/i18n/datepicker-lv.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['lv'] = {
- closeText: 'Aizvērt',
- prevText: 'Iepr.',
- nextText: 'Nāk.',
- currentText: 'Šodien',
- monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs',
- 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn',
- 'Jūl','Aug','Sep','Okt','Nov','Dec'],
- dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'],
- dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'],
- dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'],
- weekHeader: 'Ned.',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['lv']);
-
-return datepicker.regional['lv'];
-
-}));
diff --git a/ui/i18n/datepicker-mk.js b/ui/i18n/datepicker-mk.js
deleted file mode 100644
index b5463d182..000000000
--- a/ui/i18n/datepicker-mk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Macedonian i18n for the jQuery UI date picker plugin. */
-/* Written by Stojce Slavkovski. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['mk'] = {
- closeText: 'Затвори',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Денес',
- monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни',
- 'Јули','Август','Септември','Октомври','Ноември','Декември'],
- monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун',
- 'Јул','Авг','Сеп','Окт','Ное','Дек'],
- dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'],
- dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'],
- dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'],
- weekHeader: 'Сед',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['mk']);
-
-return datepicker.regional['mk'];
-
-}));
diff --git a/ui/i18n/datepicker-ml.js b/ui/i18n/datepicker-ml.js
deleted file mode 100644
index 554cb1667..000000000
--- a/ui/i18n/datepicker-ml.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Saji Nediyanchath (saji89@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ml'] = {
- closeText: 'ശരി',
- prevText: 'മുന്നത്തെ',
- nextText: 'അടുത്തത് ',
- currentText: 'ഇന്ന്',
- monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍',
- 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'],
- monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍',
- 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'],
- dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'],
- dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'],
- dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'],
- weekHeader: 'ആ',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ml']);
-
-return datepicker.regional['ml'];
-
-}));
diff --git a/ui/i18n/datepicker-ms.js b/ui/i18n/datepicker-ms.js
deleted file mode 100644
index 4a13ec4e4..000000000
--- a/ui/i18n/datepicker-ms.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Malaysian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ms'] = {
- closeText: 'Tutup',
- prevText: '&#x3C;Sebelum',
- nextText: 'Selepas&#x3E;',
- currentText: 'hari ini',
- monthNames: ['Januari','Februari','Mac','April','Mei','Jun',
- 'Julai','Ogos','September','Oktober','November','Disember'],
- monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun',
- 'Jul','Ogo','Sep','Okt','Nov','Dis'],
- dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'],
- dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'],
- dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'],
- weekHeader: 'Mg',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ms']);
-
-return datepicker.regional['ms'];
-
-}));
diff --git a/ui/i18n/datepicker-nb.js b/ui/i18n/datepicker-nb.js
deleted file mode 100644
index 2ad0e03b4..000000000
--- a/ui/i18n/datepicker-nb.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */
-/* Written by Bjørn Johansen (post@bjornjohansen.no). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['nb'] = {
- closeText: 'Lukk',
- prevText: '&#xAB;Forrige',
- nextText: 'Neste&#xBB;',
- currentText: 'I dag',
- monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'],
- monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'],
- dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'],
- dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],
- dayNamesMin: ['sø','ma','ti','on','to','fr','lø'],
- weekHeader: 'Uke',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''
-};
-datepicker.setDefaults(datepicker.regional['nb']);
-
-return datepicker.regional['nb'];
-
-}));
diff --git a/ui/i18n/datepicker-nl-BE.js b/ui/i18n/datepicker-nl-BE.js
deleted file mode 100644
index 192aeb7ed..000000000
--- a/ui/i18n/datepicker-nl-BE.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */
-/* David De Sloovere @DavidDeSloovere */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['nl-BE'] = {
- closeText: 'Sluiten',
- prevText: '←',
- nextText: '→',
- currentText: 'Vandaag',
- monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni',
- 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
- monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
- 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
- dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
- dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'],
- dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['nl-BE']);
-
-return datepicker.regional['nl-BE'];
-
-}));
diff --git a/ui/i18n/datepicker-nl.js b/ui/i18n/datepicker-nl.js
deleted file mode 100644
index bfbb1a688..000000000
--- a/ui/i18n/datepicker-nl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Mathias Bynens <http://mathiasbynens.be/> */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional.nl = {
- closeText: 'Sluiten',
- prevText: '←',
- nextText: '→',
- currentText: 'Vandaag',
- monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni',
- 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
- monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
- 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
- dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
- dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'],
- dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
- weekHeader: 'Wk',
- dateFormat: 'dd-mm-yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional.nl);
-
-return datepicker.regional.nl;
-
-}));
diff --git a/ui/i18n/datepicker-nn.js b/ui/i18n/datepicker-nn.js
deleted file mode 100644
index 6d8fdc857..000000000
--- a/ui/i18n/datepicker-nn.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */
-/* Written by Bjørn Johansen (post@bjornjohansen.no). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['nn'] = {
- closeText: 'Lukk',
- prevText: '&#xAB;Førre',
- nextText: 'Neste&#xBB;',
- currentText: 'I dag',
- monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'],
- monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'],
- dayNamesShort: ['sun','mån','tys','ons','tor','fre','lau'],
- dayNames: ['sundag','måndag','tysdag','onsdag','torsdag','fredag','laurdag'],
- dayNamesMin: ['su','må','ty','on','to','fr','la'],
- weekHeader: 'Veke',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''
-};
-datepicker.setDefaults(datepicker.regional['nn']);
-
-return datepicker.regional['nn'];
-
-}));
diff --git a/ui/i18n/datepicker-no.js b/ui/i18n/datepicker-no.js
deleted file mode 100644
index 316e9c333..000000000
--- a/ui/i18n/datepicker-no.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Norwegian initialisation for the jQuery UI date picker plugin. */
-/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */
-
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['no'] = {
- closeText: 'Lukk',
- prevText: '&#xAB;Forrige',
- nextText: 'Neste&#xBB;',
- currentText: 'I dag',
- monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'],
- monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'],
- dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'],
- dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],
- dayNamesMin: ['sø','ma','ti','on','to','fr','lø'],
- weekHeader: 'Uke',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''
-};
-datepicker.setDefaults(datepicker.regional['no']);
-
-return datepicker.regional['no'];
-
-}));
diff --git a/ui/i18n/datepicker-pl.js b/ui/i18n/datepicker-pl.js
deleted file mode 100644
index c9dd9d2b9..000000000
--- a/ui/i18n/datepicker-pl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Polish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['pl'] = {
- closeText: 'Zamknij',
- prevText: '&#x3C;Poprzedni',
- nextText: 'Następny&#x3E;',
- currentText: 'Dziś',
- monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec',
- 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],
- monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze',
- 'Lip','Sie','Wrz','Pa','Lis','Gru'],
- dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'],
- dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'],
- dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'],
- weekHeader: 'Tydz',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['pl']);
-
-return datepicker.regional['pl'];
-
-}));
diff --git a/ui/i18n/datepicker-pt-BR.js b/ui/i18n/datepicker-pt-BR.js
deleted file mode 100644
index 90cf0abc1..000000000
--- a/ui/i18n/datepicker-pt-BR.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Brazilian initialisation for the jQuery UI date picker plugin. */
-/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['pt-BR'] = {
- closeText: 'Fechar',
- prevText: '&#x3C;Anterior',
- nextText: 'Próximo&#x3E;',
- currentText: 'Hoje',
- monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho',
- 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
- monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
- 'Jul','Ago','Set','Out','Nov','Dez'],
- dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'],
- dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
- dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
- weekHeader: 'Sm',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['pt-BR']);
-
-return datepicker.regional['pt-BR'];
-
-}));
diff --git a/ui/i18n/datepicker-pt.js b/ui/i18n/datepicker-pt.js
deleted file mode 100644
index cce2d7efe..000000000
--- a/ui/i18n/datepicker-pt.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Portuguese initialisation for the jQuery UI date picker plugin. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['pt'] = {
- closeText: 'Fechar',
- prevText: 'Anterior',
- nextText: 'Seguinte',
- currentText: 'Hoje',
- monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho',
- 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
- monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
- 'Jul','Ago','Set','Out','Nov','Dez'],
- dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'],
- dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
- dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
- weekHeader: 'Sem',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['pt']);
-
-return datepicker.regional['pt'];
-
-}));
diff --git a/ui/i18n/datepicker-rm.js b/ui/i18n/datepicker-rm.js
deleted file mode 100644
index 2c12e9e93..000000000
--- a/ui/i18n/datepicker-rm.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Romansh initialisation for the jQuery UI date picker plugin. */
-/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['rm'] = {
- closeText: 'Serrar',
- prevText: '&#x3C;Suandant',
- nextText: 'Precedent&#x3E;',
- currentText: 'Actual',
- monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'],
- monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'],
- dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'],
- dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'],
- dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'],
- weekHeader: 'emna',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['rm']);
-
-return datepicker.regional['rm'];
-
-}));
diff --git a/ui/i18n/datepicker-ro.js b/ui/i18n/datepicker-ro.js
deleted file mode 100644
index ef658472f..000000000
--- a/ui/i18n/datepicker-ro.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Romanian initialisation for the jQuery UI date picker plugin.
- *
- * Written by Edmond L. (ll_edmond@walla.com)
- * and Ionut G. Stan (ionut.g.stan@gmail.com)
- */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ro'] = {
- closeText: 'Închide',
- prevText: '&#xAB; Luna precedentă',
- nextText: 'Luna următoare &#xBB;',
- currentText: 'Azi',
- monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie',
- 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'],
- monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun',
- 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'],
- dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
- dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'],
- weekHeader: 'Săpt',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ro']);
-
-return datepicker.regional['ro'];
-
-}));
diff --git a/ui/i18n/datepicker-ru.js b/ui/i18n/datepicker-ru.js
deleted file mode 100644
index e2b16623a..000000000
--- a/ui/i18n/datepicker-ru.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Andrew Stromnov (stromnov@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ru'] = {
- closeText: 'Закрыть',
- prevText: '&#x3C;Пред',
- nextText: 'След&#x3E;',
- currentText: 'Сегодня',
- monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
- 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
- monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
- 'Июл','Авг','Сен','Окт','Ноя','Дек'],
- dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
- dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
- dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
- weekHeader: 'Нед',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ru']);
-
-return datepicker.regional['ru'];
-
-}));
diff --git a/ui/i18n/datepicker-sk.js b/ui/i18n/datepicker-sk.js
deleted file mode 100644
index 73b490718..000000000
--- a/ui/i18n/datepicker-sk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Slovak initialisation for the jQuery UI date picker plugin. */
-/* Written by Vojtech Rinik (vojto@hmm.sk). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sk'] = {
- closeText: 'Zavrieť',
- prevText: '&#x3C;Predchádzajúci',
- nextText: 'Nasledujúci&#x3E;',
- currentText: 'Dnes',
- monthNames: ['január','február','marec','apríl','máj','jún',
- 'júl','august','september','október','november','december'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún',
- 'Júl','Aug','Sep','Okt','Nov','Dec'],
- dayNames: ['nedeľa','pondelok','utorok','streda','štvrtok','piatok','sobota'],
- dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'],
- dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'],
- weekHeader: 'Ty',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sk']);
-
-return datepicker.regional['sk'];
-
-}));
diff --git a/ui/i18n/datepicker-sl.js b/ui/i18n/datepicker-sl.js
deleted file mode 100644
index 083b2ae40..000000000
--- a/ui/i18n/datepicker-sl.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Slovenian initialisation for the jQuery UI date picker plugin. */
-/* Written by Jaka Jancar (jaka@kubje.org). */
-/* c = č, s = š z = ž C = Č S = Š Z = Ž */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sl'] = {
- closeText: 'Zapri',
- prevText: '&#x3C;Prejšnji',
- nextText: 'Naslednji&#x3E;',
- currentText: 'Trenutni',
- monthNames: ['Januar','Februar','Marec','April','Maj','Junij',
- 'Julij','Avgust','September','Oktober','November','December'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Avg','Sep','Okt','Nov','Dec'],
- dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'],
- dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'],
- dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'],
- weekHeader: 'Teden',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sl']);
-
-return datepicker.regional['sl'];
-
-}));
diff --git a/ui/i18n/datepicker-sq.js b/ui/i18n/datepicker-sq.js
deleted file mode 100644
index d0d8f5703..000000000
--- a/ui/i18n/datepicker-sq.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Albanian initialisation for the jQuery UI date picker plugin. */
-/* Written by Flakron Bytyqi (flakron@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sq'] = {
- closeText: 'mbylle',
- prevText: '&#x3C;mbrapa',
- nextText: 'Përpara&#x3E;',
- currentText: 'sot',
- monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor',
- 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'],
- monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer',
- 'Kor','Gus','Sht','Tet','Nën','Dhj'],
- dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'],
- dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'],
- dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'],
- weekHeader: 'Ja',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sq']);
-
-return datepicker.regional['sq'];
-
-}));
diff --git a/ui/i18n/datepicker-sr-SR.js b/ui/i18n/datepicker-sr-SR.js
deleted file mode 100644
index 0c2d2af49..000000000
--- a/ui/i18n/datepicker-sr-SR.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sr-SR'] = {
- closeText: 'Zatvori',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Danas',
- monthNames: ['Januar','Februar','Mart','April','Maj','Jun',
- 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Avg','Sep','Okt','Nov','Dec'],
- dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'],
- dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'],
- dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
- weekHeader: 'Sed',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sr-SR']);
-
-return datepicker.regional['sr-SR'];
-
-}));
diff --git a/ui/i18n/datepicker-sr.js b/ui/i18n/datepicker-sr.js
deleted file mode 100644
index 2d28e17c0..000000000
--- a/ui/i18n/datepicker-sr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sr'] = {
- closeText: 'Затвори',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Данас',
- monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун',
- 'Јул','Август','Септембар','Октобар','Новембар','Децембар'],
- monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун',
- 'Јул','Авг','Сеп','Окт','Нов','Дец'],
- dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'],
- dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'],
- dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'],
- weekHeader: 'Сед',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sr']);
-
-return datepicker.regional['sr'];
-
-}));
diff --git a/ui/i18n/datepicker-sv.js b/ui/i18n/datepicker-sv.js
deleted file mode 100644
index 87e02cc00..000000000
--- a/ui/i18n/datepicker-sv.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Swedish initialisation for the jQuery UI date picker plugin. */
-/* Written by Anders Ekdahl ( anders@nomadiz.se). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['sv'] = {
- closeText: 'Stäng',
- prevText: '&#xAB;Förra',
- nextText: 'Nästa&#xBB;',
- currentText: 'Idag',
- monthNames: ['Januari','Februari','Mars','April','Maj','Juni',
- 'Juli','Augusti','September','Oktober','November','December'],
- monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
- 'Jul','Aug','Sep','Okt','Nov','Dec'],
- dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'],
- dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'],
- dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'],
- weekHeader: 'Ve',
- dateFormat: 'yy-mm-dd',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['sv']);
-
-return datepicker.regional['sv'];
-
-}));
diff --git a/ui/i18n/datepicker-ta.js b/ui/i18n/datepicker-ta.js
deleted file mode 100644
index e3b66fe37..000000000
--- a/ui/i18n/datepicker-ta.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by S A Sureshkumar (saskumar@live.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['ta'] = {
- closeText: 'மூடு',
- prevText: 'முன்னையது',
- nextText: 'அடுத்தது',
- currentText: 'இன்று',
- monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி',
- 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'],
- monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி',
- 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'],
- dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'],
- dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'],
- dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'],
- weekHeader: 'Не',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['ta']);
-
-return datepicker.regional['ta'];
-
-}));
diff --git a/ui/i18n/datepicker-th.js b/ui/i18n/datepicker-th.js
deleted file mode 100644
index 2a174f670..000000000
--- a/ui/i18n/datepicker-th.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Thai initialisation for the jQuery UI date picker plugin. */
-/* Written by pipo (pipo@sixhead.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['th'] = {
- closeText: 'ปิด',
- prevText: '&#xAB;&#xA0;ย้อน',
- nextText: 'ถัดไป&#xA0;&#xBB;',
- currentText: 'วันนี้',
- monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน',
- 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'],
- monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.',
- 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'],
- dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'],
- dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
- dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
- weekHeader: 'Wk',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['th']);
-
-return datepicker.regional['th'];
-
-}));
diff --git a/ui/i18n/datepicker-tj.js b/ui/i18n/datepicker-tj.js
deleted file mode 100644
index 7bfcc7595..000000000
--- a/ui/i18n/datepicker-tj.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Abdurahmon Saidov (saidovab@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['tj'] = {
- closeText: 'Идома',
- prevText: '&#x3c;Қафо',
- nextText: 'Пеш&#x3e;',
- currentText: 'Имрӯз',
- monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн',
- 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'],
- monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
- 'Июл','Авг','Сен','Окт','Ноя','Дек'],
- dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'],
- dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'],
- dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'],
- weekHeader: 'Хф',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['tj']);
-
-return datepicker.regional['tj'];
-
-}));
diff --git a/ui/i18n/datepicker-tr.js b/ui/i18n/datepicker-tr.js
deleted file mode 100644
index 98370d38c..000000000
--- a/ui/i18n/datepicker-tr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Turkish initialisation for the jQuery UI date picker plugin. */
-/* Written by Izzet Emre Erkan (kara@karalamalar.net). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['tr'] = {
- closeText: 'kapat',
- prevText: '&#x3C;geri',
- nextText: 'ileri&#x3e',
- currentText: 'bugün',
- monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran',
- 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'],
- monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz',
- 'Tem','Ağu','Eyl','Eki','Kas','Ara'],
- dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],
- dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
- dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
- weekHeader: 'Hf',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['tr']);
-
-return datepicker.regional['tr'];
-
-}));
diff --git a/ui/i18n/datepicker-uk.js b/ui/i18n/datepicker-uk.js
deleted file mode 100644
index 0dddc3eb8..000000000
--- a/ui/i18n/datepicker-uk.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */
-/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['uk'] = {
- closeText: 'Закрити',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Сьогодні',
- monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень',
- 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'],
- monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер',
- 'Лип','Сер','Вер','Жов','Лис','Гру'],
- dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'],
- dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'],
- dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],
- weekHeader: 'Тиж',
- dateFormat: 'dd.mm.yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['uk']);
-
-return datepicker.regional['uk'];
-
-}));
diff --git a/ui/i18n/datepicker-vi.js b/ui/i18n/datepicker-vi.js
deleted file mode 100644
index de9e8c02c..000000000
--- a/ui/i18n/datepicker-vi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Vietnamese initialisation for the jQuery UI date picker plugin. */
-/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['vi'] = {
- closeText: 'Đóng',
- prevText: '&#x3C;Trước',
- nextText: 'Tiếp&#x3E;',
- currentText: 'Hôm nay',
- monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu',
- 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'],
- monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
- 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
- dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'],
- dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
- dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
- weekHeader: 'Tu',
- dateFormat: 'dd/mm/yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-datepicker.setDefaults(datepicker.regional['vi']);
-
-return datepicker.regional['vi'];
-
-}));
diff --git a/ui/i18n/datepicker-zh-CN.js b/ui/i18n/datepicker-zh-CN.js
deleted file mode 100644
index 977e6628c..000000000
--- a/ui/i18n/datepicker-zh-CN.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Cloudream (cloudream@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['zh-CN'] = {
- closeText: '关闭',
- prevText: '&#x3C;上月',
- nextText: '下月&#x3E;',
- currentText: '今天',
- monthNames: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- monthNamesShort: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
- dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
- dayNamesMin: ['日','一','二','三','四','五','六'],
- weekHeader: '周',
- dateFormat: 'yy-mm-dd',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: '年'};
-datepicker.setDefaults(datepicker.regional['zh-CN']);
-
-return datepicker.regional['zh-CN'];
-
-}));
diff --git a/ui/i18n/datepicker-zh-HK.js b/ui/i18n/datepicker-zh-HK.js
deleted file mode 100644
index 4feb5a79d..000000000
--- a/ui/i18n/datepicker-zh-HK.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by SCCY (samuelcychan@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['zh-HK'] = {
- closeText: '關閉',
- prevText: '&#x3C;上月',
- nextText: '下月&#x3E;',
- currentText: '今天',
- monthNames: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- monthNamesShort: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
- dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
- dayNamesMin: ['日','一','二','三','四','五','六'],
- weekHeader: '周',
- dateFormat: 'dd-mm-yy',
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: '年'};
-datepicker.setDefaults(datepicker.regional['zh-HK']);
-
-return datepicker.regional['zh-HK'];
-
-}));
diff --git a/ui/i18n/datepicker-zh-TW.js b/ui/i18n/datepicker-zh-TW.js
deleted file mode 100644
index 120c46143..000000000
--- a/ui/i18n/datepicker-zh-TW.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Ressol (ressol@gmail.com). */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}(function( datepicker ) {
-
-datepicker.regional['zh-TW'] = {
- closeText: '關閉',
- prevText: '&#x3C;上月',
- nextText: '下月&#x3E;',
- currentText: '今天',
- monthNames: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- monthNamesShort: ['一月','二月','三月','四月','五月','六月',
- '七月','八月','九月','十月','十一月','十二月'],
- dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
- dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
- dayNamesMin: ['日','一','二','三','四','五','六'],
- weekHeader: '周',
- dateFormat: 'yy/mm/dd',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: '年'};
-datepicker.setDefaults(datepicker.regional['zh-TW']);
-
-return datepicker.regional['zh-TW'];
-
-}));
diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js
new file mode 100644
index 000000000..947d79d8d
--- /dev/null
+++ b/ui/widgets/calendar.js
@@ -0,0 +1,657 @@
+/*!
+ * jQuery UI Calendar @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Datepicker
+//>>group: Widgets
+//>>description: Displays a calendar for inline date selection.
+//>>docs: http://api.jqueryui.com/calendar/
+//>>demos: http://jqueryui.com/calendar/
+
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ // TODO: Keep button even if its optional?
+ define( [
+ "jquery",
+ "globalize",
+ "globalize/date",
+ "globalize-locales",
+ "date",
+ "./button",
+ "../widget",
+ "../version",
+ "../keycode",
+ "../unique-id",
+ "../tabbable"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery, Globalize );
+ }
+}( function( $, Globalize ) {
+
+return $.widget( "ui.calendar", {
+ version: "@VERSION",
+ options: {
+ buttons: [],
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ showWeek: false,
+ value: null,
+
+ // callbacks
+ select: null
+ },
+
+ refreshRelatedOptions: {
+ dateFormat: true,
+ eachDay: true,
+ locale: true,
+ max: true,
+ min: true,
+ showWeek: true,
+ value: true
+ },
+
+ _create: function() {
+ this.id = this.element.uniqueId().attr( "id" );
+ this.labels = this.options.labels;
+ this.buttonClickContext = this.element[ 0 ];
+
+ this._setLocale( this.options.locale, this.options.dateFormat );
+
+ this.date = new $.ui.calendarDate( this.options.value, this._calendarDateOptions );
+ this.viewDate = this.date.clone();
+ this.viewDate.eachDay = this.options.eachDay;
+
+ this._on( this.element, {
+ "click .ui-calendar-prev": function( event ) {
+ event.preventDefault();
+ this.date.adjust( "M", -this.options.numberOfMonths );
+ this._refresh();
+ },
+ "click .ui-calendar-next": function( event ) {
+ event.preventDefault();
+ this.date.adjust( "M", this.options.numberOfMonths );
+ this._refresh();
+ },
+ "mousedown .ui-calendar-calendar button": function( event ) {
+ event.preventDefault();
+
+ this._setOption( "value", new Date( $( event.currentTarget ).data( "timestamp" ) ) );
+ this.refresh();
+ this._trigger( "select", event );
+ this.grid.focus();
+ },
+ "mouseenter .ui-calendar-header button": "_hover",
+ "mouseleave .ui-calendar-header button": "_hover",
+ "mouseenter .ui-calendar-calendar button": "_hover",
+ "mouseleave .ui-calendar-calendar button": "_hover",
+ "keydown .ui-calendar-calendar": "_handleKeydown"
+ } );
+
+ this._createCalendar();
+ },
+
+ _hover: function( event ) {
+ $( event.currentTarget ).toggleClass( "ui-state-hover" );
+ },
+
+ _handleKeydown: function( event ) {
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.ENTER:
+ this.activeDescendant.mousedown();
+ return;
+ case $.ui.keyCode.PAGE_UP:
+ this.date.adjust( event.altKey ? "Y" : "M", -1 );
+ break;
+ case $.ui.keyCode.PAGE_DOWN:
+ this.date.adjust( event.altKey ? "Y" : "M", 1 );
+ break;
+ case $.ui.keyCode.END:
+ this.date.setDay( this.date.daysInMonth() );
+ break;
+ case $.ui.keyCode.HOME:
+ this.date.setDay( 1 );
+ break;
+ case $.ui.keyCode.LEFT:
+ this.date.adjust( "D", -1 );
+ break;
+ case $.ui.keyCode.UP:
+ this.date.adjust( "D", -7 );
+ break;
+ case $.ui.keyCode.RIGHT:
+ this.date.adjust( "D", 1 );
+ break;
+ case $.ui.keyCode.DOWN:
+ this.date.adjust( "D", 7 );
+ break;
+ default:
+ event.preventDefault();
+ return;
+ }
+
+ if ( this._needsRefresh() ) {
+ this._refresh();
+ this.grid.focus();
+ }
+
+ this._setActiveDescendant();
+ },
+
+ _needsRefresh: function() {
+ if ( this.date.month() !== this.viewDate.month() || this.date.year() !== this.viewDate.year() ) {
+
+ // Check if the needed day is already present in our grid due
+ // to eachDay option changes (eg. other-months demo)
+ return !this.grid.find(
+ this._sanitizeSelector( "#" + this._getDayId( this.date ) )
+ ).length;
+ }
+
+ return false;
+ },
+
+ _setActiveDescendant: function() {
+ var id = this._getDayId( this.date );
+
+ this.grid
+ .attr( "aria-activedescendant", id )
+ .find( ".ui-state-focus" )
+ .removeClass( "ui-state-focus" );
+
+ this.activeDescendant = this.grid.find(
+ this._sanitizeSelector( "#" + id ) + " > button"
+ ).addClass( "ui-state-focus" );
+ },
+
+ _setLocale: function( locale, dateFormat ) {
+ var globalize = new Globalize( locale ),
+ weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }),
+ weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" });
+
+ this._format = globalize.dateFormatter( dateFormat );
+ this._parse = globalize.dateParser( dateFormat );
+ this._calendarDateOptions = {
+ firstDay: globalize.cldr.supplemental.weekData.firstDay(),
+ formatWeekdayShort: function( date ) {
+
+ // Return the short weekday if its length is < 3. Otherwise, its narrow form.
+ var shortWeekday = weekdayShortFormatter( date );
+
+ return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday;
+ },
+ formatWeekdayFull: globalize.dateFormatter({ raw: "EEEE" }),
+ formatMonth: globalize.dateFormatter({ raw: "MMMM" }),
+ formatWeekOfYear: globalize.dateFormatter({ raw: "w" }),
+ parse: this._parse
+ };
+ },
+
+ _createCalendar: function() {
+ var classes = "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all",
+ pickerHtml = "";
+
+ if ( this.options.numberOfMonths === 1 ) {
+ pickerHtml = this._buildHeader() + this._buildGrid();
+ } else {
+ pickerHtml = this._buildMultiplePicker();
+ classes += " ui-calendar-multi";
+ }
+
+ this.element
+ .addClass( classes )
+ .attr( {
+ role: "region",
+ "aria-labelledby": this.id + "-title"
+ } )
+ .html( pickerHtml );
+
+ this._createButtonPane();
+
+ this.grid = this.element.find( ".ui-calendar-calendar" );
+ },
+
+ _buildMultiplePicker: function() {
+ var headerClass,
+ html = "",
+ currentDate = this.viewDate,
+ months = this.viewDate.months( this.options.numberOfMonths - 1 ),
+ i = 0;
+
+ for ( ; i < months.length; i++ ) {
+
+ // TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
+ this.viewDate = months[ i ];
+ headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix";
+ if ( months[ i ].first ) {
+ headerClass += " ui-corner-left";
+ } else if ( months[ i ].last ) {
+ headerClass += " ui-corner-right";
+ }
+
+ html += "<div class='ui-calendar-group'>" +
+ "<div class='" + headerClass + "'>";
+ if ( months[ i ].first ) {
+ html += this._buildPreviousLink();
+ } else if ( months[ i ].last ) {
+ html += this._buildNextLink();
+ }
+
+ html += this._buildTitlebar() + "</div>" + this._buildGrid() + "</div>";
+ }
+
+ html += "<div class='ui-calendar-row-break'></div>";
+
+ this.viewDate = currentDate;
+
+ return html;
+ },
+
+ _buildHeader: function() {
+ return "<div class='ui-calendar-header ui-widget-header ui-helper-clearfix ui-corner-all'>" +
+ this._buildPreviousLink() +
+ this._buildNextLink() +
+ this._buildTitlebar() +
+ "</div>";
+ },
+
+ _buildPreviousLink: function() {
+ var prevText = this._getTranslation( "prevText" );
+
+ return "<button class='ui-calendar-prev ui-corner-all' title='" +
+ prevText + "'>" +
+ "<span class='ui-icon ui-icon-circle-triangle-w'>" +
+ prevText +
+ "</span>" +
+ "</button>";
+ },
+
+ _buildNextLink: function() {
+ var nextText = this._getTranslation( "nextText" );
+
+ return "<button class='ui-calendar-next ui-corner-all' title='" +
+ nextText + "'>" +
+ "<span class='ui-icon ui-icon-circle-triangle-e'>" +
+ nextText +
+ "</span>" +
+ "</button>";
+ },
+
+ _buildTitlebar: function() {
+ return "<div role='header' id='" + this.id + "-title'>" +
+ "<div id='" + this.id + "-month-label' class='ui-calendar-title'>" +
+ this._buildTitle() +
+ "</div>" +
+ "<span class='ui-helper-hidden-accessible'>, " +
+ this._getTranslation( "datePickerRole" ) +
+ "</span>" +
+ "</div>";
+ },
+
+ _buildTitle: function() {
+ return "<span class='ui-calendar-month'>" +
+ this.viewDate.monthName() +
+ "</span> " +
+ "<span class='ui-calendar-year'>" +
+ this.viewDate.year() +
+ "</span>";
+ },
+
+ _buildGrid: function() {
+ return "<table class='ui-calendar-calendar' role='grid' aria-readonly='true' " +
+ "aria-labelledby='" + this.id + "-month-label' tabindex='0' " +
+ "aria-activedescendant='" + this._getDayId( this.date ) + "'>" +
+ this._buildGridHeading() +
+ this._buildGridBody() +
+ "</table>";
+ },
+
+ _buildGridHeading: function() {
+ var cells = "",
+ i = 0,
+ weekDayLength = this.viewDate.weekdays().length,
+ weekdays = this.date.weekdays();
+
+ if ( this.options.showWeek ) {
+ cells += "<th class='ui-calendar-week-col'>" + this._getTranslation( "weekHeader" ) + "</th>";
+ }
+ for ( ; i < weekDayLength; i++ ) {
+ cells += this._buildGridHeaderCell( weekdays[ i ] );
+ }
+
+ return "<thead role='presentation'>" +
+ "<tr role='row'>" + cells + "</tr>" +
+ "</thead>";
+ },
+
+ _buildGridHeaderCell: function( day ) {
+ return "<th role='columnheader' abbr='" + day.fullname + "' aria-label='" + day.fullname + "'>" +
+ "<span title='" + day.fullname + "'>" +
+ day.shortname +
+ "</span>" +
+ "</th>";
+ },
+
+ _buildGridBody: function() {
+ var days = this.viewDate.days(),
+ i = 0,
+ rows = "";
+
+ for ( ; i < days.length; i++ ) {
+ rows += this._buildWeekRow( days[ i ] );
+ }
+
+ return "<tbody role='presentation'>" + rows + "</tbody>";
+ },
+
+ _buildWeekRow: function( week ) {
+ var cells = "",
+ i = 0;
+
+ if ( this.options.showWeek ) {
+ cells += "<td class='ui-calendar-week-col'>" + week.number + "</td>";
+ }
+ for ( ; i < week.days.length; i++ ) {
+ cells += this._buildDayCell( week.days[ i ] );
+ }
+
+ return "<tr role='row'>" + cells + "</tr>";
+ },
+
+ _buildDayCell: function( day ) {
+ var content = "",
+ attributes = [
+ "role='gridcell'",
+ "aria-selected='" + ( this._isCurrent( day ) ? true : false ) + "'"
+ ],
+ selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) );
+
+ if ( day.render ) {
+ attributes.push( "id='" + this.id + "-" + day.year + "-" + day.month + "-" + day.date + "'" );
+
+ if ( !selectable ) {
+ attributes.push( "aria-disabled='true'" );
+ attributes.push( "class='ui-state-disabled'" );
+ }
+
+ content = this._buildDayElement( day, selectable );
+ }
+
+ return "<td " + attributes.join( " " ) + ">" + content + "</td>";
+ },
+
+ _getDayId: function( date ) {
+ return this.id + "-" + date.year() + "-" + date.month() + "-" + date.day();
+ },
+
+ _buildDayElement: function( day, selectable ) {
+ var attributes, content,
+ classes = [ "ui-state-default" ];
+
+ if ( day === this.date && selectable ) {
+ classes.push( "ui-state-focus" );
+ }
+ if ( this._isCurrent( day ) ) {
+ classes.push( "ui-state-active" );
+ }
+ if ( day.today ) {
+ classes.push( "ui-state-highlight" );
+ }
+ if ( day.extraClasses ) {
+ classes.push( day.extraClasses.split( " " ) );
+ }
+
+ attributes = " class='" + classes.join( " " ) + "'";
+ if ( selectable ) {
+ attributes += " tabindex='-1' data-timestamp='" + day.timestamp + "'";
+ } else {
+ attributes += " disabled='disabled'";
+ }
+ content = "<button" + attributes + ">" + day.date + "</button>";
+
+ if ( day.today ) {
+ content += "<span class='ui-helper-hidden-accessible'>, " + this._getTranslation( "currentText" ) + "</span>";
+ }
+
+ return content;
+ },
+
+ _isCurrent: function( day ) {
+ return this.options.value && day.timestamp === this.options.value.getTime();
+ },
+
+ _createButtonPane: function() {
+ this.buttonPane = $( "<div>" )
+ .addClass( "ui-calendar-buttonpane ui-widget-content ui-helper-clearfix" );
+
+ this.buttonSet = $( "<div>" )
+ .addClass( "ui-calendar-buttonset" )
+ .appendTo( this.buttonPane );
+
+ this._createButtons();
+ },
+
+ _createButtons: function() {
+ var that = this,
+ buttons = this.options.buttons;
+
+ this.buttonPane.remove();
+ this.buttonSet.empty();
+
+ if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
+ this.element.removeClass( "ui-calendar-buttons" );
+ return;
+ }
+
+ $.each( buttons, function( name, props ) {
+ var click, buttonOptions;
+ props = $.isFunction( props ) ?
+ { click: props, text: name } :
+ props;
+
+ // Default to a non-submitting button
+ props = $.extend( { type: "button" }, props );
+
+ // Change the context for the click callback to be the main element
+ click = props.click;
+ props.click = function() {
+ click.apply( that.buttonClickContext, arguments );
+ };
+ buttonOptions = {
+ icons: props.icons,
+ text: props.showText
+ };
+ delete props.icons;
+ delete props.showText;
+ $( "<button></button>", props )
+ .button( buttonOptions )
+ .appendTo( that.buttonSet );
+ } );
+ this.element.addClass( "ui-calendar-buttons" );
+ this.buttonPane.appendTo( this.element );
+ },
+
+ _refresh: function() {
+ this.viewDate.setTime( this.date.date().getTime() );
+ this.refresh();
+ },
+
+ // Refreshing the entire calendar during interaction confuses screen readers, specifically
+ // because the grid heading is marked up as a live region and will often not update if it's
+ // destroyed and recreated instead of just having its text change. Additionally, interacting
+ // with the prev and next links would cause loss of focus issues because the links being
+ // interacted with will disappear while focused.
+ refresh: function() {
+ this.labels = this.options.labels;
+
+ // Determine which day gridcell to focus after refresh
+ // TODO: Prevent disabled cells from being focused
+ if ( this.options.numberOfMonths === 1 ) {
+ this.grid = $( this._buildGrid() );
+ this.element.find( ".ui-calendar-title" ).html( this._buildTitle() );
+ this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid );
+ $( ".ui-calendar-prev", this.element ).attr( "title", this.labels.prevText )
+ .children().html( this.labels.prevText );
+ $( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText )
+ .children().html( this.labels.nextText );
+ this._createButtons();
+ } else {
+ this._refreshMultiplePicker();
+ }
+ },
+
+ _refreshMultiplePicker: function() {
+ var i = 0;
+
+ for ( ; i < this.options.numberOfMonths; i++ ) {
+ this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() );
+ this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() );
+ this.viewDate.adjust( "M", 1 );
+ }
+ this.viewDate.adjust( "M", -this.options.numberOfMonths );
+
+ // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
+ // to maintain the currently focused grid and base queries like this off of it.
+ this.element.find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" );
+ },
+
+ _getTranslation: function( key ) {
+ return $( "<a>" ).text( this.labels[ key ] ).html();
+ },
+
+ _sanitizeSelector: function( hash ) {
+ return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+ },
+
+ _setHiddenPicker: function() {
+ this.element.attr( {
+ "aria-hidden": "true",
+ "aria-expanded": "false"
+ } );
+ },
+
+ value: function( value ) {
+ if ( arguments.length ) {
+ this.valueAsDate( this._parse( value ) );
+ } else {
+ return this._format( this.option( "value" ) );
+ }
+ },
+
+ valueAsDate: function( value ) {
+ if ( arguments.length ) {
+ this.option( "value", value );
+ } else {
+ return this.options.value;
+ }
+ },
+
+ _isValid: function( value ) {
+ if ( $.type( value ) !== "date" ) {
+ return false;
+ }
+
+ if ( $.type( this.options.max ) === "date" ) {
+ if ( value > this.options.max ) {
+ return false;
+ }
+ }
+
+ if ( $.type( this.options.min ) === "date" ) {
+ if ( value < this.options.min ) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ _destroy: function() {
+ this.element
+ .off( ".calendar" )
+ .removeClass( "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-calendar-multi" )
+ .removeAttr( "role aria-labelledby" )
+ .removeUniqueId()
+ .empty();
+ },
+
+ _setOptions: function( options ) {
+ var that = this,
+ refresh = false,
+ dateAttributes = false;
+
+ $.each( options, function( key, value ) {
+ that._setOption( key, value );
+
+ if ( key in that.refreshRelatedOptions ) {
+ refresh = true;
+ }
+ if ( key === "dateFormat" || key === "locale" ) {
+ dateAttributes = true;
+ }
+ } );
+
+ if ( dateAttributes ) {
+ this._setLocale( this.options.locale, this.options.dateFormat );
+ this.date.setAttributes( this._calendarDateOptions );
+ this.viewDate.setAttributes( this._calendarDateOptions );
+ }
+ if ( refresh ) {
+ this._refresh();
+ }
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "value" ) {
+ if ( this._isValid( value ) ) {
+ this.date.setTime( value.getTime() );
+ this._super( key, value );
+ }
+ return;
+ }
+
+ if ( key === "max" || key === "min" ) {
+ if ( $.type( value ) === "date" || value === null ) {
+ this._super( key, value );
+ }
+ return;
+ }
+
+ this._super( key, value );
+
+ if ( key === "buttons" ) {
+ this._createButtons();
+ }
+
+ if ( key === "disabled" ) {
+ this.element
+ .toggleClass( "ui-state-disabled", value )
+ .attr( "aria-disabled", value );
+ }
+
+ if ( key === "eachDay" ) {
+ this.viewDate.eachDay = value;
+ }
+ }
+} );
+
+} ) );
diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js
index 85b658319..5e0e47eb5 100644
--- a/ui/widgets/datepicker.js
+++ b/ui/widgets/datepicker.js
@@ -9,12 +9,9 @@
//>>label: Datepicker
//>>group: Widgets
-//>>description: Displays a calendar from an input or inline for selecting dates.
+//>>description: Displays a calendar for input-based date selection.
//>>docs: http://api.jqueryui.com/datepicker/
//>>demos: http://jqueryui.com/datepicker/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/datepicker.css
-//>>css.theme: ../themes/base/theme.css
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -22,2072 +19,344 @@
// AMD. Register as an anonymous module.
define([
"jquery",
+ "globalize",
+ "globalize/date",
+ "./calendar",
+ "../widget",
+ "../position",
"../version",
"../keycode"
], factory );
} else {
// Browser globals
- factory( jQuery );
+ factory( jQuery, Globalize );
}
-}(function( $ ) {
+}(function( $, Globalize ) {
-$.extend($.ui, { datepicker: { version: "@VERSION" } });
+var widget = $.widget( "ui.datepicker", {
+ version: "@VERSION",
+ options: {
+ appendTo: null,
+ position: {
+ my: "left top",
+ at: "left bottom"
+ },
+ show: true,
+ hide: true,
-var datepicker_instActive;
-
-function datepicker_getZindex( elem ) {
- var position, value;
- while ( elem.length && elem[ 0 ] !== document ) {
- // Ignore z-index if position is set to a value where z-index is ignored by the browser
- // This makes behavior of this function consistent across browsers
- // WebKit always returns auto if the element is positioned
- position = elem.css( "position" );
- if ( position === "absolute" || position === "relative" || position === "fixed" ) {
- // IE returns 0 when zIndex is not specified
- // other browsers return a string
- // we ignore the case of nested elements with an explicit value of 0
- // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
- value = parseInt( elem.css( "zIndex" ), 10 );
- if ( !isNaN( value ) && value !== 0 ) {
- return value;
- }
- }
- elem = elem.parent();
- }
-
- return 0;
-}
-/* Date picker manager.
- Use the singleton instance of this class, $.datepicker, to interact with the date picker.
- Settings for (groups of) date pickers are maintained in an instance object,
- allowing multiple different settings on the same page. */
-
-function Datepicker() {
- this._curInst = null; // The current instance in use
- this._keyEvent = false; // If the last event was a key event
- this._disabledInputs = []; // List of date picker inputs that have been disabled
- this._datepickerShowing = false; // True if the popup picker is showing , false if not
- this._inDialog = false; // True if showing within a "dialog", false if not
- this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
- this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
- this._appendClass = "ui-datepicker-append"; // The name of the append marker class
- this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
- this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
- this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
- this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
- this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
- this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
- this.regional = []; // Available regional settings, indexed by language code
- this.regional[""] = { // Default regional settings
- closeText: "Done", // Display text for close link
- prevText: "Prev", // Display text for previous month link
- nextText: "Next", // Display text for next month link
- currentText: "Today", // Display text for current month link
- monthNames: ["January","February","March","April","May","June",
- "July","August","September","October","November","December"], // Names of months for drop-down and formatting
- monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
- dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
- dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
- dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
- weekHeader: "Wk", // Column header for week of the year
- dateFormat: "mm/dd/yy", // See format options on parseDate
- firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
- isRTL: false, // True if right-to-left language, false if left-to-right
- showMonthAfterYear: false, // True if the year select precedes month, false for month then year
- yearSuffix: "" // Additional text to append to the year in the month headers
- };
- this._defaults = { // Global defaults for all the date picker instances
- showOn: "focus", // "focus" for popup on focus,
- // "button" for trigger button, or "both" for either
- showAnim: "fadeIn", // Name of jQuery animation for popup
- showOptions: {}, // Options for enhanced animations
- defaultDate: null, // Used when field is blank: actual date,
- // +/-number for offset from today, null for today
- appendText: "", // Display text following the input box, e.g. showing the format
- buttonText: "...", // Text for trigger button
- buttonImage: "", // URL for trigger button image
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
- hideIfNoPrevNext: false, // True to hide next/previous month links
- // if not applicable, false to just disable them
- navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
- gotoCurrent: false, // True if today link goes back to current selection instead
- changeMonth: false, // True if month can be selected directly, false if only prev/next
- changeYear: false, // True if year can be selected directly, false if only prev/next
- yearRange: "c-10:c+10", // Range of years to display in drop-down,
- // either relative to today's year (-nn:+nn), relative to currently displayed year
- // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
- showOtherMonths: false, // True to show dates in other months, false to leave blank
- selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
- showWeek: false, // True to show week of the year, false to not show it
- calculateWeek: this.iso8601Week, // How to calculate the week of the year,
- // takes a Date and returns the number of the week for it
- shortYearCutoff: "+10", // Short year values < this are in the current century,
- // > this are in the previous century,
- // string value starting with "+" for current year + value
- minDate: null, // The earliest selectable date, or null for no limit
- maxDate: null, // The latest selectable date, or null for no limit
- duration: "fast", // Duration of display/closure
- beforeShowDay: null, // Function that takes a date and returns an array with
- // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
- // [2] = cell title (optional), e.g. $.datepicker.noWeekends
- beforeShow: null, // Function that takes an input field and
- // returns a set of custom settings for the date picker
- onSelect: null, // Define a callback function when a date is selected
- onChangeMonthYear: null, // Define a callback function when the month or year is changed
- onClose: null, // Define a callback function when the datepicker is closed
- numberOfMonths: 1, // Number of months to show at a time
- showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
- stepMonths: 1, // Number of months to step back/forward
- stepBigMonths: 12, // Number of months to step back/forward for the big links
- altField: "", // Selector for an alternate field to store selected dates into
- altFormat: "", // The date format to use for the alternate field
- constrainInput: true, // The input is constrained by the current date format
- showButtonPanel: false, // True to show button panel, false to not show it
- autoSize: false, // True to size the input for the date format, false to leave as is
- disabled: false // The initial disabled state
- };
- $.extend(this._defaults, this.regional[""]);
- this.regional.en = $.extend( true, {}, this.regional[ "" ]);
- this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
- this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
-}
-
-$.extend(Datepicker.prototype, {
- /* Class name added to elements to indicate already configured with a date picker. */
- markerClassName: "hasDatepicker",
-
- //Keep track of the maximum number of rows displayed (see #7043)
- maxRows: 4,
-
- // TODO rename to "widget" when switching to widget factory
- _widgetDatepicker: function() {
- return this.dpDiv;
- },
-
- /* Override the default settings for all instances of the date picker.
- * @param settings object - the new settings to use as defaults (anonymous object)
- * @return the manager object
- */
- setDefaults: function(settings) {
- datepicker_extendRemove(this._defaults, settings || {});
- return this;
- },
-
- /* Attach the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- * @param settings object - the new settings to use for this date picker instance (anonymous)
- */
- _attachDatepicker: function(target, settings) {
- var nodeName, inline, inst;
- nodeName = target.nodeName.toLowerCase();
- inline = (nodeName === "div" || nodeName === "span");
- if (!target.id) {
- this.uuid += 1;
- target.id = "dp" + this.uuid;
- }
- inst = this._newInst($(target), inline);
- inst.settings = $.extend({}, settings || {});
- if (nodeName === "input") {
- this._connectDatepicker(target, inst);
- } else if (inline) {
- this._inlineDatepicker(target, inst);
- }
- },
-
- /* Create a new instance object. */
- _newInst: function(target, inline) {
- var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
- return {id: id, input: target, // associated target
- selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
- drawMonth: 0, drawYear: 0, // month being drawn
- inline: inline, // is datepicker inline or not
- dpDiv: (!inline ? this.dpDiv : // presentation div
- datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
- },
-
- /* Attach the date picker to an input field. */
- _connectDatepicker: function(target, inst) {
- var input = $(target);
- inst.append = $([]);
- inst.trigger = $([]);
- if (input.hasClass(this.markerClassName)) {
- return;
- }
- this._attachments(input, inst);
- input.addClass(this.markerClassName).on( "keydown", this._doKeyDown).
- on( "keypress", this._doKeyPress).on( "keyup", this._doKeyUp);
- this._autoSize(inst);
- $.data(target, "datepicker", inst);
- //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
- if( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
+ // callbacks
+ beforeOpen: null,
+ close: null,
+ open: null,
+ select: null
},
- /* Make attachments based on settings. */
- _attachments: function(input, inst) {
- var showOn, buttonText, buttonImage,
- appendText = this._get(inst, "appendText"),
- isRTL = this._get(inst, "isRTL");
-
- if (inst.append) {
- inst.append.remove();
- }
- if (appendText) {
- inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
- input[isRTL ? "before" : "after"](inst.append);
- }
-
- input.off("focus", this._showDatepicker);
+ calendarOptions: [ "buttons", "disabled", "dateFormat", "eachDay", "labels",
+ "locale", "max", "min", "numberOfMonths", "showWeek" ],
- if (inst.trigger) {
- inst.trigger.remove();
- }
+ _create: function() {
+ this.suppressExpandOnFocus = false;
- showOn = this._get(inst, "showOn");
- if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
- input.on( "focus", this._showDatepicker );
+ if ( $.type( this.options.max ) === "string" ) {
+ this.options.max = Globalize.parseDate( this.options.max, { raw: "yyyy-MM-dd" } );
}
- if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
- buttonText = this._get(inst, "buttonText");
- buttonImage = this._get(inst, "buttonImage");
- inst.trigger = $(this._get(inst, "buttonImageOnly") ?
- $("<img/>").addClass(this._triggerClass).
- attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
- $("<button type='button'></button>").addClass(this._triggerClass).
- html(!buttonImage ? buttonText : $("<img/>").attr(
- { src:buttonImage, alt:buttonText, title:buttonText })));
- input[isRTL ? "before" : "after"](inst.trigger);
- inst.trigger.on( "click", function() {
- if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
- $.datepicker._hideDatepicker();
- } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
- $.datepicker._hideDatepicker();
- $.datepicker._showDatepicker(input[0]);
- } else {
- $.datepicker._showDatepicker(input[0]);
- }
- return false;
- });
- }
- },
-
- /* Apply the maximum length for the date format. */
- _autoSize: function(inst) {
- if (this._get(inst, "autoSize") && !inst.inline) {
- var findMax, max, maxI, i,
- date = new Date(2009, 12 - 1, 20), // Ensure double digits
- dateFormat = this._get(inst, "dateFormat");
-
- if (dateFormat.match(/[DM]/)) {
- findMax = function(names) {
- max = 0;
- maxI = 0;
- for (i = 0; i < names.length; i++) {
- if (names[i].length > max) {
- max = names[i].length;
- maxI = i;
- }
- }
- return maxI;
- };
- date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
- "monthNames" : "monthNamesShort"))));
- date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
- "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
- }
- inst.input.attr("size", this._formatDate(inst, date).length);
- }
- },
-
- /* Attach an inline date picker to a div. */
- _inlineDatepicker: function(target, inst) {
- var divSpan = $(target);
- if (divSpan.hasClass(this.markerClassName)) {
- return;
- }
- divSpan.addClass(this.markerClassName).append(inst.dpDiv);
- $.data(target, "datepicker", inst);
- this._setDate(inst, this._getDefaultDate(inst), true);
- this._updateDatepicker(inst);
- this._updateAlternate(inst);
- //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
- if( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
- // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
- // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
- inst.dpDiv.css( "display", "block" );
- },
-
- /* Pop-up the date picker in a "dialog" box.
- * @param input element - ignored
- * @param date string or Date - the initial date to display
- * @param onSelect function - the function to call when a date is selected
- * @param settings object - update the dialog date picker instance's settings (anonymous object)
- * @param pos int[2] - coordinates for the dialog's position within the screen or
- * event - with x/y coordinates or
- * leave empty for default (screen centre)
- * @return the manager object
- */
- _dialogDatepicker: function(input, date, onSelect, settings, pos) {
- var id, browserWidth, browserHeight, scrollX, scrollY,
- inst = this._dialogInst; // internal instance
-
- if (!inst) {
- this.uuid += 1;
- id = "dp" + this.uuid;
- this._dialogInput = $("<input type='text' id='" + id +
- "' style='position: absolute; top: -100px; width: 0px;'/>");
- this._dialogInput.on( "keydown", this._doKeyDown );
- $("body").append(this._dialogInput);
- inst = this._dialogInst = this._newInst(this._dialogInput, false);
- inst.settings = {};
- $.data(this._dialogInput[0], "datepicker", inst);
+ if ( $.type( this.options.min ) === "string" ) {
+ this.options.min = Globalize.parseDate( this.options.min, { raw: "yyyy-MM-dd" } );
}
- datepicker_extendRemove(inst.settings, settings || {});
- date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
- this._dialogInput.val(date);
- this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
- if (!this._pos) {
- browserWidth = document.documentElement.clientWidth;
- browserHeight = document.documentElement.clientHeight;
- scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
- scrollY = document.documentElement.scrollTop || document.body.scrollTop;
- this._pos = // should use actual width/height below
- [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
- }
+ this._createCalendar();
- // move input on screen for focus, but hidden behind dialog
- this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
- inst.settings.onSelect = onSelect;
- this._inDialog = true;
- this.dpDiv.addClass(this._dialogClass);
- this._showDatepicker(this._dialogInput[0]);
- if ($.blockUI) {
- $.blockUI(this.dpDiv);
- }
- $.data(this._dialogInput[0], "datepicker", inst);
- return this;
+ this._on( this._inputEvents );
+ this._on( this.calendar, this._calendarEvents );
+ this._on( this.document, this._documentEvents );
},
- /* Detach a datepicker from its control.
- * @param target element - the target input field or division or span
- */
- _destroyDatepicker: function(target) {
- var nodeName,
- $target = $(target),
- inst = $.data(target, "datepicker");
+ _getCreateOptions: function() {
+ var max = this.element.attr( "max" ),
+ min = this.element.attr( "min" ),
+ options = {};
- if (!$target.hasClass(this.markerClassName)) {
- return;
+ if ( max !== undefined ) {
+ options.max = Globalize.parseDate( max, { raw: "yyyy-MM-dd" } );
}
- nodeName = target.nodeName.toLowerCase();
- $.removeData(target, "datepicker");
- if (nodeName === "input") {
- inst.append.remove();
- inst.trigger.remove();
- $target.removeClass(this.markerClassName).
- off("focus", this._showDatepicker).
- off("keydown", this._doKeyDown).
- off("keypress", this._doKeyPress).
- off("keyup", this._doKeyUp);
- } else if (nodeName === "div" || nodeName === "span") {
- $target.removeClass(this.markerClassName).empty();
+ if ( min !== undefined ) {
+ options.min = Globalize.parseDate( min, { raw: "yyyy-MM-dd" } );
}
- if ( datepicker_instActive === inst ) {
- datepicker_instActive = null;
- }
+ return options;
},
- /* Enable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _enableDatepicker: function(target) {
- var nodeName, inline,
- $target = $(target),
- inst = $.data(target, "datepicker");
+ _createCalendar: function() {
+ var that = this,
+ globalize = new Globalize( this.options.locale );
- if (!$target.hasClass(this.markerClassName)) {
- return;
- }
+ this.calendar = $( "<div>" )
+ .addClass( "ui-front ui-datepicker" )
+ .appendTo( this._appendTo() );
- nodeName = target.nodeName.toLowerCase();
- if (nodeName === "input") {
- target.disabled = false;
- inst.trigger.filter("button").
- each(function() { this.disabled = false; }).end().
- filter("img").css({opacity: "1.0", cursor: ""});
- } else if (nodeName === "div" || nodeName === "span") {
- inline = $target.children("." + this._inlineClass);
- inline.children().removeClass("ui-state-disabled");
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
- prop("disabled", false);
- }
- this._disabledInputs = $.map(this._disabledInputs,
- function(value) { return (value === target ? null : value); }); // delete entry
- },
-
- /* Disable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _disableDatepicker: function(target) {
- var nodeName, inline,
- $target = $(target),
- inst = $.data(target, "datepicker");
-
- if (!$target.hasClass(this.markerClassName)) {
- return;
- }
+ // Initialize calendar widget
+ this.calendarInstance = this.calendar
+ .calendar( $.extend( {}, this.options, {
+ value: globalize.dateParser( this.options.dateFormat )( this.element.val() ),
+ select: function( event ) {
+ that.element.val( that.calendarInstance.value() );
+ that.close();
+ that._focusTrigger();
+ that._trigger( "select", event );
+ }
+ }) )
+ .calendar( "instance" );
- nodeName = target.nodeName.toLowerCase();
- if (nodeName === "input") {
- target.disabled = true;
- inst.trigger.filter("button").
- each(function() { this.disabled = true; }).end().
- filter("img").css({opacity: "0.5", cursor: "default"});
- } else if (nodeName === "div" || nodeName === "span") {
- inline = $target.children("." + this._inlineClass);
- inline.children().addClass("ui-state-disabled");
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
- prop("disabled", true);
- }
- this._disabledInputs = $.map(this._disabledInputs,
- function(value) { return (value === target ? null : value); }); // delete entry
- this._disabledInputs[this._disabledInputs.length] = target;
- },
+ this.calendarInstance.buttonClickContext = that.element[ 0 ];
- /* Is the first field in a jQuery collection disabled as a datepicker?
- * @param target element - the target input field or division or span
- * @return boolean - true if disabled, false if enabled
- */
- _isDisabledDatepicker: function(target) {
- if (!target) {
- return false;
- }
- for (var i = 0; i < this._disabledInputs.length; i++) {
- if (this._disabledInputs[i] === target) {
- return true;
- }
- }
- return false;
- },
+ this._setHiddenPicker();
- /* Retrieve the instance data for the target control.
- * @param target element - the target input field or division or span
- * @return object - the associated instance data
- * @throws error if a jQuery problem getting data
- */
- _getInst: function(target) {
- try {
- return $.data(target, "datepicker");
- }
- catch (err) {
- throw "Missing instance data for this datepicker";
- }
+ this.element.attr({
+ "aria-haspopup": true,
+ "aria-owns": this.calendar.attr( "id" )
+ });
},
- /* Update or retrieve the settings for a date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- * @param name object - the new settings to update or
- * string - the name of the setting to change or retrieve,
- * when retrieving also "all" for all instance settings or
- * "defaults" for all global defaults
- * @param value any - the new value for the setting
- * (omit if above is an object or to retrieve a value)
- */
- _optionDatepicker: function(target, name, value) {
- var settings, date, minDate, maxDate,
- inst = this._getInst(target);
-
- if (arguments.length === 2 && typeof name === "string") {
- return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
- (inst ? (name === "all" ? $.extend({}, inst.settings) :
- this._get(inst, name)) : null));
- }
-
- settings = name || {};
- if (typeof name === "string") {
- settings = {};
- settings[name] = value;
- }
-
- if (inst) {
- if (this._curInst === inst) {
- this._hideDatepicker();
+ _inputEvents: {
+ keydown: function( event ) {
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.TAB:
+ // Waiting for close() will make popup hide too late, which breaks tab key behavior
+ this.calendar.hide();
+ this.close( event );
+ break;
+ case $.ui.keyCode.ESCAPE:
+ if ( this.isOpen ) {
+ this.close( event );
+ }
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.UP:
+ clearTimeout( this.closeTimer );
+ this._delay( function() {
+ this.open( event );
+ this.calendarInstance.grid.focus();
+ }, 1 );
+ break;
}
-
- date = this._getDateDatepicker(target, true);
- minDate = this._getMinMaxDate(inst, "min");
- maxDate = this._getMinMaxDate(inst, "max");
- datepicker_extendRemove(inst.settings, settings);
- // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
- if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
- inst.settings.minDate = this._formatDate(inst, minDate);
- }
- if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
- inst.settings.maxDate = this._formatDate(inst, maxDate);
+ },
+ keyup: function() {
+ if ( this.isValid() ) {
+ this.refresh();
}
- if ( "disabled" in settings ) {
- if ( settings.disabled ) {
- this._disableDatepicker(target);
- } else {
- this._enableDatepicker(target);
- }
+ },
+ mousedown: function( event ) {
+ if ( this.isOpen ) {
+ this.suppressExpandOnFocus = true;
+ this.close();
+ return;
}
- this._attachments($(target), inst);
- this._autoSize(inst);
- this._setDate(inst, date);
- this._updateAlternate(inst);
- this._updateDatepicker(inst);
- }
- },
-
- // change method deprecated
- _changeDatepicker: function(target, name, value) {
- this._optionDatepicker(target, name, value);
- },
-
- /* Redraw the date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- */
- _refreshDatepicker: function(target) {
- var inst = this._getInst(target);
- if (inst) {
- this._updateDatepicker(inst);
- }
- },
-
- /* Set the dates for a jQuery selection.
- * @param target element - the target input field or division or span
- * @param date Date - the new date
- */
- _setDateDatepicker: function(target, date) {
- var inst = this._getInst(target);
- if (inst) {
- this._setDate(inst, date);
- this._updateDatepicker(inst);
- this._updateAlternate(inst);
- }
- },
-
- /* Get the date(s) for the first entry in a jQuery selection.
- * @param target element - the target input field or division or span
- * @param noDefault boolean - true if no default date is to be used
- * @return Date - the current date
- */
- _getDateDatepicker: function(target, noDefault) {
- var inst = this._getInst(target);
- if (inst && !inst.inline) {
- this._setDateFromField(inst, noDefault);
- }
- return (inst ? this._getDate(inst) : null);
- },
-
- /* Handle keystrokes. */
- _doKeyDown: function(event) {
- var onSelect, dateStr, sel,
- inst = $.datepicker._getInst(event.target),
- handled = true,
- isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
-
- inst._keyEvent = true;
- if ($.datepicker._datepickerShowing) {
- switch (event.keyCode) {
- case 9: $.datepicker._hideDatepicker();
- handled = false;
- break; // hide on tab out
- case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
- $.datepicker._currentClass + ")", inst.dpDiv);
- if (sel[0]) {
- $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
- }
-
- onSelect = $.datepicker._get(inst, "onSelect");
- if (onSelect) {
- dateStr = $.datepicker._formatDate(inst);
-
- // trigger custom callback
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
- } else {
- $.datepicker._hideDatepicker();
- }
-
- return false; // don't submit the form
- case 27: $.datepicker._hideDatepicker();
- break; // hide on escape
- case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- -$.datepicker._get(inst, "stepBigMonths") :
- -$.datepicker._get(inst, "stepMonths")), "M");
- break; // previous month/year on page up/+ ctrl
- case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- +$.datepicker._get(inst, "stepBigMonths") :
- +$.datepicker._get(inst, "stepMonths")), "M");
- break; // next month/year on page down/+ ctrl
- case 35: if (event.ctrlKey || event.metaKey) {
- $.datepicker._clearDate(event.target);
- }
- handled = event.ctrlKey || event.metaKey;
- break; // clear on ctrl or command +end
- case 36: if (event.ctrlKey || event.metaKey) {
- $.datepicker._gotoToday(event.target);
- }
- handled = event.ctrlKey || event.metaKey;
- break; // current on ctrl or command +home
- case 37: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
- }
- handled = event.ctrlKey || event.metaKey;
- // -1 day on ctrl or command +left
- if (event.originalEvent.altKey) {
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- -$.datepicker._get(inst, "stepBigMonths") :
- -$.datepicker._get(inst, "stepMonths")), "M");
- }
- // next month/year on alt +left on Mac
- break;
- case 38: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, -7, "D");
- }
- handled = event.ctrlKey || event.metaKey;
- break; // -1 week on ctrl or command +up
- case 39: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
- }
- handled = event.ctrlKey || event.metaKey;
- // +1 day on ctrl or command +right
- if (event.originalEvent.altKey) {
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- +$.datepicker._get(inst, "stepBigMonths") :
- +$.datepicker._get(inst, "stepMonths")), "M");
- }
- // next month/year on alt +right
- break;
- case 40: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, +7, "D");
- }
- handled = event.ctrlKey || event.metaKey;
- break; // +1 week on ctrl or command +down
- default: handled = false;
- }
- } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
- $.datepicker._showDatepicker(this);
- } else {
- handled = false;
- }
-
- if (handled) {
- event.preventDefault();
- event.stopPropagation();
- }
- },
-
- /* Filter entered characters - based on date format. */
- _doKeyPress: function(event) {
- var chars, chr,
- inst = $.datepicker._getInst(event.target);
-
- if ($.datepicker._get(inst, "constrainInput")) {
- chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
- chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
- return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
- }
- },
-
- /* Synchronise manual entry and field/alternate field. */
- _doKeyUp: function(event) {
- var date,
- inst = $.datepicker._getInst(event.target);
-
- if (inst.input.val() !== inst.lastVal) {
- try {
- date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
- (inst.input ? inst.input.val() : null),
- $.datepicker._getFormatConfig(inst));
-
- if (date) { // only if valid
- $.datepicker._setDateFromField(inst);
- $.datepicker._updateAlternate(inst);
- $.datepicker._updateDatepicker(inst);
- }
+ this.open( event );
+ clearTimeout( this.closeTimer );
+ },
+ focus: function( event ) {
+ if ( !this.suppressExpandOnFocus && !this.isOpen ) {
+ this._delay( function() {
+ this.open( event );
+ });
}
- catch (err) {
+ this._delay( function() {
+ this.suppressExpandOnFocus = false;
+ }, 100 );
+ },
+ blur: function() {
+ this.suppressExpandOnFocus = false;
+ }
+ },
+
+ _calendarEvents: {
+ focusout: function( event ) {
+ // use a timer to allow click to clear it and letting that
+ // handle the closing instead of opening again
+ // also allows tabbing inside the calendar without it closing
+ this.closeTimer = this._delay( function() {
+ this.close( event );
+ }, 150 );
+ },
+ focusin: function() {
+ clearTimeout( this.closeTimer );
+ },
+ mouseup: function() {
+ clearTimeout( this.closeTimer );
+ },
+ // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order
+ keyup: function( event ) {
+ if ( event.keyCode === $.ui.keyCode.ESCAPE && this.calendar.is( ":visible" ) ) {
+ this.close( event );
+ this._focusTrigger();
}
}
- return true;
},
- /* Pop-up the date picker for a given input field.
- * If false returned from beforeShow event handler do not show.
- * @param input element - the input field attached to the date picker or
- * event - if triggered by focus
- */
- _showDatepicker: function(input) {
- input = input.target || input;
- if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
- input = $("input", input.parentNode)[0];
- }
-
- if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
- return;
- }
-
- var inst, beforeShow, beforeShowSettings, isFixed,
- offset, showAnim, duration;
-
- inst = $.datepicker._getInst(input);
- if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
- $.datepicker._curInst.dpDiv.stop(true, true);
- if ( inst && $.datepicker._datepickerShowing ) {
- $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
+ _documentEvents: {
+ mousedown: function( event ) {
+ if ( !this.isOpen ) {
+ return;
}
- }
-
- beforeShow = $.datepicker._get(inst, "beforeShow");
- beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
- if(beforeShowSettings === false){
- return;
- }
- datepicker_extendRemove(inst.settings, beforeShowSettings);
-
- inst.lastVal = null;
- $.datepicker._lastInput = input;
- $.datepicker._setDateFromField(inst);
- if ($.datepicker._inDialog) { // hide cursor
- input.value = "";
- }
- if (!$.datepicker._pos) { // position below input
- $.datepicker._pos = $.datepicker._findPos(input);
- $.datepicker._pos[1] += input.offsetHeight; // add the height
- }
-
- isFixed = false;
- $(input).parents().each(function() {
- isFixed |= $(this).css("position") === "fixed";
- return !isFixed;
- });
-
- offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
- $.datepicker._pos = null;
- //to avoid flashes on Firefox
- inst.dpDiv.empty();
- // determine sizing offscreen
- inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
- $.datepicker._updateDatepicker(inst);
- // fix width for dynamic number of date pickers
- // and adjust position before showing
- offset = $.datepicker._checkOffset(inst, offset, isFixed);
- inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
- "static" : (isFixed ? "fixed" : "absolute")), display: "none",
- left: offset.left + "px", top: offset.top + "px"});
-
- if (!inst.inline) {
- showAnim = $.datepicker._get(inst, "showAnim");
- duration = $.datepicker._get(inst, "duration");
- inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
- $.datepicker._datepickerShowing = true;
-
- if ( $.effects && $.effects.effect[ showAnim ] ) {
- inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
- } else {
- inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
+ if ( !$( event.target ).closest( this.element.add( this.calendar ) ).length ) {
+ this.close( event );
}
-
- if ( $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.trigger( "focus" );
- }
-
- $.datepicker._curInst = inst;
}
},
- /* Generate the date picker content. */
- _updateDatepicker: function(inst) {
- this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
- datepicker_instActive = inst; // for delegate hover events
- inst.dpDiv.empty().append(this._generateHTML(inst));
- this._attachHandlers(inst);
+ _appendTo: function() {
+ var element = this.options.appendTo;
- var origyearshtml,
- numMonths = this._getNumberOfMonths(inst),
- cols = numMonths[1],
- width = 17,
- activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
-
- if ( activeCell.length > 0 ) {
- datepicker_handleMouseover.apply( activeCell.get( 0 ) );
+ if ( element ) {
+ element = element.jquery || element.nodeType ?
+ $( element ) :
+ this.document.find( element ).eq( 0 );
}
- inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
- if (cols > 1) {
- inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
+ if ( !element || !element[ 0 ] ) {
+ element = this.element.closest( ".ui-front, dialog" );
}
- inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
- "Class"]("ui-datepicker-multi");
- inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
- "Class"]("ui-datepicker-rtl");
- if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.trigger( "focus" );
+ if ( !element.length ) {
+ element = this.document[ 0 ].body;
}
- // deffered render of the years select (to avoid flashes on Firefox)
- if( inst.yearshtml ){
- origyearshtml = inst.yearshtml;
- setTimeout(function(){
- //assure that inst.yearshtml didn't change.
- if( origyearshtml === inst.yearshtml && inst.yearshtml ){
- inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
- }
- origyearshtml = inst.yearshtml = null;
- }, 0);
- }
+ return element;
},
- // #6694 - don't focus the input if it's already focused
- // this breaks the change event in IE
- // Support: IE and jQuery <1.9
- _shouldFocusInput: function( inst ) {
- return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+ _focusTrigger: function() {
+ this.suppressExpandOnFocus = true;
+ this.element.focus();
},
- /* Check positioning to remain on screen. */
- _checkOffset: function(inst, offset, isFixed) {
- var dpWidth = inst.dpDiv.outerWidth(),
- dpHeight = inst.dpDiv.outerHeight(),
- inputWidth = inst.input ? inst.input.outerWidth() : 0,
- inputHeight = inst.input ? inst.input.outerHeight() : 0,
- viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
- viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
-
- offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
- offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
- offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
-
- // now check if datepicker is showing outside window viewport - move to a better place if so.
- offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
- Math.abs(offset.left + dpWidth - viewWidth) : 0);
- offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
- Math.abs(dpHeight + inputHeight) : 0);
-
- return offset;
- },
-
- /* Find an object's position on the screen. */
- _findPos: function(obj) {
- var position,
- inst = this._getInst(obj),
- isRTL = this._get(inst, "isRTL");
-
- while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
- obj = obj[isRTL ? "previousSibling" : "nextSibling"];
- }
-
- position = $(obj).offset();
- return [position.left, position.top];
+ refresh: function() {
+ this.calendarInstance.option( "value", this._getParsedValue() );
},
- /* Hide the date picker from view.
- * @param input element - the input field attached to the date picker
- */
- _hideDatepicker: function(input) {
- var showAnim, duration, postProcess, onClose,
- inst = this._curInst;
-
- if (!inst || (input && inst !== $.data(input, "datepicker"))) {
+ open: function( event ) {
+ if ( this.isOpen ) {
return;
}
-
- if (this._datepickerShowing) {
- showAnim = this._get(inst, "showAnim");
- duration = this._get(inst, "duration");
- postProcess = function() {
- $.datepicker._tidyDialog(inst);
- };
-
- // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
- if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
- inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
- } else {
- inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
- (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
- }
-
- if (!showAnim) {
- postProcess();
- }
- this._datepickerShowing = false;
-
- onClose = this._get(inst, "onClose");
- if (onClose) {
- onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
- }
-
- this._lastInput = null;
- if (this._inDialog) {
- this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
- if ($.blockUI) {
- $.unblockUI();
- $("body").append(this.dpDiv);
- }
- }
- this._inDialog = false;
- }
- },
-
- /* Tidy up after a dialog display. */
- _tidyDialog: function(inst) {
- inst.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar");
- },
-
- /* Close date picker if clicked elsewhere. */
- _checkExternalClick: function(event) {
- if (!$.datepicker._curInst) {
+ if ( this._trigger( "beforeOpen", event ) === false ) {
return;
}
- var $target = $(event.target),
- inst = $.datepicker._getInst($target[0]);
-
- if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
- $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
- !$target.hasClass($.datepicker.markerClassName) &&
- !$target.closest("." + $.datepicker._triggerClass).length &&
- $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
- ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
- $.datepicker._hideDatepicker();
- }
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustDate: function(id, offset, period) {
- var target = $(id),
- inst = this._getInst(target[0]);
+ this.calendarInstance.refresh();
+ this.calendar
+ .attr({
+ "aria-hidden": false,
+ "aria-expanded": true
+ })
+ .show()
+ .position( this._buildPosition() )
+ .hide();
+ this._show( this.calendar, this.options.show );
- if (this._isDisabledDatepicker(target[0])) {
- return;
- }
- this._adjustInstDate(inst, offset +
- (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
- period);
- this._updateDatepicker(inst);
- },
+ // Take trigger out of tab order to allow shift-tab to skip trigger
+ // TODO Does this really make sense? related bug: tab-shift moves focus to last element on page
+ this.element.attr( "tabindex", -1 );
+ this.isOpen = true;
- /* Action for current link. */
- _gotoToday: function(id) {
- var date,
- target = $(id),
- inst = this._getInst(target[0]);
-
- if (this._get(inst, "gotoCurrent") && inst.currentDay) {
- inst.selectedDay = inst.currentDay;
- inst.drawMonth = inst.selectedMonth = inst.currentMonth;
- inst.drawYear = inst.selectedYear = inst.currentYear;
- } else {
- date = new Date();
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- }
- this._notifyChange(inst);
- this._adjustDate(target);
+ this._trigger( "open", event );
},
- /* Action for selecting a new month/year. */
- _selectMonthYear: function(id, select, period) {
- var target = $(id),
- inst = this._getInst(target[0]);
+ close: function( event ) {
+ this._setHiddenPicker();
+ this._hide( this.calendar, this.options.hide );
- inst["selected" + (period === "M" ? "Month" : "Year")] =
- inst["draw" + (period === "M" ? "Month" : "Year")] =
- parseInt(select.options[select.selectedIndex].value,10);
+ this.element.attr( "tabindex", 0 );
- this._notifyChange(inst);
- this._adjustDate(target);
+ this.isOpen = false;
+ this._trigger( "close", event );
},
- /* Action for selecting a day. */
- _selectDay: function(id, month, year, td) {
- var inst,
- target = $(id);
-
- if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
- return;
- }
-
- inst = this._getInst(target[0]);
- inst.selectedDay = inst.currentDay = $("a", td).html();
- inst.selectedMonth = inst.currentMonth = month;
- inst.selectedYear = inst.currentYear = year;
- this._selectDate(id, this._formatDate(inst,
- inst.currentDay, inst.currentMonth, inst.currentYear));
+ _setHiddenPicker: function() {
+ this.calendar.attr({
+ "aria-hidden": true,
+ "aria-expanded": false
+ });
},
- /* Erase the input field and hide the date picker. */
- _clearDate: function(id) {
- var target = $(id);
- this._selectDate(target, "");
+ _buildPosition: function() {
+ return $.extend( { of: this.element }, this.options.position );
},
- /* Update the input field with the selected date. */
- _selectDate: function(id, dateStr) {
- var onSelect,
- target = $(id),
- inst = this._getInst(target[0]);
-
- dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
- if (inst.input) {
- inst.input.val(dateStr);
- }
- this._updateAlternate(inst);
-
- onSelect = this._get(inst, "onSelect");
- if (onSelect) {
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
- } else if (inst.input) {
- inst.input.trigger("change"); // fire the change event
- }
-
- if (inst.inline){
- this._updateDatepicker(inst);
+ value: function( value ) {
+ if ( arguments.length ) {
+ this.valueAsDate( this.calendarInstance._parse( value ) );
} else {
- this._hideDatepicker();
- this._lastInput = inst.input[0];
- if (typeof(inst.input[0]) !== "object") {
- inst.input.trigger( "focus" ); // restore focus
- }
- this._lastInput = null;
- }
- },
-
- /* Update any alternate field to synchronise with the main field. */
- _updateAlternate: function(inst) {
- var altFormat, date, dateStr,
- altField = this._get(inst, "altField");
-
- if (altField) { // update alternate field too
- altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
- date = this._getDate(inst);
- dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
- $(altField).each(function() { $(this).val(dateStr); });
- }
- },
-
- /* Set as beforeShowDay function to prevent selection of weekends.
- * @param date Date - the date to customise
- * @return [boolean, string] - is this date selectable?, what is its CSS class?
- */
- noWeekends: function(date) {
- var day = date.getDay();
- return [(day > 0 && day < 6), ""];
- },
-
- /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
- * @param date Date - the date to get the week for
- * @return number - the number of the week within the year that contains this date
- */
- iso8601Week: function(date) {
- var time,
- checkDate = new Date(date.getTime());
-
- // Find Thursday of this week starting on Monday
- checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
-
- time = checkDate.getTime();
- checkDate.setMonth(0); // Compare with Jan 1
- checkDate.setDate(1);
- return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
- },
-
- /* Parse a string value into a date object.
- * See formatDate below for the possible formats.
- *
- * @param format string - the expected format of the date
- * @param value string - the date in the above format
- * @param settings Object - attributes include:
- * shortYearCutoff number - the cutoff year for determining the century (optional)
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return Date - the extracted date value or null if value is blank
- */
- parseDate: function (format, value, settings) {
- if (format == null || value == null) {
- throw "Invalid arguments";
- }
-
- value = (typeof value === "object" ? value.toString() : value + "");
- if (value === "") {
- return null;
- }
-
- var iFormat, dim, extra,
- iValue = 0,
- shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
- shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
- new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
- year = -1,
- month = -1,
- day = -1,
- doy = -1,
- literal = false,
- date,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- },
- // Extract a number from the string value
- getNumber = function(match) {
- var isDoubled = lookAhead(match),
- size = (match === "@" ? 14 : (match === "!" ? 20 :
- (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
- minSize = (match === "y" ? size : 1),
- digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
- num = value.substring(iValue).match(digits);
- if (!num) {
- throw "Missing number at position " + iValue;
- }
- iValue += num[0].length;
- return parseInt(num[0], 10);
- },
- // Extract a name from the string value and convert to an index
- getName = function(match, shortNames, longNames) {
- var index = -1,
- names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
- return [ [k, v] ];
- }).sort(function (a, b) {
- return -(a[1].length - b[1].length);
- });
-
- $.each(names, function (i, pair) {
- var name = pair[1];
- if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
- index = pair[0];
- iValue += name.length;
- return false;
- }
- });
- if (index !== -1) {
- return index + 1;
- } else {
- throw "Unknown name at position " + iValue;
- }
- },
- // Confirm that a literal character matches the string value
- checkLiteral = function() {
- if (value.charAt(iValue) !== format.charAt(iFormat)) {
- throw "Unexpected literal at position " + iValue;
- }
- iValue++;
- };
-
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- checkLiteral();
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d":
- day = getNumber("d");
- break;
- case "D":
- getName("D", dayNamesShort, dayNames);
- break;
- case "o":
- doy = getNumber("o");
- break;
- case "m":
- month = getNumber("m");
- break;
- case "M":
- month = getName("M", monthNamesShort, monthNames);
- break;
- case "y":
- year = getNumber("y");
- break;
- case "@":
- date = new Date(getNumber("@"));
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "!":
- date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "'":
- if (lookAhead("'")){
- checkLiteral();
- } else {
- literal = true;
- }
- break;
- default:
- checkLiteral();
- }
- }
- }
-
- if (iValue < value.length){
- extra = value.substr(iValue);
- if (!/^\s+/.test(extra)) {
- throw "Extra/unparsed characters found in date: " + extra;
- }
- }
-
- if (year === -1) {
- year = new Date().getFullYear();
- } else if (year < 100) {
- year += new Date().getFullYear() - new Date().getFullYear() % 100 +
- (year <= shortYearCutoff ? 0 : -100);
- }
-
- if (doy > -1) {
- month = 1;
- day = doy;
- do {
- dim = this._getDaysInMonth(year, month - 1);
- if (day <= dim) {
- break;
- }
- month++;
- day -= dim;
- } while (true);
+ return this._getParsedValue() ? this.element.val() : null;
}
-
- date = this._daylightSavingAdjust(new Date(year, month - 1, day));
- if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
- throw "Invalid date"; // E.g. 31/02/00
- }
- return date;
},
- /* Standard date formats. */
- ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
- COOKIE: "D, dd M yy",
- ISO_8601: "yy-mm-dd",
- RFC_822: "D, d M y",
- RFC_850: "DD, dd-M-y",
- RFC_1036: "D, d M y",
- RFC_1123: "D, d M yy",
- RFC_2822: "D, d M yy",
- RSS: "D, d M y", // RFC 822
- TICKS: "!",
- TIMESTAMP: "@",
- W3C: "yy-mm-dd", // ISO 8601
-
- _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
- Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
-
- /* Format a date object into a string value.
- * The format can be combinations of the following:
- * d - day of month (no leading zero)
- * dd - day of month (two digit)
- * o - day of year (no leading zeros)
- * oo - day of year (three digit)
- * D - day name short
- * DD - day name long
- * m - month of year (no leading zero)
- * mm - month of year (two digit)
- * M - month name short
- * MM - month name long
- * y - year (two digit)
- * yy - year (four digit)
- * @ - Unix timestamp (ms since 01/01/1970)
- * ! - Windows ticks (100ns since 01/01/0001)
- * "..." - literal text
- * '' - single quote
- *
- * @param format string - the desired format of the date
- * @param date Date - the date value to format
- * @param settings Object - attributes include:
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return string - the date in the above format
- */
- formatDate: function (format, date, settings) {
- if (!date) {
- return "";
- }
-
- var iFormat,
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- },
- // Format a number, with leading zero if necessary
- formatNumber = function(match, value, len) {
- var num = "" + value;
- if (lookAhead(match)) {
- while (num.length < len) {
- num = "0" + num;
- }
- }
- return num;
- },
- // Format a name, short or long as requested
- formatName = function(match, value, shortNames, longNames) {
- return (lookAhead(match) ? longNames[value] : shortNames[value]);
- },
- output = "",
- literal = false;
-
- if (date) {
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- output += format.charAt(iFormat);
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d":
- output += formatNumber("d", date.getDate(), 2);
- break;
- case "D":
- output += formatName("D", date.getDay(), dayNamesShort, dayNames);
- break;
- case "o":
- output += formatNumber("o",
- Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
- break;
- case "m":
- output += formatNumber("m", date.getMonth() + 1, 2);
- break;
- case "M":
- output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
- break;
- case "y":
- output += (lookAhead("y") ? date.getFullYear() :
- (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
- break;
- case "@":
- output += date.getTime();
- break;
- case "!":
- output += date.getTime() * 10000 + this._ticksTo1970;
- break;
- case "'":
- if (lookAhead("'")) {
- output += "'";
- } else {
- literal = true;
- }
- break;
- default:
- output += format.charAt(iFormat);
- }
- }
+ valueAsDate: function( value ) {
+ if ( arguments.length ) {
+ if ( this.calendarInstance._isValid( value ) ) {
+ this.calendarInstance.valueAsDate( value );
+ this.element.val( this.calendarInstance._format( value ) );
}
+ } else {
+ return this._getParsedValue();
}
- return output;
},
- /* Extract all possible characters from the date format. */
- _possibleChars: function (format) {
- var iFormat,
- chars = "",
- literal = false,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- };
-
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- chars += format.charAt(iFormat);
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d": case "m": case "y": case "@":
- chars += "0123456789";
- break;
- case "D": case "M":
- return null; // Accept anything
- case "'":
- if (lookAhead("'")) {
- chars += "'";
- } else {
- literal = true;
- }
- break;
- default:
- chars += format.charAt(iFormat);
- }
- }
- }
- return chars;
+ isValid: function() {
+ return this.calendarInstance._isValid( this._getParsedValue() );
},
- /* Get a setting value, defaulting if necessary. */
- _get: function(inst, name) {
- return inst.settings[name] !== undefined ?
- inst.settings[name] : this._defaults[name];
+ _destroy: function() {
+ this.calendarInstance.destroy();
+ this.calendar.remove();
+ this.element.removeAttr( "aria-haspopup aria-owns" );
},
- /* Parse existing date and initialise date picker. */
- _setDateFromField: function(inst, noDefault) {
- if (inst.input.val() === inst.lastVal) {
- return;
- }
-
- var dateFormat = this._get(inst, "dateFormat"),
- dates = inst.lastVal = inst.input ? inst.input.val() : null,
- defaultDate = this._getDefaultDate(inst),
- date = defaultDate,
- settings = this._getFormatConfig(inst);
-
- try {
- date = this.parseDate(dateFormat, dates, settings) || defaultDate;
- } catch (event) {
- dates = (noDefault ? "" : dates);
- }
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- inst.currentDay = (dates ? date.getDate() : 0);
- inst.currentMonth = (dates ? date.getMonth() : 0);
- inst.currentYear = (dates ? date.getFullYear() : 0);
- this._adjustInstDate(inst);
+ widget: function() {
+ return this.calendar;
},
- /* Retrieve the default date shown on opening. */
- _getDefaultDate: function(inst) {
- return this._restrictMinMax(inst,
- this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
+ _getParsedValue: function() {
+ return this.calendarInstance._parse( this.element.val() );
},
- /* A date may be specified as an exact value or a relative one. */
- _determineDate: function(inst, date, defaultDate) {
- var offsetNumeric = function(offset) {
- var date = new Date();
- date.setDate(date.getDate() + offset);
- return date;
- },
- offsetString = function(offset) {
- try {
- return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
- offset, $.datepicker._getFormatConfig(inst));
- }
- catch (e) {
- // Ignore
- }
-
- var date = (offset.toLowerCase().match(/^c/) ?
- $.datepicker._getDate(inst) : null) || new Date(),
- year = date.getFullYear(),
- month = date.getMonth(),
- day = date.getDate(),
- pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
- matches = pattern.exec(offset);
-
- while (matches) {
- switch (matches[2] || "d") {
- case "d" : case "D" :
- day += parseInt(matches[1],10); break;
- case "w" : case "W" :
- day += parseInt(matches[1],10) * 7; break;
- case "m" : case "M" :
- month += parseInt(matches[1],10);
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
- break;
- case "y": case "Y" :
- year += parseInt(matches[1],10);
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
- break;
- }
- matches = pattern.exec(offset);
- }
- return new Date(year, month, day);
- },
- newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
- (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+ _setOption: function( key, value ) {
+ this._super( key, value );
- newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
- if (newDate) {
- newDate.setHours(0);
- newDate.setMinutes(0);
- newDate.setSeconds(0);
- newDate.setMilliseconds(0);
+ if ( $.inArray( key, this.calendarOptions ) !== -1 ) {
+ this.calendarInstance.option( key, value );
}
- return this._daylightSavingAdjust(newDate);
- },
- /* Handle switch to/from daylight saving.
- * Hours may be non-zero on daylight saving cut-over:
- * > 12 when midnight changeover, but then cannot generate
- * midnight datetime, so jump to 1AM, otherwise reset.
- * @param date (Date) the date to check
- * @return (Date) the corrected date
- */
- _daylightSavingAdjust: function(date) {
- if (!date) {
- return null;
+ if ( key === "appendTo" ) {
+ this.calendar.appendTo( this._appendTo() );
}
- date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
- return date;
- },
-
- /* Set the date(s) directly. */
- _setDate: function(inst, date, noChange) {
- var clear = !date,
- origMonth = inst.selectedMonth,
- origYear = inst.selectedYear,
- newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
- inst.selectedDay = inst.currentDay = newDate.getDate();
- inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
- inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
- if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
- this._notifyChange(inst);
+ if ( key === "locale" || key === "dateFormat" ) {
+ this.element.val( this.calendarInstance.value() );
}
- this._adjustInstDate(inst);
- if (inst.input) {
- inst.input.val(clear ? "" : this._formatDate(inst));
- }
- },
- /* Retrieve the date(s) directly. */
- _getDate: function(inst) {
- var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
- this._daylightSavingAdjust(new Date(
- inst.currentYear, inst.currentMonth, inst.currentDay)));
- return startDate;
- },
-
- /* Attach the onxxx handlers. These are declared statically so
- * they work with static code transformers like Caja.
- */
- _attachHandlers: function(inst) {
- var stepMonths = this._get(inst, "stepMonths"),
- id = "#" + inst.id.replace( /\\\\/g, "\\" );
- inst.dpDiv.find("[data-handler]").map(function () {
- var handler = {
- prev: function () {
- $.datepicker._adjustDate(id, -stepMonths, "M");
- },
- next: function () {
- $.datepicker._adjustDate(id, +stepMonths, "M");
- },
- hide: function () {
- $.datepicker._hideDatepicker();
- },
- today: function () {
- $.datepicker._gotoToday(id);
- },
- selectDay: function () {
- $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
- return false;
- },
- selectMonth: function () {
- $.datepicker._selectMonthYear(id, this, "M");
- return false;
- },
- selectYear: function () {
- $.datepicker._selectMonthYear(id, this, "Y");
- return false;
- }
- };
- $(this).on(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
- });
- },
+ if ( key === "disabled" ) {
+ this.element
+ .prop( "disabled", value )
+ .toggleClass( "ui-state-disabled", value )
+ .attr( "aria-disabled", value );
- /* Generate the HTML for the current state of the date picker. */
- _generateHTML: function(inst) {
- var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
- controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
- monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
- selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
- cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
- printDate, dRow, tbody, daySettings, otherMonth, unselectable,
- tempDate = new Date(),
- today = this._daylightSavingAdjust(
- new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
- isRTL = this._get(inst, "isRTL"),
- showButtonPanel = this._get(inst, "showButtonPanel"),
- hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
- navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
- numMonths = this._getNumberOfMonths(inst),
- showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
- stepMonths = this._get(inst, "stepMonths"),
- isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
- currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
- new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
- minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- drawMonth = inst.drawMonth - showCurrentAtPos,
- drawYear = inst.drawYear;
-
- if (drawMonth < 0) {
- drawMonth += 12;
- drawYear--;
- }
- if (maxDate) {
- maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
- maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
- maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
- while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
- drawMonth--;
- if (drawMonth < 0) {
- drawMonth = 11;
- drawYear--;
- }
+ if ( value ) {
+ this.close();
}
}
- inst.drawMonth = drawMonth;
- inst.drawYear = drawYear;
-
- prevText = this._get(inst, "prevText");
- prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
- this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
- this._getFormatConfig(inst)));
-
- prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
- "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
- " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
- (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
- nextText = this._get(inst, "nextText");
- nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
- this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
- this._getFormatConfig(inst)));
-
- next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
- "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
- " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
- (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
-
- currentText = this._get(inst, "currentText");
- gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
- currentText = (!navigationAsDateFormat ? currentText :
- this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
-
- controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
- this._get(inst, "closeText") + "</button>" : "");
-
- buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
- (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
- ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
-
- firstDay = parseInt(this._get(inst, "firstDay"),10);
- firstDay = (isNaN(firstDay) ? 0 : firstDay);
-
- showWeek = this._get(inst, "showWeek");
- dayNames = this._get(inst, "dayNames");
- dayNamesMin = this._get(inst, "dayNamesMin");
- monthNames = this._get(inst, "monthNames");
- monthNamesShort = this._get(inst, "monthNamesShort");
- beforeShowDay = this._get(inst, "beforeShowDay");
- showOtherMonths = this._get(inst, "showOtherMonths");
- selectOtherMonths = this._get(inst, "selectOtherMonths");
- defaultDate = this._getDefaultDate(inst);
- html = "";
- dow;
- for (row = 0; row < numMonths[0]; row++) {
- group = "";
- this.maxRows = 4;
- for (col = 0; col < numMonths[1]; col++) {
- selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
- cornerClass = " ui-corner-all";
- calender = "";
- if (isMultiMonth) {
- calender += "<div class='ui-datepicker-group";
- if (numMonths[1] > 1) {
- switch (col) {
- case 0: calender += " ui-datepicker-group-first";
- cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
- case numMonths[1]-1: calender += " ui-datepicker-group-last";
- cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
- default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
- }
- }
- calender += "'>";
- }
- calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
- (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
- (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
- this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
- row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
- "</div><table class='ui-datepicker-calendar'><thead>" +
- "<tr>";
- thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
- for (dow = 0; dow < 7; dow++) { // days of the week
- day = (dow + firstDay) % 7;
- thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
- "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
- }
- calender += thead + "</tr></thead><tbody>";
- daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
- if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
- inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
- }
- leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
- curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
- numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
- this.maxRows = numRows;
- printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
- for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
- calender += "<tr>";
- tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
- this._get(inst, "calculateWeek")(printDate) + "</td>");
- for (dow = 0; dow < 7; dow++) { // create date picker days
- daySettings = (beforeShowDay ?
- beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
- otherMonth = (printDate.getMonth() !== drawMonth);
- unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
- (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
- tbody += "<td class='" +
- ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
- (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
- ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
- (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
- // or defaultDate is current printedDate and defaultDate is selectedDate
- " " + this._dayOverClass : "") + // highlight selected day
- (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
- (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
- (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
- (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
- ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
- (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
- (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
- (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
- (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
- (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
- (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
- "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
- printDate.setDate(printDate.getDate() + 1);
- printDate = this._daylightSavingAdjust(printDate);
- }
- calender += tbody + "</tr>";
- }
- drawMonth++;
- if (drawMonth > 11) {
- drawMonth = 0;
- drawYear++;
- }
- calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
- ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
- group += calender;
- }
- html += group;
- }
- html += buttonPanel;
- inst._keyEvent = false;
- return html;
- },
-
- /* Generate the month and year header. */
- _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
- secondary, monthNames, monthNamesShort) {
-
- var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
- changeMonth = this._get(inst, "changeMonth"),
- changeYear = this._get(inst, "changeYear"),
- showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
- html = "<div class='ui-datepicker-title'>",
- monthHtml = "";
-
- // month selection
- if (secondary || !changeMonth) {
- monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
- } else {
- inMinYear = (minDate && minDate.getFullYear() === drawYear);
- inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
- monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
- for ( month = 0; month < 12; month++) {
- if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
- monthHtml += "<option value='" + month + "'" +
- (month === drawMonth ? " selected='selected'" : "") +
- ">" + monthNamesShort[month] + "</option>";
- }
- }
- monthHtml += "</select>";
- }
-
- if (!showMonthAfterYear) {
- html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
- }
-
- // year selection
- if ( !inst.yearshtml ) {
- inst.yearshtml = "";
- if (secondary || !changeYear) {
- html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
- } else {
- // determine range of years to display
- years = this._get(inst, "yearRange").split(":");
- thisYear = new Date().getFullYear();
- determineYear = function(value) {
- var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
- (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
- parseInt(value, 10)));
- return (isNaN(year) ? thisYear : year);
- };
- year = determineYear(years[0]);
- endYear = Math.max(year, determineYear(years[1] || ""));
- year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
- endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
- inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
- for (; year <= endYear; year++) {
- inst.yearshtml += "<option value='" + year + "'" +
- (year === drawYear ? " selected='selected'" : "") +
- ">" + year + "</option>";
- }
- inst.yearshtml += "</select>";
-
- html += inst.yearshtml;
- inst.yearshtml = null;
- }
+ if ( key === "position" ) {
+ this.calendar.position( this._buildPosition() );
}
-
- html += this._get(inst, "yearSuffix");
- if (showMonthAfterYear) {
- html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
- }
- html += "</div>"; // Close datepicker_header
- return html;
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustInstDate: function(inst, offset, period) {
- var year = inst.drawYear + (period === "Y" ? offset : 0),
- month = inst.drawMonth + (period === "M" ? offset : 0),
- day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
- date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
-
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- if (period === "M" || period === "Y") {
- this._notifyChange(inst);
- }
- },
-
- /* Ensure a date is within any min/max bounds. */
- _restrictMinMax: function(inst, date) {
- var minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- newDate = (minDate && date < minDate ? minDate : date);
- return (maxDate && newDate > maxDate ? maxDate : newDate);
- },
-
- /* Notify change of month/year. */
- _notifyChange: function(inst) {
- var onChange = this._get(inst, "onChangeMonthYear");
- if (onChange) {
- onChange.apply((inst.input ? inst.input[0] : null),
- [inst.selectedYear, inst.selectedMonth + 1, inst]);
- }
- },
-
- /* Determine the number of months to show. */
- _getNumberOfMonths: function(inst) {
- var numMonths = this._get(inst, "numberOfMonths");
- return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
- },
-
- /* Determine the current maximum date - ensure no time components are set. */
- _getMinMaxDate: function(inst, minMax) {
- return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
- },
-
- /* Find the number of days in a given month. */
- _getDaysInMonth: function(year, month) {
- return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
- },
-
- /* Find the day of the week of the first of a month. */
- _getFirstDayOfMonth: function(year, month) {
- return new Date(year, month, 1).getDay();
- },
-
- /* Determines if we should allow a "next/prev" month display change. */
- _canAdjustMonth: function(inst, offset, curYear, curMonth) {
- var numMonths = this._getNumberOfMonths(inst),
- date = this._daylightSavingAdjust(new Date(curYear,
- curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
-
- if (offset < 0) {
- date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
- }
- return this._isInRange(inst, date);
- },
-
- /* Is the given date in the accepted range? */
- _isInRange: function(inst, date) {
- var yearSplit, currentYear,
- minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- minYear = null,
- maxYear = null,
- years = this._get(inst, "yearRange");
- if (years){
- yearSplit = years.split(":");
- currentYear = new Date().getFullYear();
- minYear = parseInt(yearSplit[0], 10);
- maxYear = parseInt(yearSplit[1], 10);
- if ( yearSplit[0].match(/[+\-].*/) ) {
- minYear += currentYear;
- }
- if ( yearSplit[1].match(/[+\-].*/) ) {
- maxYear += currentYear;
- }
- }
-
- return ((!minDate || date.getTime() >= minDate.getTime()) &&
- (!maxDate || date.getTime() <= maxDate.getTime()) &&
- (!minYear || date.getFullYear() >= minYear) &&
- (!maxYear || date.getFullYear() <= maxYear));
- },
-
- /* Provide the configuration settings for formatting/parsing. */
- _getFormatConfig: function(inst) {
- var shortYearCutoff = this._get(inst, "shortYearCutoff");
- shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
- new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
- return {shortYearCutoff: shortYearCutoff,
- dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
- monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
- },
-
- /* Format the given date for display. */
- _formatDate: function(inst, day, month, year) {
- if (!day) {
- inst.currentDay = inst.selectedDay;
- inst.currentMonth = inst.selectedMonth;
- inst.currentYear = inst.selectedYear;
- }
- var date = (day ? (typeof day === "object" ? day :
- this._daylightSavingAdjust(new Date(year, month, day))) :
- this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
- return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
}
});
-/*
- * Bind hover events for datepicker elements.
- * Done via delegate so the binding only occurs once in the lifetime of the parent div.
- * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
- */
-function datepicker_bindHover(dpDiv) {
- var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
- return dpDiv.on( "mouseout", selector, function() {
- $(this).removeClass("ui-state-hover");
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
- $(this).removeClass("ui-datepicker-prev-hover");
- }
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
- $(this).removeClass("ui-datepicker-next-hover");
- }
- })
- .on( "mouseover", selector, datepicker_handleMouseover );
-}
-
-function datepicker_handleMouseover() {
- if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
- $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
- $(this).addClass("ui-state-hover");
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
- $(this).addClass("ui-datepicker-prev-hover");
- }
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
- $(this).addClass("ui-datepicker-next-hover");
- }
- }
-}
-
-/* jQuery extend now ignores nulls! */
-function datepicker_extendRemove(target, props) {
- $.extend(target, props);
- for (var name in props) {
- if (props[name] == null) {
- target[name] = props[name];
- }
- }
- return target;
-}
-
-/* Invoke the datepicker functionality.
- @param options string - a command, optionally followed by additional parameters or
- Object - settings for attaching new datepicker functionality
- @return jQuery object */
-$.fn.datepicker = function(options){
-
- /* Verify an empty collection wasn't passed - Fixes #6976 */
- if ( !this.length ) {
- return this;
- }
-
- /* Initialise the date picker. */
- if (!$.datepicker.initialized) {
- $(document).on( "mousedown", $.datepicker._checkExternalClick );
- $.datepicker.initialized = true;
- }
-
- /* Append datepicker main container to body if not exist. */
- if ($("#"+$.datepicker._mainDivId).length === 0) {
- $("body").append($.datepicker.dpDiv);
- }
-
- var otherArgs = Array.prototype.slice.call(arguments, 1);
- if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
- return $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this[0]].concat(otherArgs));
- }
- if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
- return $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this[0]].concat(otherArgs));
- }
- return this.each(function() {
- typeof options === "string" ?
- $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this].concat(otherArgs)) :
- $.datepicker._attachDatepicker(this, options);
- });
-};
-
-$.datepicker = new Datepicker(); // singleton instance
-$.datepicker.initialized = false;
-$.datepicker.uuid = new Date().getTime();
-$.datepicker.version = "@VERSION";
+$.each( $.ui.datepicker.prototype.calendarOptions, function( index, option ) {
+ $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ];
+});
-return $.datepicker;
+return widget;
}));